如題圖,mapbox是一個支援真3D地形展示的webGIS框架,與常用的Leaflet、Cesium和Openlayers並稱四大框架,本文將介紹mapbox-gl js 在 vue 中的用法。
各位可以自行搜尋上面提到的或者其他的webGIS框架或者整合服務商,可以很輕鬆的比較出mapbox的優勢:
mapbox禁止中國地區的新使用者註冊,需要開啟全域性的魔法,進入 mapbox官網註冊
如果要求輸入 海外銀行卡號,參閱:知乎:mapbox的註冊怎麼需要填卡號,有銀行要求嗎,之前看網上說不需要填,具體要怎麼操作,求大神指點。?
完成註冊後會看到如下畫面
左上紅框可以線上建立、編輯地圖樣式。下方紅框是公鑰,可以用來存取你建立的公開地圖。
你可以自行探索各個圖層分別是什麼,我這裡只新增了一個衛星圖,圖層越多,載入的時候就越慢,用起來就越卡。
點選左上角3D按鈕,即可開啟3D檢視,mapbox會根據全球等高線資訊模擬出地形
上圖為山東省泰安市。此外還支援:
本文使用vue3,選配如下:
- router
- vuex
- less
安裝,通過NPM安裝
npm i mapbox-gl
引入
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import MapboxLanguage from '@mapbox/mapbox-gl-language'; //可以將標籤改為中文
初始化
mapboxgl.accessToken='pk.eyJ1IjoiemJiZW4iLCJhIjoiACtpemtnOXRoMDRhcDMwbG43aGYxbXhqYyJ9.YOJzSXzubABBJeK7SXg60w'; //這是一個無效的公鑰,上面提到了公鑰在哪裡可以獲取到
this.map = new mapboxgl.Map({
container: "basicMapbox",
style: 'mapbox://styles/xxx/ckus1uok22m4117aif4pg9qa6', //這是個假連結,在上面有提到分享按鈕,那裡有你自己的連結
center: [118, 28],
zoom: 3, //zoom你都不懂就別看了
pitch: 0, // 相對於地面3D視角的角度
bearing: 0, // 東西南北 方向,正北方為 0
projection: 'globe', // 為 3D 地球
antialias: false, //抗鋸齒,通過false關閉提升效能
essential: true, //不知道什麼意思,我看人家寫我就寫了
renderWorldCopies: false, //可理解為loop,在projection: 'globe'時無效
skipOnboarding: true,//可選擇不等待瓦片載入
});
// ### 標籤漢化
// this.map.addControl(new MapboxLanguage({ defaultLanguage: 'zh-Hans' }));
// ### 新增導航控制條
// this.map.addControl(new mapboxgl.NavigationControl(), 'top-left');
監聽事件
this.map.on("eventName",()=>{})
// 常用事件有:load、moveend、render等,自行探索
常用方法
this.map.setFog({}); //開啟宇宙、星空
this.map.flyTo({
center: [109.926476, 19.088415], //目標中心點 海南省瓊中縣灣嶺鎮
zoom: 11, //目標縮放級別
bearing: 56.50, //目標方位角
pitch: 47.50, //目標傾斜角
},duration: 7000,) //飛行
let shape = await request.get("some_geoJosn")
this.map.addSource('customSourceName'{
type:"geojson" //可選: raster || image || 等
// 每個型別所需的引數不一樣,自行探索,這裡用geojson舉例。
"data": shape
}) //新增資源
this.map.getSource('customSourceName') && this.map.removeSource('customSourceName') //獲取資源、刪除資源
this.map.addLayer({
id: 'measure-lines',
type: 'line',
source: 'customSourceName', //使用剛剛新增的資源
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#00FFF4',
'line-width': 2.5,
'line-opacity': 1,
'line-gap-width': 0,
},
}); // 新增圖層,如上使用 名為 customSourceName 的資源 新增了一個用線勾勒輪廓的圖層。
this.map.getLayer('measure-lines') && this.map.removeLayer('measure-lines') // 獲取圖層、刪除圖層
插點,以下是一個插點的簡單範例,可以用vue元件渲染插點的響應彈窗:
import mapboxPopView from '../mapboxPopView/mapboxPopView.vue'; //彈窗元件需提前引入
async setMaker(makerList) {
if (!makerList) {
return
}
// console.log('makerList::: ', makerList);
for (let item of makerList) {
let dom = document.createElement('img')
dom.src = require(`../../../public/static/img/${item.deviceType}.png`) //這裡使用了自定義圖片來替換預設插點圖示
dom.style.width = '52.4px'
dom.style.height = 'auto' //可以保持比例
dom.id = `marker-${item.deviceId}`
dom.classList.add("markerCustom")
dom.addEventListener("click", () => {
this.setPopContent(item)
})
let marker = new mapboxgl.Marker({
element: dom,
offset: [0, -50], //圖示偏移量
}).setLngLat([item.lon, item.lat]).addTo(this.map);
// 新增標記的彈窗事件
var popup = new mapboxgl.Popup({
offset: [0, -100], //彈窗偏移量
}).setHTML(`<div id="popup-content-${item.deviceId}"></div>`)
// this.setPopContent(item)
marker.setPopup(popup);
this.markerList.push(marker)
// 點選標記時顯示彈窗
}
this.$store.dispatch('addLayer')
},
setPopContent(item) {
const MyNewPopup = defineComponent({
extends: mapboxPopView,
setup() {
const deviceItem = item
return { deviceItem } //這裡的常數可以直接在元件的this物件中獲取
},
})
setTimeout(() => {
createApp(MyNewPopup).mount(`#popup-content-${item.deviceId}`) //掛載到剛剛定義的擁有唯一ID的DOM節點上
}, 10);
},
插點效果如圖:
至此,mapbox的基本功能介紹完畢,另外,mapbox支援自定義圖源,下面是一個使用天地圖瓦片的例子:
setTiandituLaryer() {
this.map.addSource('tianditu', {
type: 'raster',
tiles: [
'你的天地圖連結',
],
tileSize: 256,
});
this.map.addLayer({
id: 'tianditu',
type: 'raster',
source: 'tianditu',
});
},
如果使用其他的圖源,記得在mapbox studio裡關閉或刪除無用的圖層。
碼雲:mapbox_demo
旗鼓相當的對手,就是我們磨礪爪子的堅石。