lg_frontend/static/libs/mars3d/thirdParty/pbf-ol/PbfolLayer.js

310 lines
8.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* MVT加载类 作者: 木遥(微信: http://marsgis.cn/weixin.html */
// import * as mars3d from "mars3d"
;(function (window) {
function MvtImageryProvider(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT)
this.options = options
this._tileWidth = Cesium.defaultValue(options.tileWidth, 512)
this._tileHeight = Cesium.defaultValue(options.tileHeight, 512)
this._minimumLevel = Cesium.defaultValue(options.minimumLevel, 0)
this._maximumLevel = Cesium.defaultValue(options.maximumLevel, 18)
if (options.rectangle && options.rectangle.xmin && options.rectangle.xmax && options.rectangle.ymin && options.rectangle.ymax) {
var xmin = options.rectangle.xmin
var xmax = options.rectangle.xmax
var ymin = options.rectangle.ymin
var ymax = options.rectangle.ymax
options.rectangle = Cesium.Rectangle.fromDegrees(xmin, ymin, xmax, ymax)
}
this._tilingScheme = Cesium.defaultValue(options.tilingScheme, new Cesium.WebMercatorTilingScheme({ ellipsoid: options.ellipsoid }))
this._rectangle = Cesium.defaultValue(options.rectangle, this._tilingScheme.rectangle)
this._rectangle = Cesium.Rectangle.intersection(this._rectangle, this._tilingScheme.rectangle)
this._hasAlphaChannel = Cesium.defaultValue(options.hasAlphaChannel, true)
this._errorEvent = new Cesium.Event()
this._readyPromise = Cesium.defer()
this._credit = undefined
this._ready = true
//mvt相关的处理
if (!window.ol) {
throw new DeveloperError("请引入Openlayers类库")
}
this._ol = window.ol
this._mvtParser = new this._ol.format.MVT()
this._key = Cesium.defaultValue(options.key, "")
this._url = Cesium.defaultValue(options.url, "")
if (options.styleConfig) {
//(glStyle, sources, resolutions = defaultResolutions, spriteData, spriteImageUrl, getFonts)
this._styleClass = window.olms.stylefunction(options.styleConfig, options.styleConfig.sources, "", null, null)
// this._url = options.styleConfig.tiles[0]
} else if (options.style) {
switch (options.style) {
case "mapbox-streets-v6":
this._styleClass = new mars3d.MapboxStreetsV6()
break
default:
this._styleClass = options.style
break
}
}
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, this._maximumLevel, 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(MvtImageryProvider.prototype, {
proxy: {
get: function () {
return undefined
}
},
tileWidth: {
get: function () {
return this._tileWidth
}
},
tileHeight: {
get: function () {
return this._tileHeight
}
},
maximumLevel: {
get: function () {
return undefined
}
},
minimumLevel: {
get: function () {
return undefined
}
},
tilingScheme: {
get: function () {
return this._tilingScheme
}
},
rectangle: {
get: function () {
return this._tilingScheme.rectangle
}
},
tileDiscardPolicy: {
get: function () {
return undefined
}
},
errorEvent: {
get: function () {
return this._errorEvent
}
},
ready: {
get: function () {
return true
}
},
readyPromise: {
get: function () {
return this._readyPromise.promise
}
},
credit: {
get: function () {
return undefined
}
},
hasAlphaChannel: {
get: function () {
return true
}
}
})
MvtImageryProvider.prototype.getTileCredits = function (x, y, level) {
return undefined
}
MvtImageryProvider.prototype.pickFeatures = function (x, y, level, longitude, latitude) {
return undefined
}
MvtImageryProvider.prototype.requestImage = function (x, y, level, request) {
var cacheTile = findTileInQueue(x, y, level, this._tileQueue)
if (cacheTile != undefined) {
return new Promise((resolve, reject) => {
resolve(cacheTile)
})
} else {
var that = this
var url = this._url
var reverseY = this._tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1
url = url.replace("{x}", x).replace("{y}", y).replace("{reverseY}", reverseY).replace("{z}", level).replace("{k}", this._key)
var resource = Cesium.Resource.createIfNeeded(url)
return resource.fetchArrayBuffer().then(function (arrayBuffer) {
var canvas = document.createElement("canvas")
canvas.width = that._tileWidth
canvas.height = that._tileHeight
var vectorContext = canvas.getContext("2d")
var features = that._mvtParser.readFeatures(arrayBuffer)
var styleFun = that._styleClass.getStyle()
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 = level
that._tileQueue.markTileRendered(canvas)
delete _replayGroup
_replayGroup = null
return canvas
})
}
}
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 removeQueue(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
removeQueue(tileQueue, tileToTrim)
delete tileToTrim
tileToTrim = null
tileToTrim = previous
}
}
class PbfolLayer extends mars3d.layer.BaseTileLayer {
_addedHook() {
let styleUrl = this.options.style
if (mars3d.Util.isString(styleUrl) && styleUrl.endsWith(".json")) {
this.getPbfStyle(styleUrl).then((data) => {
if (this.isAdded) {
super._addedHook()
}
})
} else {
super._addedHook()
}
}
//构建ImageryProvider
async _createImageryProvider(options) {
return createImageryProvider(options)
}
//取样式数据
getPbfStyle(styleUrl) {
return mars3d.Util.fetchJson({
url: styleUrl,
queryParameters: {
access_token: this.options.key || "mars3d"
}
})
.then((json) => {
this.options.styleConfig = json
})
.catch(function (error) {
console.log("加载样式出错", error)
})
}
}
async function createImageryProvider(options) {
return new MvtImageryProvider(options)
}
PbfolLayer.createImageryProvider = createImageryProvider
//注册下
const layerType = "mvt" //图层类型
mars3d.LayerUtil.register(layerType, PbfolLayer)
mars3d.LayerUtil.registerImageryProvider(layerType, createImageryProvider)
//对外接口
mars3d.provider.MvtImageryProvider = MvtImageryProvider
mars3d.layer.PbfolLayer = PbfolLayer
})(window)
// export { PbfolLayer }