上一章我们搭建了vue-cli,npm等环境,并且基于组件化开发的模式借助vue+webpack+openlayers6实现了地图的加载。今天这一章,我们将继续组件化的开发地图相关功能,我会通过具体的地图功能实例来进行阐述,大家加油!
这里把上一章内容链接发一下:https://blog.youkuaiyun.com/MagicMHD/article/details/104962747
一、地图双屏联动功能的开发
1、在上一章新建的项目的基础上添加一个DoubleMap组件如下图:

2、编写DoubleMap组件完成双屏联动效果,代码如下:
<template>
<div>
<p>地图1</p>
<div id="map1"></div>
<p>地图2</p>
<div id="map2"></div>
</div>
</template>
<script>
import 'ol/ol.css'
import View from 'ol/View'
import Map from 'ol/Map'
import TileLayer from 'ol/layer/Tile'
import {OSM, TileArcGISRest} from 'ol/source';
export default {
name:'OlMap',
mounted() {
//渲染地图
//1、首先创建一个视图
var view=new View({
center: [0, 0],
zoom: 2
})
//2、创建地图图层
var layers1=[
new TileLayer({
source: new OSM()
})
]
var layers2=[
new TileLayer({
source: new OSM()
})
]
//3、创建第一个地图
var map1=new Map({
target: 'map1',
layers: layers1,
view: view
})
//4、创建第二个地图
var map2=new Map({
layers: layers2,
target: 'map2',
view: view
})
}
}
</script>
<style lang="stylus" scoped>
#map1
width:600px
height:250px
#map2
width:600px
height:250px
</style>
这里我们新建了两个map,但是让两个map共用一个view,这样就可以达到双屏联动的效果,如果你只是想双屏展示,不想联动,那就让两个map分别对应不同的view即可。
3、调用DoubleMap组件完成地图双屏联动
首先我们要在Home组件里面引入DoubleMap局部组件,包括:引入DoubleMap组件、声明局部组件和最后在模板中使用局部组件这三步,Home.vue组件的具体代码如下:
<template>
<!-- 这里我们就可以用引入的HomeMap组件了,大小写用破折号 -->
<home-double-map></home-double-map>
</template>
<script>
// 首先引入局部组件
import HomeMap from './components/Map'
import HomeDoubleMap from './components/DoubleMap'
export default {
name: 'Home',
// 需要声明局部组件
components: {
HomeMap: HomeMap,
HomeDoubleMap: HomeDoubleMap
}
}
</script>
<style scoped>
</style>
这里面还有上一章引入的Map组件,我没删除但是在模板template里面只用了DoubleMap组件,所以程序界面也就只会显示地图双屏联动的功能了!
4、运行程序测试
效果如下图所示:

当我们移动一个地图时,另外一个地图也会移动,也就实现了地图联动功能!
二、地图上下左右移动及定位功能
1、新建MapLoc组件,如下图所示:

