除了二維平面圖、衛(wèi)星圖外涮坐,三維地圖凄贩、手繪地圖等新地圖形式也開(kāi)始出現(xiàn)在各應(yīng)用中。手繪地圖能夠快速定制化的呈現(xiàn)出特定區(qū)域的路線袱讹、交通疲扎、建筑、景點(diǎn)等捷雕,對(duì)于景區(qū)導(dǎo)覽椒丧、旅游觀光和規(guī)劃等場(chǎng)景,具有良好的應(yīng)用前景救巷。最近做了個(gè)關(guān)于手繪地圖的項(xiàng)目壶熏,使用 openlayers 渲染,加載速度和渲染效果都很不錯(cuò)浦译。
參考資料:
openlayers 文檔地址:https://openlayers.org/en/latest/apidoc/
一棒假、手繪地圖繪制、參數(shù)設(shè)置
繪圖人員繪制完地圖并配準(zhǔn)后精盅,發(fā)布到 GeoServer(一款基于 java 的開(kāi)源 GIS 工具集)帽哑,需在 GeoServer 上設(shè)置好投影坐標(biāo)系(EPSG:3857即墨卡托坐標(biāo)系,EPSG:4326即WGS84坐標(biāo)系)叹俏、地圖瓦片格式妻枕、坐標(biāo)軸范圍、地圖原點(diǎn)她肯、地圖層級(jí)佳头、分辨率等參數(shù),一般由后臺(tái)人員設(shè)置晴氨。
注意:以上地圖參數(shù)一般由后臺(tái)人員通過(guò)接口傳給前端康嘉,但有時(shí)傳過(guò)來(lái)的數(shù)據(jù)可能不全,此時(shí)必須問(wèn)清楚或者自己去 GeoServer 上看籽前,加載地圖時(shí)如果出現(xiàn)問(wèn)題基本是因?yàn)槁┝藚?shù)或者參數(shù)錯(cuò)誤亭珍。
二、openlayers 加載手繪地圖
1枝哄、項(xiàng)目引入 openlayers
首先npm 安裝 openlayers
npm install ol
注意肄梨,在 vue 中必須逐一聲明所需的 openlayers 庫(kù)的對(duì)象和方法才能正常使用
import Map from 'ol/Map.js' // 無(wú)法像普通庫(kù)那樣直接 import ol from 'ol' 后調(diào)用里面的對(duì)象和方法
import View from 'ol/View.js'
import Vectors from 'ol/layer/Vector.js'
import { asString } from 'ol/color'
import { fromLonLat, Projection } from 'ol/proj.js'
2、加載手繪地圖
手繪地圖以 WMTS (Web Map Tile Service, Web 地圖瓦片形式)加載挠锥,先創(chuàng)建一個(gè)類型為 WMTS 的圖層資源众羡,再將其放入創(chuàng)建的 Map 對(duì)象的圖層資源集合中。
// 單獨(dú)引入要使用的對(duì)象和方法
import Map from 'ol/Map.js'
import View from 'ol/View.js'
import { fromLonLat, Projection } from 'ol/proj.js'
import { WMTS, Vector } from 'ol/source.js'
import WMTSTileGrid from 'ol/tilegrid/WMTS.js'
import TileLayer from 'ol/layer/Tile.js'
/*配置 WMTS 圖層資源參數(shù)
*@param{object} data 后臺(tái)接口傳過(guò)來(lái)的地圖參數(shù)
*@return {object} 返回創(chuàng)建的 WMTS 圖層資源對(duì)象
*/
initWMTSLayer(data) {
const projection = new Projection({ // 地圖的投影坐標(biāo)系
code: 'EPSG:4326', // 類型可以是墨卡托坐標(biāo)系或WGS84坐標(biāo)系
units: 'm', // 坐標(biāo)單位
axisOrientation: 'neu' // 坐標(biāo)軸方向
})
// 設(shè)置分辨率數(shù)組蓖租,這里后臺(tái)傳過(guò)來(lái)的是以逗號(hào)分隔的字符串
const resolutions = data.layerCoordinates.split(',').map(item => +item)
// 設(shè)置地圖瓦片矩陣Id
const gridIds = data.gridsetIds.split(',').map(item => item.replace(/\s+/g, '')
const tilesGrid = new WMTSTileGrid({ // 地圖瓦片網(wǎng)格對(duì)象
tileSize: [256, 256], // 瓦片大小
origin: [-2.003750834E7, 2.003750834E7], // 切片原點(diǎn)
resolutions: resolutions,
matrixIds: gridIds
}),
// 創(chuàng)建 WMTS 圖層資源
const source = new WMTS({
url: data.url // 地圖服務(wù)的地址
layer: data.layerName // 地圖圖層的名稱
matrixSet: data.gridsetName // 地圖瓦片矩陣
format: 'image/png' // 地圖瓦片的格式粱侣,可以接口傳過(guò)來(lái)也可以前端寫(xiě)死
projection: projection,
tileGrid: tilesGrid,
wrapX: true
})
return source
}
/*創(chuàng)建 Map 對(duì)象羊壹,將配置好的 WMTS 圖層資源加入到圖層合集中
*@param{object} data 后臺(tái)接口傳過(guò)來(lái)的地圖參數(shù)
*/
initMap(data) {
const projection = new Projection({ // 地圖的投影坐標(biāo)系
code: 'EPSG:4326', // 類型可以是墨卡托坐標(biāo)系或WGS84坐標(biāo)系
units: 'm', // 坐標(biāo)單位
axisOrientation: 'neu' // 坐標(biāo)軸方向
})
// 設(shè)置地圖可拖動(dòng)的范圍
const leftBottom = data.leftBottom.split(',')
const rightTop = data.rightTop.split(',')
// 創(chuàng)建地圖對(duì)象
this.map = new Map({
target: 'map',
interactions: defaultInteractions({ // 禁止旋轉(zhuǎn)
altShiftDragRotate: false,
pinchRotate: false
}),
view: new View({
center: data.center.split(','), // 設(shè)置地圖中心坐標(biāo)
zoom: data.minLevel || data.defaultLevel, // 設(shè)置地圖打開(kāi)默認(rèn)的層級(jí)
minZoom: data.minLevel, // 設(shè)置最小縮放層級(jí)
maxZoom: data.maxLevel, // 設(shè)置最大縮放層級(jí)
projection: projection, // 設(shè)置投影坐標(biāo)系
extent: [+leftBottom[0], +leftBottom[1], +rightTop[0], +rightTop[1]] // 拖動(dòng)范圍
}),
layers: [ // 將創(chuàng)建好的 WMTS 圖層資源放入地圖圖層合集中
new TileLayer({
source: this.initWMTSLayer(data)
})
]
})
// 地圖打開(kāi)后移動(dòng)到要顯示的位置
this.map.getView().animate({
center: data.location.split(','), // 目標(biāo)位置的坐標(biāo)
duration: data.duration, // 移動(dòng)動(dòng)畫(huà)時(shí)長(zhǎng)
zoom: data.minLevel || data.defaultLevel // 地圖縮放層級(jí)
})
}
以上,實(shí)現(xiàn)加載手繪地圖后齐婴,移動(dòng)至指定經(jīng)緯度油猫。
這樣就完成了手繪地圖底圖的加載,后續(xù)如何為地圖添加標(biāo)注(含聚合標(biāo)注)柠偶、覆蓋物及路線等情妖,可以查看我的另一篇文章:http://www.reibang.com/p/4af2a52a0fc6