CaiYuanYiTiHua/public/bigScreen/lib/mars3d/plugins/pbf/mvt.js

281 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* MVT加载类 作者: 木遥(微信: http://marsgis.cn/weixin.html */
(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.when.resolve(true);
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();
switch (options.style) {
case "mapbox-streets-v6":
this._styleClass = new mars3d.MapboxStreetsV6()
break;
default:
this._styleClass = options.style;
break;
}
this._key = Cesium.defaultValue(options.key, "");
this._url = Cesium.defaultValue(options.url, "");
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;
}
},
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 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;
}).otherwise(function (error) {
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 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;
}
};
function createImageryProvider (options) {
return new MvtImageryProvider(options)
}
class MvtLayer extends mars3d.layer.BaseTileLayer {
//构建ImageryProvider
_createImageryProvider (options, urltemplate) {
return createImageryProvider(options, urltemplate)
}
}
MvtLayer.createImageryProvider = createImageryProvider
//注册下
const layerType = 'mvt'//图层类型
mars3d.layer.register(layerType, MvtLayer)
mars3d.layer.registerImageryProvider(layerType, createImageryProvider)
//对外接口
window.mars3d.provider.MvtImageryProvider = MvtImageryProvider;
window.mars3d.layer.MvtLayer = MvtLayer;
})(window);