本文完全参考了这篇文章的内容,只是把TypeScript代码改成了JavaScript代码,感谢原作者的无私奉献
typescript代码链接
Cesium不改源码支持坐标系为4490的ArcGIS Rest缓存服务的解决方案,代码为TypeScript编写(vx gzh【图说GIS】)
JavaScript版本
由于很多项目在使用cesium的时候,还是用的JavaScript,所以我把代码改成了JavaScript版本,供大家分享。
GeographicTilingScheme4490.js
"use strict";
class GeographicTilingScheme4490 extends Cesium.GeographicTilingScheme {
options = {};
constructor(options) {
super(options);
console.log("create object");
this.options = options;
this.init();
}
init() {
console.log("init...");
const EllipsoidExt = new Cesium.Ellipsoid();
EllipsoidExt.CGCS2000 = Object.freeze(new Cesium.Ellipsoid(6378137.0, 6378137.0, 6356752.31414035585));
const { options } = this;
const self = this;
if (options
&& options.tileInfo
&& options.tileInfo.spatialReference
&& options.tileInfo.spatialReference.wkid
&& options.tileInfo.spatialReference.wkid == 4490) {
self._tileInfo = options.tileInfo;
self._ellipsoid = options.ellipsoid ? options.ellipsoid : EllipsoidExt.CGCS2000;
self._rectangle = options.rectangle ? options.rectangle : Cesium.Rectangle.fromDegrees(-180, -90, 180, 90);
self._numberOfLevelZeroTilesX = options.numberOfLevelZeroTilesX ? options.numberOfLevelZeroTilesX : 4;
self._numberOfLevelZeroTilesY = options.numberOfLevelZeroTilesY ? options.numberOfLevelZeroTilesY : 2;
}
self._projection = new Cesium.GeographicProjection(self._ellipsoid);
}
getNumberOfXTilesAtLevel(level) {
const self = this
if (!self._tileInfo) {
return self._numberOfLevelZeroTilesX << level;
}
else {
var currentMatrix = self._tileInfo.lods.filter(function (item) {
return item.level === level;
});
var currentResolution = currentMatrix[0].resolution;
return Math.round(Cesium.Math.toDegrees(Cesium.Math.TWO_PI) / (self._tileInfo.rows * currentResolution));
}
}
rectangleToNativeRectangle(rectangle, result) {
var west = Cesium.Math.toDegrees(rectangle.west);
var south = Cesium.Math.toDegrees(rectangle.south);
var east = Cesium.Math.toDegrees(rectangle.east);
var north = Cesium.Math.toDegrees(rectangle.north);
if (!result) {
return new Cesium.Rectangle(west, south, east, north);
}
result.west = west;
result.south = south;
result.east = east;
result.north = north;
return result;
}
tileXYToNativeRectangle(x, y, level, result) {
var rectangleRadians = this.tileXYToRectangle(x, y, level, result);
rectangleRadians.west = Cesium.Math.toDegrees(rectangleRadians.west);
rectangleRadians.south = Cesium.Math.toDegrees(rectangleRadians.south);
rectangleRadians.east = Cesium.Math.toDegrees(rectangleRadians.east);
rectangleRadians.north = Cesium.Math.toDegrees(rectangleRadians.north);
return rectangleRadians;
}
tileXYToRectangle(x, y, level, result) {
const self = this
var rectangle = self._rectangle;
var west = 0;
var east = 0;
var north = 0;
var south = 0;
if (self._tileInfo) {
var currentMatrix = self._tileInfo.lods.filter(function (item) {
return item.level === level;
});
var currentResolution = currentMatrix[0].resolution;
north = self._tileInfo.origin.y - y * (self._tileInfo.cols * currentResolution);
west = self._tileInfo.origin.x + x * (self._tileInfo.rows * currentResolution);
south = self._tileInfo.origin.y - (y + 1) * (self._tileInfo.cols * currentResolution);
east = self._tileInfo.origin.x + (x + 1) * (self._tileInfo.rows * currentResolution);
west = Cesium.Math.toRadians(west);
north = Cesium.Math.toRadians(north);
east = Cesium.Math.toRadians(east);
south = Cesium.Math.toRadians(south);
}
else {
var xTiles = this.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);
var xTileWidth = rectangle.width / xTiles;
west = x * xTileWidth + rectangle.west;
east = (x + 1) * xTileWidth + rectangle.west;
var yTileHeight = rectangle.height / yTiles;
north = rectangle.north - y * yTileHeight;
south = rectangle.north - (y + 1) * yTileHeight;
}
if (!result) {
result = new Cesium.Rectangle(west, south, east, north);
}
result.west = west;
result.south = south;
result.east = east;
result.north = north;
return result;
}
positionToTileXY(
position,
level,
result) {
const self = this
var rectangle = self._rectangle;
if (!Cesium.Rectangle.contains(rectangle, position)) {
// outside the bounds of the tiling scheme
return undefined;
}
if (self._tileInfo) {
var currentMatrix = self._tileInfo.lods.filter(function (item) {
return item.level === level;
});
var currentResolution = currentMatrix[0].resolution;
var degLon = Cesium.Math.toDegrees(position.longitude);
var degLat = Cesium.Math.toDegrees(position.latitude);
var x_4490 = Math.floor((degLon - self._tileInfo.origin.x) / (self._tileInfo.rows * currentResolution));
var y_4490 = Math.floor((self._tileInfo.origin.y - degLat) / (self._tileInfo.cols * currentResolution));
return new Cesium.Cartesian2(x_4490, y_4490);
}
var xTiles = self.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);
var xTileWidth = rectangle.width / xTiles;
var yTileHeight = rectangle.height / yTiles;
var longitude = position.longitude;
if (rectangle.east < rectangle.west) {
longitude += Cesium.Math.TWO_PI;
}
var xTileCoordinate = ((longitude - rectangle.west) / xTileWidth) | 0;
if (xTileCoordinate >= xTiles) {
xTileCoordinate = xTiles - 1;
}
var yTileCoordinate =
((rectangle.north - position.latitude) / yTileHeight) | 0;
if (yTileCoordinate >= yTiles) {
yTileCoordinate = yTiles - 1;
}
if (!result) {
return new Cesium.Cartesian2(xTileCoordinate, yTileCoordinate);
}
result.x = xTileCoordinate;
result.y = yTileCoordinate;
return result;
}
}
export default GeographicTilingScheme4490;
ArcGisMapServerImageryProvider4490.js
"use strict";
import GeographicTilingScheme4490 from "./GeographicTilingScheme4490";
class ArcGisMapServerImageryProvider4490 extends Cesium.ArcGisMapServerImageryProvider {
options = {};
constructor(options) {
super(options)
this.options = options
this.init()
}
init() {
const self = this
function requestMetadata() {
const resource = self._resource.getDerivedResource({
queryParameters: {
f: "json",
},
});
const metadata = resource.fetchJsonp();
metadata.then((data) => {
self.metadata4490Success(data)
})
}
requestMetadata()
}
metadata4490Success(data) {
const tileInfo = data.tileInfo;
if (data.spatialReference.wkid === 4490 && tileInfo) {
const self = this
const { options } = this
if (options) {
if (data.tileInfo.spatialReference.wkid === 4490) {
const geoTilingScheme = new GeographicTilingScheme4490({
ellipsoid: options.ellipsoid,
tileInfo: tileInfo
});
self._tilingScheme = geoTilingScheme
}
self._maximumLevel = tileInfo.lods.length - 1;
self._useTiles = true;
if (data.fullExtent) {
if (
data.fullExtent.spatialReference &&
data.fullExtent.spatialReference.wkid
) {
if (data.fullExtent.spatialReference.wkid === 4490) {
self._rectangle = Cesium.Rectangle.fromDegrees(
data.fullExtent.xmin,
data.fullExtent.ymin,
data.fullExtent.xmax,
data.fullExtent.ymax
);
}
}
} else {
self._rectangle = self._tilingScheme.rectangle;
}
// Install the default tile discard policy if none has been supplied.
if (!self._tileDiscardPolicy) {
self._tileDiscardPolicy = new Cesium.DiscardMissingTileImagePolicy({
missingImageUrl: self.buildImageResource(self, 0, 0, self._maximumLevel).url,
pixelsToCheck: [
new Cesium.Cartesian2(0, 0),
new Cesium.Cartesian2(200, 20),
new Cesium.Cartesian2(20, 200),
new Cesium.Cartesian2(80, 110),
new Cesium.Cartesian2(160, 130),
],
disableCheckIfAllPixelsAreTransparent: true,
});
}
}
if (data.copyrightText && data.copyrightText.length > 0) {
self._credit = new Cesium.Credit(data.copyrightText);
}
self._ready = true;
self._readyPromise.resolve(true);
}
}
buildImageResource(imageryProvider, x, y, level, request) {
var resource;
if (imageryProvider._useTiles) {
resource = imageryProvider._resource.getDerivedResource({
url: "tile/" + level + "/" + y + "/" + x,
request: request,
});
} else {
var nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(
x,
y,
level
);
var bbox =
nativeRectangle.west +
"," +
nativeRectangle.south +
"," +
nativeRectangle.east +
"," +
nativeRectangle.north;
var query = {
bbox: bbox,
size: imageryProvider._tileWidth + "," + imageryProvider._tileHeight,
format: "png32",
transparent: true,
f: "image",
};
if (
imageryProvider._tilingScheme.projection instanceof Cesium.GeographicProjection
) {
query.bboxSR = 4490;
query.imageSR = 4490;
} else {
query.bboxSR = 3857;
query.imageSR = 3857;
}
if (imageryProvider.layers) {
query.layers = "show:" + imageryProvider.layers;
}
resource = imageryProvider._resource.getDerivedResource({
url: "export",
request: request,
queryParameters: query,
});
}
return resource;
}
}
export default ArcGisMapServerImageryProvider4490;
使用
const szdomProvider = new ArcGisMapServerImageryProvider4490({
url: "ArcgisServer URL",
});
viewer.imageryLayers.addImageryProvider(szdomProvider);
评论区