2、编写MapLoc组件,使之完成地图上下左右移动及定位功能,代码如下:
<template>
<div>
<div>
<div id="map"></div>
</div>
<div>
<button @click="moveToLeft">左移</button>
<button @click="moveToRight">右移</button>
<button @click="moveToUp">上移</button>
<button @click="moveToDown">下移</button>
<button @click="moveToQingdao">移到青岛</button>
<button @click="zoomIn">放大</button>
<button @click="zoomOut">缩小</button>
</div>
</div>
</template>
<script>
import 'ol/ol.css'
import View from 'ol/View'
import Map from 'ol/Map'
import TileLayer from 'ol/layer/Tile'
import {transform} from 'ol/proj';
import {OSM, TileArcGISRest} from 'ol/source'
export default {
name:'OlMapLoc',
data() {
return {
map: null,
view: null,
layers: null
}
},
mounted() {
//渲染地图
//1、首先创建一个视图
var view=new View({
// 设置青岛为地图中心,此处进行坐标转换, 把EPSG:4326的坐标,转换为EPSG:3857坐标,因为ol默认使用的是EPSG:3857坐标
center: transform([120.374798,36.07316], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
})
//2、创建地图图层
var layers=[
new TileLayer({
source: new OSM()
})
]
//3、创建地图
var map=new Map({
target: 'map',
layers: layers,
view: view
})
this.map=map;
this.view=view;
this.layers=layers;
},
methods: {
//左移
moveToLeft: function(e){
var view = this.map.getView();
var mapCenter = this.view.getCenter();
// 让地图中心的x值增加,即可使得地图向左移动,增加的值根据效果可自由设定
mapCenter[0] += 50000;
view.setCenter(mapCenter);
this.map.render();
},
//右移
moveToRight: function(e){
var view = this.map.getView();
var mapCenter = this.view.getCenter();
// 让地图中心的x值减少,即可使得地图向右移动,增加的值根据效果可自由设定
mapCenter[0] -= 50000;
view.setCenter(mapCenter);
this.map.render();
},
//上移
moveToUp: function(e){
var view = this.map.getView();
var mapCenter = this.view.getCenter();
// 让地图中心的y值减少,即可使得地图向上移动,增加的值根据效果可自由设定
mapCenter[1] -= 50000;
view.setCenter(mapCenter);
this.map.render();
},
//下移
moveToDown: function(e){
var view = this.map.getView();
var mapCenter = this.view.getCenter();
// 让地图中心的y值增加,即可使得地图向下移动,增加的值根据效果可自由设定
mapCenter[1] += 50000;
view.setCenter(mapCenter);
this.map.render();
},
//移动到青岛
moveToQingdao: function(e){
var view = this.map.getView();
// 设置地图中心为青岛的坐标,即可让地图移动到青岛
view.setCenter(transform([120.374798,36.07316], 'EPSG:4326', 'EPSG:3857'));
this.map.render();
},
//放大
zoomIn: function(e){
var view = this.map.getView();
// 让地图的zoom增加1,从而实现地图放大
view.setZoom(view.getZoom() + 1);
},
//缩小
zoomOut: function(e){
var view = this.map.getView();
// 让地图的zoom增加1,从而实现地图缩小
view.setZoom(view.getZoom() - 1);
}
}
}
</script>
<style lang="stylus" scoped>
#map
width:900px
height:350px
</style>
这里说一下由于我们在做地图操作时一般都会涉及map、view、layer等操作,为了方便获取这些对象,我们把这些对象放到data方法里面,初始化地图的时候使用this方法给这些参数赋值,在操作地图的时候只需要使用this指向这些参数就可以。说白了就是给这些参数定义全局变量,使我们方便使用!
3、调用MapLoc组件完成地图双屏联动
首先我们要在Home组件里面引入MapLoc局部组件,包括:引入MapLoc组件、声明局部组件和最后在模板中使用局部组件这三步,Home.vue组件的具体代码如下:
<template>
<!-- 这里我们就可以用引入的HomeMap组件了,大小写用破折号 -->
<home-map-loc></home-map-loc>
</template>
<script>
// 首先引入局部组件
import HomeMap from './components/Map'
import HomeDoubleMap from './components/DoubleMap'
import HomeMapLoc from './components/MapLoc'
export default {
name: 'Home',
// 需要声明局部组件
components: {
HomeMap: HomeMap,
HomeDoubleMap: HomeDoubleMap,
HomeMapLoc: HomeMapLoc
}
}
</script>
<style scoped>
</style>
4、运行程序测试,如下图:

经过测试上述功能都没有问题!
三、 加载各种在线地图
这一部分我们要实现一些常见的在线地图的加载,比如ArcGIS地图服务、OSM地图服务、天地图服务和高德地图服务。并且实现这些图层的叠加顺序的相关操作!
1、新建MapOnline组件,如下图所示:

2、编写MapOnline组件,使之可以加载常用的在线地图,代码如下:
<template>
<div>
<div>
<div id="map"></div>
</div>
<div>显示/隐藏:
<input type="checkbox" checked="checked" @click="checkERSI($event)" />加载ArcGIS地图
<input type="checkbox" checked="checked" @click="checkOSM($event)"/>加载Open Street Map地图
<input type="checkbox" checked="checked" @click="checkTDT($event)"/>加载天地图
<input type="checkbox" checked="checked" @click="checkAmap($event)"/>加载高德地图 -->
</div>
<div>图层顺序:
<input name="seq" type="radio" value="" @click="upArcGIS($event);" />ArcGIS地图在最上
<input name="seq" type="radio" value="" @click="upOSM($event);"/>OSM地图在最上
<input name="seq" type="radio" value="" checked="checked" @click="upTDT($event);"/>天地图在最上
<input name="seq" type="radio" value="" checked="checked" @click="upAmap($event);"/>高德地图在最上
</div>
</div>
</template>
<script>
import 'ol/ol.css'
import View from 'ol/View'
import Map from 'ol/Map'
import TileLayer from 'ol/layer/Tile'
// import {Group as LayerGroup, Tile as TileLayer} from 'ol/layer'
import {transform} from 'ol/proj';
import {OSM, TileArcGISRest, XYZ} from 'ol/source'
export default {
name:'OlMapOnline',
data() {
return {
map: null,
view: null,
//这里创建我们要添加的多个图层
esriLayers: null,
osmLayers: null,
tiandituLayers: null,
gaodeLayers: null
}
},
mounted() {
//渲染地图
//1、首先创建一个视图
var view=new View({
// 设置青岛为地图中心,此处进行坐标转换, 把EPSG:4326的坐标,转换为EPSG:3857坐标,因为ol默认使用的是EPSG:3857坐标
center: transform([120.374798,36.07316], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
})
this.view=view;
//2、创建地图图层
var esriLayers=
new TileLayer({
source: new XYZ({
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
}),
title: 'ESRI影像'
})
//给data中的esriLayers赋值
this.esriLayers=esriLayers;
var osmLayers=
new TileLayer({
source: new OSM(),
title: 'OSM影像'
})
this.osmLayers=osmLayers;
var tiandituLayers=
new TileLayer({
source: new XYZ({
url: "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=008a8816d2eee25a677670273eaee891",
crossOrigin: "anonymous"
}),
title: '天地图影像'
})
//给data赋值
this.tiandituLayers=tiandituLayers;
var gaodeLayers=
new TileLayer({
source: new XYZ({
url:'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
}),
title: '高德影像'
})
//给data赋值
this.gaodeLayers=gaodeLayers;
//3、创建地图
var map=new Map({
target: 'map',
//// 在地图上添加上面创建的四个图层,图层顺序自下而上,依次是ESRI地图,OSM地图,天地图和高德地图
layers: [esriLayers,osmLayers,tiandituLayers,gaodeLayers],
view: view
})
this.map=map;
},
methods: {
checkERSI: function(event){
console.log(event.target.checked)
this.esriLayers.setVisible(event.target.checked);
},
checkOSM: function(event){
this.osmLayers.setVisible(event.target.checked);
},
checkTDT: function(event){
this.tiandituLayers.setVisible(event.target.checked);
},
checkAmap: function(event){
this.gaodeLayers.setVisible(event.target.checked);
},
upArcGIS: function(event){
if(event.target.checked){
this.esriLayers.setZIndex(3);
this.osmLayers.setZIndex(this.osmLayers.getZIndex()-1);
this.tiandituLayers.setZIndex(this.tiandituLayers.getZIndex()-1);
this.gaodeLayers.setZIndex(this.gaodeLayers.getZIndex()-1);
}
},
upOSM: function(event){
if(event.target.checked){
this.osmLayers.setZIndex(3);
this.esriLayers.setZIndex(this.esriLayers.getZIndex()-1);
this.tiandituLayers.setZIndex(this.tiandituLayers.getZIndex()-1);
this.gaodeLayers.setZIndex(this.gaodeLayers.getZIndex()-1);
}
},
upTDT: function(event){
if(event.target.checked){
this.tiandituLayers.setZIndex(3);
this.esriLayers.setZIndex(this.esriLayers.getZIndex()-1);
this.osmLayers.setZIndex(this.osmLayers.getZIndex()-1);
this.gaodeLayers.setZIndex(this.gaodeLayers.getZIndex()-1);
}
},
upAmap: function(event){
if(event.target.checked){
this.gaodeLayers.setZIndex(3);
this.esriLayers.setZIndex(this.esriLayers.getZIndex()-1);
this.osmLayers.setZIndex(this.osmLayers.getZIndex()-1);
this.tiandituLayers.setZIndex(this.tiandituLayers.getZIndex()-1);
}
}
}
}
</script>
<style lang="stylus" scoped>
#map
width:900px
height:350px
</style>
3、调用MapOnline组件完成地图双屏联动
首先我们要在Home组件里面引入MapOnline局部组件,包括:引入MapOnline组件、声明局部组件和最后在模板中使用局部组件这三步,Home.vue组件的具体代码如下:
<template>
<!-- 这里我们就可以用引入的HomeMap组件了,大小写用破折号 -->
<home-map-online></home-map-online>
</template>
<script>
// 首先引入局部组件
import HomeMap from './components/Map'
import HomeDoubleMap from './components/DoubleMap'
import HomeMapLoc from './components/MapLoc'
import HomeMapOnline from './components/MapOnline'
export default {
name: 'Home',
// 需要声明局部组件
components: {
HomeMap: HomeMap,
HomeDoubleMap: HomeDoubleMap,
HomeMapLoc: HomeMapLoc,
HomeMapOnline: HomeMapOnline
}
}
</script>
<style scoped>
</style>
4、运行测试

经过测试,以上功能均没有问题!
四、加载我们自己发布的地图服务
这里以加载Geoserver发布的WMS服务为例进行讲解。关于Geoserver如何发布地图服务我之前在openlayers入门开发中做过一个详细的说明,不明白的同学可以看一下,链接如下:https://blog.youkuaiyun.com/MagicMHD/article/details/91430148
好了,下面开始实际编码加载Geoserver发布的wms地图服务了!
1、新建MapWms组件,如下图所示

2、编写MapWms组件,使之可以加载Geoserver发布的wms地图服务,代码如下:
<template>
<div>
<div id="map"></div>
</div>
</template>
<script>
import 'ol/ol.css'
import View from 'ol/View'
import Map from 'ol/Map'
import TileLayer from 'ol/layer/Tile'
import Projection from 'ol/proj/Projection';
import TileWMS from 'ol/source/TileWMS';
import {OSM} from 'ol/source'
export default {
name:'OlMapWms',
data() {
return {
map: null,
view: null,
//这里创建我们要添加的图层
chinaLayers: null
}
},
mounted() {
//渲染地图
//1、创建wms地图图层
var chinaLayers=
new TileLayer({
source: new TileWMS({
url: "http://"这里要写你实际发布地图服务的IP地址":8123/geoserver/airtraffic/wms",
params: {
'FORMAT': 'image/png',
'VERSION': '1.1.1',
tiled: true,
STYLES: '',
LAYERS: 'airtraffic:china',
tilesOrigin: 73.62004852302096 + "," + 3.8378885148431436
}
}),
title: '中国wms服务'
})
//给data赋值
this.chinaLayers=chinaLayers;
//2、创建空间参考4326
var projection = new Projection({
code: 'EPSG:4326',
units: 'degrees',
});
//3、创建视图
var view=new View({
projection: projection
})
this.view=view;
//4、创建地图
var map=new Map({
target: 'map',
layers: [chinaLayers],
view: view
})
var bounds = [73.62004852302096, 3.8378885148431436,
134.7684631352655, 53.553741455004214];
map.getView().fit(bounds, map.getSize());
}
}
</script>
<style lang="stylus" scoped>
#map
width:900px
height:350px
</style>
3、调用MapWms组件完成地图双屏联动
首先我们要在Home组件里面引入MapWms局部组件,包括:引入MapWms组件、声明局部组件和最后在模板中使用局部组件这三步,Home.vue组件的具体代码如下:
<template>
<!-- 这里我们就可以用引入的HomeMap组件了,大小写用破折号 -->
<home-map-wms></home-map-wms>
</template>
<script>
// 首先引入局部组件
import HomeMap from './components/Map'
import HomeDoubleMap from './components/DoubleMap'
import HomeMapLoc from './components/MapLoc'
import HomeMapOnline from './components/MapOnline'
import HomeMapWms from './components/MapWms'
export default {
name: 'Home',
// 需要声明局部组件
components: {
HomeMap: HomeMap,
HomeDoubleMap: HomeDoubleMap,
HomeMapLoc: HomeMapLoc,
HomeMapOnline: HomeMapOnline,
HomeMapWms: HomeMapWms
}
}
</script>
<style scoped>
</style>
4、运行测试

这里我们就成功的把Geoserver发布的wms服务加载出来了!
五、加载离线矢量地图数据
这里以加载GeoJSON数据为例进行讲解!
1、新建MapJson组件,如下图所示

2、编写MapJson组件,使之可以加载GeoJSON数据,代码如下:
<template>
<div>
<div id="map"></div>
</div>
</template>
<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import GeoJSON from 'ol/format/GeoJSON';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import {Fill, Stroke, Style, Text} from 'ol/style';
export default {
name:'OlMapWms',
mounted() {
var vectorLayer = new VectorLayer({
source: new VectorSource({
url: './../../../../static/china.json',
format: new GeoJSON()
})
});
var map = new Map({
layers: [vectorLayer],
target: 'map',
view: new View({
center: [0, 0],
zoom: 1
})
});
}
}
</script>
<style lang="stylus" scoped>
#map
width:900px
height:350px
</style>
这里要提醒大家的是json文件一定要放到static文件夹下,不然在Vue中是访问不到的!这里我踩了坑-。-
3、调用MapJson组件完成地图双屏联动
首先我们要在Home组件里面引入MapJson局部组件,包括:引入MapJson组件、声明局部组件和最后在模板中使用局部组件这三步,Home.vue组件的具体代码如下:
<template>
<!-- 这里我们就可以用引入的HomeMap组件了 -->
<home-map-json></home-map-json>
</template>
<script>
// 首先引入局部组件
import HomeMap from './components/Map'
import HomeDoubleMap from './components/DoubleMap'
import HomeMapLoc from './components/MapLoc'
import HomeMapOnline from './components/MapOnline'
import HomeMapWms from './components/MapWms'
import HomeMapJson from './components/MapJson'
export default {
name: 'Home',
// 需要声明局部组件
components: {
HomeMap: HomeMap,
HomeDoubleMap: HomeDoubleMap,
HomeMapLoc: HomeMapLoc,
HomeMapOnline: HomeMapOnline,
HomeMapWms: HomeMapWms,
HomeMapJson: HomeMapJson
}
}
</script>
<style scoped>
</style>
4、运行测试

加载成功!
这里就介绍这五种地图的操作,如果你想详细的了解OpenLayers的地图操作,你可以看一下我之前根据原生js写的openlayers的各种地图操作,链接我就不给了,有好几篇,你可以翻一下我的博客,截图如下:

然后根据我们前面整理的基于vue+openlayers的模块化地图开发模式开发新的功能组件!其实原理掌握一点就行了,当你要使用openlayers的某个对象时,首先引用他,然后别的就和我们原声js的openlayers操作基本一致了!
关于Vue+Webpack+OpenLayers6完成组件化的WebGIS开发的地图实例讲解就先讲到这儿了!
下一章节我们将正式开始前后端分离+模块化开发的WebGIS实战项目的开发!我们现在有了中国的行政区划数据,正好眼前全国正值抗击新馆疫情的关键时期,我们的实战项目就以抗击疫情为主题!大家加油!
5249



被折叠的 条评论
为什么被折叠?



