🧑💻 寫在開頭
點贊 + 收藏 === 學會🤣🤣🤣
不FQ也能使用的地圖還有Mapbox
安裝
npm install --save axios
npm install --save mapbox-gl
npm install --save @mapbox/mapbox-gl-directions
使用
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import MapboxDirections from '@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions';
import '@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions.css';
1.API實際地址轉換經緯度
geocoderAddress (address) { return new Promise((resolve) => { axios({ url: `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(address)}.json`, method: 'GET', params: { access_token: mapboxgl.accessToken } }).then(res => { if (res.status == 200) { let center = null; res.data.features.map(p => { if (!center) { center = p.center; } }) resolve(center); } }) }) }
2.初始化地圖
const origin = await this.geocoderAddress(this.origin) const destination = await this.geocoderAddress(this.destination) this.map = new mapboxgl.Map({ container: 'mapboxId', style: 'mapbox://styles/mapbox/streets-v11', center: [(origin[0] + destination[0])/2, (origin[1] + destination[1])/2], zoom: 7.5, antialias: true, // 抗鋸齒 });
新增全域性顯示控制元件
this.map.addControl(new mapboxgl.FullscreenControl());;
3.新增軌跡路線
this.map.on('load', () => { // 獲取主圖色 const primary = getComputedStyle(document.documentElement).getPropertyValue('--el-color-primary'); const themeColor = (primary.includes(',') ? `rgba(${primary}, 1)` : primary) || '#4361EE'; // 規劃路線 this.directions = new MapboxDirections({ accessToken: mapboxgl.accessToken, unit: 'metric', // metric | imperial interactive: false, profile: 'mapbox/driving', controls: { inputs: false, instructions: false, profileSwitcher: false } }); this.map.addControl(this.directions, 'top-left'); this.directions.setOrigin(origin); // 設定起點的經緯度 this.directions.setDestination(destination); // 設定起點的經緯度
軌跡線的樣式修改
// MapboxDirections 物件里加屬性styles styles: [ { 'id': 'directions-route-line-casing', 'type': 'line', 'source': 'directions', 'layout': { 'line-cap': 'round', 'line-join': 'round' }, 'paint': { 'line-color': '#fff', 'line-width': 2, }, 'filter': [ 'all', ['in', '$type', 'LineString'], ['in', 'route', 'selected'] ] }, { 'id': 'directions-route-line', 'type': 'line', 'source': 'directions', 'layout': { 'line-cap': 'butt', 'line-join': 'round' }, 'paint': { 'line-color': { property': 'congestion', 'type': 'categorical', 'default': themeColor, 'stops': [ ['unknown', themeColor], ['low', themeColor], ['moderate', '#f09a46'], ['heavy', '#e34341'], ['severe', '#8b2342'] ] }, 'line-width': 7 } }, { 'id': 'directions-origin-point', 'type': 'circle', 'source': 'directions', 'paint': { 'circle-radius': 16, 'circle-color': '#f09a46' }, 'filter': [ 'all', ['in', '$type', 'Point'], ['in', 'marker-symbol', 'A'] ] }, { 'id': 'directions-destination-point', 'type': 'circle', 'source': 'directions', 'paint': { 'circle-radius': 16, 'circle-color': '#8b2342' }, 'filter': [ 'all', ['in', '$type', 'Point'], ['in', 'marker-symbol', 'B'] ] } ]
4.計算起始點的距離
this.directions.on('route', (event) => { // console.log(event.route); // 輸出路線資訊 // 計算距離為整數 const distance = Math.round(event.route[0].distance/1000 || 0); const distanceMI = Math.round(event.route[0].distance * 0.62137/1000 || 0); // 格式化公里 this.distanceMatrix = distance ? `${numberFormat(distance)} KM` : ''; // 格式化英里 if (this.unit == 'imperial') { this.distanceMatrix = distanceMI ? `${numberFormat(distanceMI)} MILES` : ''; } }); // 格式化函式 export const numberFormat = (num) => { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") }
5.效果
6.HTML簡易程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mapbox Route from Tiananmen to The White House with Markers</title> <!-- 引入Mapbox GL JS的CSS檔案 --> <link href='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css' rel='stylesheet' /> <!-- 引入Mapbox GL JS的JavaScript檔案 --> <script src='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js'></script> </head> <body> <div id="map" style="width: 100%; height: 600px;"></div> <script> // 設定你的Mapbox訪問令牌 mapboxgl.accessToken = '你申請的key'; // 建立地圖例項 const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12', center: [0, 0], pitch: 21, // 傾斜度 maxZoom: 18, minZoom: 3, zoom: 7.5, attributionControl: false // 右下角標識 }); // 定義天安門的座標(示例座標,實際可根據準確位置調整) const tiananmenCoords = [-77.03653, 39.90882]; // 定義白宮的座標(示例座標,實際可根據準確位置調整) const whiteHouseCoords = [-77.03653, 38.89773]; // 建立一個包含起點和終點的GeoJSON物件來表示路線 const routeGeoJSON = { "type": "Feature", "properties": {}, "geometry": { "type": "LineString", "coordinates": [tiananmenCoords, whiteHouseCoords] } }; // 當地圖載入完成後新增路線圖層及標記 map.on('load', () => { // 新增一個資料來源來儲存路線資料 map.addSource('route', { "type": "geojson", "data": routeGeoJSON }); // 新增一個圖層來渲染路線 map.addLayer({ "id": "route-layer", "type": "line", "source": "route", "layout": { "line-join": "round", "line-cap": "round" }, "paint": { "line-color": "blue", "line-width": 5 } }); // 新增天安門標記(標記為A) const tiananmenMarker = new mapboxgl.Marker({ color: "red" }) .setLngLat(tiananmenCoords) .setPopup(new mapboxgl.Popup({ offset: 25 }) .setText('A - 北京天安門')) .addTo(map); // 新增白宮標記(標記為B) const whiteHouseMarker = new mapboxgl.Marker({ color: "green" }) .setLngLat(whiteHouseCoords) .setPopup(new mapboxgl.Popup({ offset: 25 }) .setText('B - 美國白宮')) .addTo(map); // 將地圖檢視中心定位到路線的大致中心位置 map.flyTo({ center: [(tiananmenCoords[0] + whiteHouseCoords[0]) / 2, (tiananmenCoords[1] + whiteHouseCoords[1]) / 2] }); }); </script> </body> </html>
效果
如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。