上一章我們搭建了vue-cli,npm等環境,並且基於組件化開發的模式藉助vue+webpack+openlayers6實現了地圖的加載。今天這一章,我們將繼續組件化的開發地圖相關功能,我會通過具體的地圖功能實例來進行闡述,大家加油!
這裏把上一章內容鏈接發一下:https://blog.csdn.net/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.csdn.net/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實戰項目的開發!我們現在有了中國的行政區劃數據,正好眼前全國正值抗擊新館疫情的關鍵時期,我們的實戰項目就以抗擊疫情爲主題!大家加油!