310 lines
8.6 KiB
JavaScript
310 lines
8.6 KiB
JavaScript
|
|
/* 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 }
|