vue怎么使用天地图和openlayers实现多个底图叠加显示效果

发布时间:2022-04-14 17:32:55 作者:zzz
来源:亿速云 阅读:863

Vue怎么使用天地图和OpenLayers实现多个底图叠加显示效果

引言

在现代WebGIS开发中,地图底图的叠加显示是一个常见的需求。通过叠加多个底图,用户可以同时查看不同来源的地理信息,从而获得更丰富的地图展示效果。本文将详细介绍如何在Vue项目中使用天地图和OpenLayers实现多个底图叠加显示的效果。

1. 环境准备

在开始之前,我们需要确保开发环境已经准备好。以下是所需的工具和库:

1.1 安装Node.js和Vue CLI

首先,确保你已经安装了Node.js。如果没有安装,可以从Node.js官网下载并安装。

安装完成后,使用以下命令安装Vue CLI:

npm install -g @vue/cli

1.2 创建Vue项目

使用Vue CLI创建一个新的Vue项目:

vue create vue-openlayers-tianditu

在创建过程中,选择默认配置或根据需要进行自定义配置。

1.3 安装OpenLayers

进入项目目录并安装OpenLayers:

cd vue-openlayers-tianditu
npm install ol

1.4 获取天地图API密钥

为了使用天地图的服务,你需要注册一个天地图开发者账号并获取API密钥。访问天地图开放平台进行注册和申请。

2. 配置天地图服务

天地图提供了多种地图服务,包括矢量地图、影像地图、地形图等。我们需要将这些服务配置到OpenLayers中。

2.1 创建天地图图层

src/components目录下创建一个新的组件TiandituMap.vue,并在其中配置天地图的图层。

<template>
  <div id="map" class="map"></div>
</template>

<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';

export default {
  name: 'TiandituMap',
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      // 天地图矢量地图
      const vecLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
      });

      // 天地图影像地图
      const imgLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
      });

      // 天地图标注图层
      const cvaLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
      });

      const map = new Map({
        target: 'map',
        layers: [vecLayer, imgLayer, cvaLayer],
        view: new View({
          center: [116.397428, 39.90923], // 北京市中心
          zoom: 10,
        }),
      });
    },
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 600px;
}
</style>

在上述代码中,我们创建了三个天地图图层:矢量地图、影像地图和标注图层。每个图层的URL中都包含了天地图的API密钥(YOUR_API_KEY),你需要将其替换为你自己的密钥。

2.2 在Vue中使用天地图组件

src/App.vue中使用刚刚创建的TiandituMap组件:

<template>
  <div id="app">
    <TiandituMap />
  </div>
</template>

<script>
import TiandituMap from './components/TiandituMap.vue';

