您好,登录后才能下订单哦!
在现代WebGIS开发中,地图底图的叠加显示是一个常见的需求。通过叠加多个底图,用户可以同时查看不同来源的地理信息,从而获得更丰富的地图展示效果。本文将详细介绍如何在Vue项目中使用天地图和OpenLayers实现多个底图叠加显示的效果。
在开始之前,我们需要确保开发环境已经准备好。以下是所需的工具和库:
首先,确保你已经安装了Node.js。如果没有安装,可以从Node.js官网下载并安装。
安装完成后,使用以下命令安装Vue CLI:
npm install -g @vue/cli
使用Vue CLI创建一个新的Vue项目:
vue create vue-openlayers-tianditu
在创建过程中,选择默认配置或根据需要进行自定义配置。
进入项目目录并安装OpenLayers:
cd vue-openlayers-tianditu
npm install ol
为了使用天地图的服务,你需要注册一个天地图开发者账号并获取API密钥。访问天地图开放平台进行注册和申请。
天地图提供了多种地图服务,包括矢量地图、影像地图、地形图等。我们需要将这些服务配置到OpenLayers中。
在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
),你需要将其替换为你自己的密钥。
在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
打开浏览器,你应该能够看到一个包含天地图矢量、影像和标注图层的地图。
在OpenLayers中,可以通过添加多个图层来实现底图的叠加显示。接下来,我们将添加其他地图服务作为底图,并与天地图进行叠加。
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,
}),
});
除了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,
}),
});
在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,
}),
});
为了实现动态切换图层的功能,我们可以使用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、天地图矢量、天地图影像和天地图标注图层的显示和隐藏。通过点击按钮,用户可以动态控制各个图层的可见性。
除了控制图层的显示和隐藏,我们还可以通过调整图层的透明度来实现更灵活的叠加效果。在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>
在上述代码中,我们添加了一个滑块来控制天地图矢量图层的透明度。通过拖动滑块,用户可以实时调整图层的透明度,从而实现更灵活的叠加效果。
除了天地图和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
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。