日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mapbox矢量切片标准_Cesium 加载矢量切片(MapBox Vector Tile)

發(fā)布時間:2024/9/27 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mapbox矢量切片标准_Cesium 加载矢量切片(MapBox Vector Tile) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

矢量切片(vector tile)是當(dāng)前 WebGIS 較熱技術(shù),國內(nèi)的高德、百度等在線地圖都使用了矢量切片技術(shù)。相較于傳統(tǒng)柵格切片,矢量切片好處很多。簡單幾點(diǎn)就是:輕量、客戶端渲染、還可加密(柵格切片容易被爬取)。矢量切片格式一般有 GeoJSON、TopoJSON 、MVT (MapBox Vector Tile)、PBF。

下面是 Cesium 加載 MVT 矢量切片的代碼,由于樣式渲染使用的了 openlayers,所以首先需要安裝 openlayers。

一、安裝 openlayers

npm install openlayers

二、MVT 加載核心代碼

```javascript

// mvtProvider.js

import * as Cesium from 'cesium'

import ol from 'openlayers/dist/ol-debug'

export function MVTProvider (options) {

options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT)

this._tilingScheme = Cesium.defined(options.tilingScheme) ? options.tilingScheme : new Cesium.WebMercatorTilingScheme({ ellipsoid: options.ellipsoid })

this._tileWidth = Cesium.defaultValue(options.tileWidth, 512)

this._tileHeight = Cesium.defaultValue(options.tileHeight, 512)

this._readyPromise = Cesium.when.resolve(true)

this._ol = ol

this._mvtParser = new this._ol.format.MVT()

this._styleFun = Cesium.defined(options.styleFun) ? options.styleFun : createMapboxStreetsV6Style

this._key = Cesium.defaultValue(options.key, '')

this._url = Cesium.defaultValue(options.url, 'https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/{z}/{x}/{y}.vector.pbf?access_token={k}')

var sw = this._tilingScheme._rectangleSouthwestInMeters

var ne = this._tilingScheme._rectangleNortheastInMeters

var mapExtent = [sw.x, sw.y, ne.x, ne.y]

this._resolutions = ol.tilegrid.resolutionsFromExtent(mapExtent, 22, this._tileWidth)

this._pixelRatio = 1

this._transform = [0.125, 0, 0, 0.125, 0, 0]

this._replays = ['Default', 'Image', 'Polygon', 'LineString', 'Text']

this._tileQueue = new Cesium.TileReplacementQueue()

this._cacheSize = 1000

}

Object.defineProperties(MVTProvider.prototype, {

proxy: {

get () {

return undefined

}

},

tileWidth: {

get () {

return this._tileWidth

}

},

tileHeight: {

get () {

return this._tileHeight

}

},

maximumLevel: {

get () {

return undefined

}

},

minimumLevel: {

get () {

return undefined

}

},

tilingScheme: {

get () {

return this._tilingScheme

}

},

rectangle: {

get () {

return this._tilingScheme.rectangle

}

},

tileDiscardPolicy: {

get () {

return undefined

}

},

errorEvent: {

get () {

return this._errorEvent

}

},

ready: {

get () {

return true

}

},

readyPromise: {

get () {

return this._readyPromise

}

},

credit: {

get () {

return undefined

}

},

hasAlphaChannel: {

get () {

return true

}

}

})

MVTProvider.prototype.getTileCredits = function () {

return undefined

}

function findTileInQueue (x, y, level, tileQueue) {

var item = tileQueue.head

while (item !== undefined && !(item.xMvt === x && item.yMvt === y && item.zMvt === level)) {

item = item.replacementNext

}

return item

}

function remove (tileReplacementQueue, item) {

var previous = item.replacementPrevious

var next = item.replacementNext

if (item === tileReplacementQueue._lastBeforeStartOfFrame) {

tileReplacementQueue._lastBeforeStartOfFrame = next

}

if (item === tileReplacementQueue.head) {

tileReplacementQueue.head = next

} else {

previous.replacementNext = next

}

if (item === tileReplacementQueue.tail) {

tileReplacementQueue.tail = previous

} else {

next.replacementPrevious = previous

}

item.replacementPrevious = undefined

item.replacementNext = undefined

--tileReplacementQueue.count

}

function trimTiles (tileQueue, maximumTiles) {

var tileToTrim = tileQueue.tail

while (tileQueue.count > maximumTiles &&

Cesium.defined(tileToTrim)) {

var previous = tileToTrim.replacementPrevious

remove(tileQueue, tileToTrim)

tileToTrim = null

tileToTrim = previous

}

}

MVTProvider.prototype.requestImage = function (x, y, level) {

var cacheTile = findTileInQueue(x, y, level, this._tileQueue)

if (cacheTile !== undefined) {

return cacheTile

}

var that = this

var url = this._url

url = url.replace('{x}', x).replace('{y}', y).replace('{z}', level).replace('{k}', this._key);

(function (x, y, z) {

var resource = Cesium.Resource.createIfNeeded(url)

return resource.fetchArrayBuffer().then((arrayBuffer) => {

var canvas = document.createElement('canvas')

canvas.width = 512

canvas.height = 512

var vectorContext = canvas.getContext('2d')

var features = that._mvtParser.readFeatures(arrayBuffer)

var styleFun = that._styleFun()

var extent = [0, 0, 4096, 4096]

var _replayGroup = new ol.render.canvas.ReplayGroup(0, extent, 8, true, 100)

for (var i = 0; i < features.length; i++) {

var feature = features[i]

var styles = styleFun(features[i], that._resolutions[level])

for (var j = 0; j < styles.length; j++) {

ol.renderer.vector.renderFeature_(_replayGroup, feature, styles[j], 16)

}

}

_replayGroup.finish()

_replayGroup.replay(vectorContext, that._pixelRatio, that._transform, 0, {}, that._replays, true)

if (that._tileQueue.count > that._cacheSize) {

trimTiles(that._tileQueue, that._cacheSize / 2)

}

canvas.xMvt = x

canvas.yMvt = y

canvas.zMvt = z

that._tileQueue.markTileRendered(canvas)

_replayGroup = null

return canvas

}).otherwise(() => {

})

}(x, y, level))

}

MVTProvider.prototype.pickFeatures = function () {

return undefined

}

function createMapboxStreetsV6Style () {

var fill = new ol.style.Fill({ color: '' })

var stroke = new ol.style.Stroke({ color: '', width: 1 })

var polygon = new ol.style.Style({ fill })

var strokedPolygon = new ol.style.Style({ fill, stroke })

var line = new ol.style.Style({ stroke })

var text = new ol.style.Style({

text: new ol.style.Text({

text: '', fill, stroke

})

})

var iconCache = {}

function getIcon (iconName) {

var icon = iconCache[iconName]

if (!icon) {

icon = new ol.style.Style({

image: new ol.style.Icon({

src: https://cdn.rawgit.com/mapbox/maki/master/icons/${iconName}-15.svg,

imgSize: [15, 15]

})

})

iconCache[iconName] = icon

}

return icon

}

var styles = []

return function (feature, resolution) {

var length = 0

var layer = feature.get('layer')

var cls = feature.get('class')

var type = feature.get('type')

var scalerank = feature.get('scalerank')

var labelrank = feature.get('labelrank')

var adminLevel = feature.get('admin_level')

var maritime = feature.get('maritime')

var disputed = feature.get('disputed')

var maki = feature.get('maki')

var geom = feature.getGeometry().getType()

if (layer === 'landuse' && cls === 'park') {

fill.setColor('#d8e8c8')

styles[length++] = polygon

} else if (layer === 'landuse' && cls === 'cemetery') {

fill.setColor('#e0e4dd')

styles[length++] = polygon

} else if (layer === 'landuse' && cls === 'hospital') {

fill.setColor('#fde')

styles[length++] = polygon

} else if (layer === 'landuse' && cls === 'school') {

fill.setColor('#f0e8f8')

styles[length++] = polygon

} else if (layer === 'landuse' && cls === 'wood') {

fill.setColor('rgb(233,238,223)')

styles[length++] = polygon

} else if (layer === 'waterway' &&

cls !== 'river' && cls !== 'stream' && cls !== 'canal') {

stroke.setColor('#a0c8f0')

總結(jié)

以上是生活随笔為你收集整理的mapbox矢量切片标准_Cesium 加载矢量切片(MapBox Vector Tile)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。