export default {
  name: 'App',
  components: {
    TiandituMap,
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

运行项目:

npm run serve

打开浏览器,你应该能够看到一个包含天地图矢量、影像和标注图层的地图。

3. 叠加多个底图

在OpenLayers中,可以通过添加多个图层来实现底图的叠加显示。接下来,我们将添加其他地图服务作为底图,并与天地图进行叠加。

3.1 添加OpenStreetMap图层

OpenStreetMap(OSM)是一个全球范围内的开源地图服务。我们可以将其底图添加到我们的地图中。

TiandituMap.vue中,添加一个新的图层:

// OpenStreetMap图层
const osmLayer = new TileLayer({
  source: new XYZ({
    url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  }),
});

osmLayer添加到地图的layers数组中:

const map = new Map({
  target: 'map',
  layers: [osmLayer, vecLayer, imgLayer, cvaLayer],
  view: new View({
    center: [116.397428, 39.90923], // 北京市中心
    zoom: 10,
  }),
});

3.2 添加其他地图服务

除了OpenStreetMap,你还可以添加其他地图服务,如Google Maps、Bing Maps等。以下是一个添加Google Maps图层的示例:

// Google Maps图层
const googleLayer = new TileLayer({
  source: new XYZ({
    url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
  }),
});

googleLayer添加到地图的layers数组中:

const map = new Map({
  target: 'map',
  layers: [googleLayer, osmLayer, vecLayer, imgLayer, cvaLayer],
  view: new View({
    center: [116.397428, 39.90923], // 北京市中心
    zoom: 10,
  }),
});

3.3 控制图层显示顺序

在OpenLayers中,图层的显示顺序由它们在layers数组中的顺序决定。数组中的第一个图层将显示在最底层,最后一个图层将显示在最顶层。

你可以通过调整layers数组中图层的顺序来控制它们的显示顺序。例如,如果你希望天地图的矢量地图显示在最上层,可以将vecLayer放在数组的最后:

const map = new Map({
  target: 'map',
  layers: [googleLayer, osmLayer, imgLayer, cvaLayer, vecLayer],
  view: new View({
    center: [116.397428, 39.90923], // 北京市中心
    zoom: 10,
  }),
});

3.4 动态切换图层

为了实现动态切换图层的功能,我们可以使用Vue的响应式数据来控制图层的显示和隐藏。

TiandituMap.vue中,添加一个data属性来存储图层的可见状态:

data() {
  return {
    layers: {
      google: true,
      osm: true,
      vec: true,
      img: true,
      cva: true,
    },
  };
},

然后,在initMap方法中,根据layers的状态来添加或移除图层:

initMap() {
  const googleLayer = new TileLayer({
    source: new XYZ({
      url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
    }),
    visible: this.layers.google,
  });

  const osmLayer = new TileLayer({
    source: new XYZ({
      url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    }),
    visible: this.layers.osm,
  });

  const vecLayer = new TileLayer({
    source: new XYZ({
      url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=YOUR_API_KEY',
      wrapX: false,
    }),
    visible: this.layers.vec,
  });

  const imgLayer = new TileLayer({
    source: new XYZ({
      url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_API_KEY',
      wrapX: false,
    }),
    visible: this.layers.img,
  });

  const cvaLayer = new TileLayer({
    source: new XYZ({
      url: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=YOUR_API_KEY',
      wrapX: false,
    }),
    visible: this.layers.cva,
  });

  this.map = new Map({
    target: 'map',
    layers: [googleLayer, osmLayer, vecLayer, imgLayer, cvaLayer],
    view: new View({
      center: [116.397428, 39.90923], // 北京市中心
      zoom: 10,
    }),
  });
},

接下来,添加一些按钮来控制图层的显示和隐藏:

<template>
  <div>
    <div id="map" class="map"></div>
    <div class="controls">
      <button @click="toggleLayer('google')">Toggle Google Maps</button>
      <button @click="toggleLayer('osm')">Toggle OpenStreetMap</button>
      <button @click="toggleLayer('vec')">Toggle 天地图矢量</button>
      <button @click="toggleLayer('img')">Toggle 天地图影像</button>
      <button @click="toggleLayer('cva')">Toggle 天地图标注</button>
    </div>
  </div>
</template>

<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';

export default {
  name: 'TiandituMap',
  data() {
    return {
      layers: {
        google: true,
        osm: true,
        vec: true,
        img: true,
        cva: true,
      },
      map: null,
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      const googleLayer = new TileLayer({
        source: new XYZ({
          url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
        }),
        visible: this.layers.google,
      });

      const osmLayer = new TileLayer({
        source: new XYZ({
          url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        }),
        visible: this.layers.osm,
      });

      const vecLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.vec,
      });

      const imgLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.img,
      });

      const cvaLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.cva,
      });

      this.map = new Map({
        target: 'map',
        layers: [googleLayer, osmLayer, vecLayer, imgLayer, cvaLayer],
        view: new View({
          center: [116.397428, 39.90923], // 北京市中心
          zoom: 10,
        }),
      });
    },
    toggleLayer(layerName) {
      this.layers[layerName] = !this.layers[layerName];
      const layer = this.map.getLayers().getArray().find(layer => layer.get('name') === layerName);
      if (layer) {
        layer.setVisible(this.layers[layerName]);
      }
    },
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 600px;
}

