2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > mapbox矢量切片标准_Cesium 加载矢量切片(MapBox Vector Tile)

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

时间:2020-08-12 05:35:00

相关推荐

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

矢量切片(vector tile)是当前 WebGIS 较热技术,国内的高德、百度等在线地图都使用了矢量切片技术。相较于传统栅格切片,矢量切片好处很多。简单几点就是:轻量、客户端渲染、还可加密(栅格切片容易被爬取)。矢量切片格式一般有 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./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: /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')

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。