.controls {
  margin-top: 10px;
}

button {
  margin-right: 10px;
}
</style>

在上述代码中,我们添加了五个按钮,分别用于切换Google Maps、OpenStreetMap、天地图矢量、天地图影像和天地图标注图层的显示和隐藏。通过点击按钮,用户可以动态控制各个图层的可见性。

4. 优化与扩展

4.1 图层透明度控制

除了控制图层的显示和隐藏,我们还可以通过调整图层的透明度来实现更灵活的叠加效果。在OpenLayers中,可以通过setOpacity方法来设置图层的透明度。

TiandituMap.vue中,添加一个滑块来控制图层的透明度:

<template>
  <div>
    <div id="map" class="map"></div>
    <div class="controls">
      <button @click="toggleLayer('google')">Toggle Google Maps</button>
      <button @click="toggleLayer('osm')">Toggle OpenStreetMap</button>
      <button @click="toggleLayer('vec')">Toggle 天地图矢量</button>
      <button @click="toggleLayer('img')">Toggle 天地图影像</button>
      <button @click="toggleLayer('cva')">Toggle 天地图标注</button>
      <div>
        <label for="opacity">天地图矢量透明度:</label>
        <input
          type="range"
          id="opacity"
          min="0"
          max="1"
          step="0.1"
          v-model="vecOpacity"
          @input="setVecOpacity"
        />
      </div>
    </div>
  </div>
</template>

<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';

export default {
  name: 'TiandituMap',
  data() {
    return {
      layers: {
        google: true,
        osm: true,
        vec: true,
        img: true,
        cva: true,
      },
      vecOpacity: 1,
      map: null,
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      const googleLayer = new TileLayer({
        source: new XYZ({
          url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
        }),
        visible: this.layers.google,
      });

      const osmLayer = new TileLayer({
        source: new XYZ({
          url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        }),
        visible: this.layers.osm,
      });

      const vecLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.vec,
        opacity: this.vecOpacity,
      });

      const imgLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.img,
      });

      const cvaLayer = new TileLayer({
        source: new XYZ({
          url: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=YOUR_API_KEY',
          wrapX: false,
        }),
        visible: this.layers.cva,
      });

      this.map = new Map({
        target: 'map',
        layers: [googleLayer, osmLayer, vecLayer, imgLayer, cvaLayer],
        view: new View({
          center: [116.397428, 39.90923], // 北京市中心
          zoom: 10,
        }),
      });
    },
    toggleLayer(layerName) {
      this.layers[layerName] = !this.layers[layerName];
      const layer = this.map.getLayers().getArray().find(layer => layer.get('name') === layerName);
      if (layer) {
        layer.setVisible(this.layers[layerName]);
      }
    },
    setVecOpacity() {
      const vecLayer = this.map.getLayers().getArray().find(layer => layer.get('name') === 'vec');
      if (vecLayer) {
        vecLayer.setOpacity(this.vecOpacity);
      }
    },
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 600px;
}

.controls {
  margin-top: 10px;
}

button {
  margin-right: 10px;
}
</style>

在上述代码中,我们添加了一个滑块来控制天地图矢量图层的透明度。通过拖动滑块,用户可以实时调整图层的透明度,从而实现更灵活的叠加效果。

4.2 添加更多地图服务

除了天地图和OpenStreetMap,你还可以添加其他地图服务,如Bing Maps、Mapbox等。以下是一个添加Bing Maps图层的示例:

// Bing Maps图层
const bingLayer = new TileLayer({
  source: new XYZ({
    url: 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=587&mkt=en-US&token=YOUR_BING_MAPS_TOKEN',
  }),
  visible: this.layers.bing,
});

bingLayer添加到地图的layers

推荐阅读:
  1. 怎么使用Vue-Awesome-Swiper实现旋转叠加轮播效果&平移轮播效果
  2. Java如何实现图片叠加效果

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue openlayers

上一篇:linux中samba的含义是什么

下一篇:idea怎么快速实现将SpringBoot项目打包Docker镜像并部署

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》