Cesium在使用加载Cesium.ArcGisMapServerImageryProvider加载切片服务时,默认只支持wgs84的4326坐标系,不支持CGCS2000的4490坐标系。
如果是ArcGIS发布的4490坐标系的切片服务,如果原点在orgin X: -180.0Y: 90.0的情况下,我们可以通过WebMapTileServiceImageryProvider按照WMTS的方式加载(需符合OGC标准的WMTS类型)。
但是对于ArcGIS发布4490坐标系的切片服务,如果原点在orgin X: -400.0Y: 400.0的情况下,我们无法实现加载,本文通过示例演示实现Cesium加载ArcGIS Server4490且orgin -400 400的切片服务。
本文使用:
Cesium源码版本:1.94
源码打包测试参考另一篇文档:cesium源码编译调试及调用全过程
另外,本文的一些解释需要对切片原理有一定了解(想进一步了解的话可以去看看相关文档说明,不想了解的话按步骤修改就行了)。
为了能够调试源码,打包的时候使用命令:npm run combine
一、通过修改源码实现ArcGIS的切片服务,需要修改的源码文件包括:
- ArcGisMapServerImageryProvider
- GeographicTilingScheme
- Ellipsoid
1、修改ArcGisMapServerImageryProvider类
通过查看ArcGisMapServerImageryProvider(\Source\Scene\ArcGisMapServerImageryProvider.js)源码,我们发现它不支持CGCS2000的4490坐标系(仅支持wgs84的4326坐标系):

找到metadataSuccess方法,进行以下修改:
(1)读取切片元数据时增加支持wkid 4490坐标系的判断,同时将切片信息也传入,目的是为了后面在获取行列号xy时,可以通过读取切片信息,使用自定义方法改写行列号的获取方式。- else if (data.tileInfo.spatialReference.wkid === 4490) {
- that._tilingScheme = new GeographicTilingScheme({
- ellipsoid: options.ellipsoid,
- tileInfo: data.tileInfo,
- rectangle: that._rectangle,
- numberOfLevelZeroTilesX: options.numberOfLevelZeroTilesX,
- numberOfLevelZeroTilesY: options.numberOfLevelZeroTilesY
- });
-
- that._tilingScheme._tileInfo = data.tileInfo;//附加自定义属性
- }
复制代码 具体位置如图所示:

(2)fullExtent范围增加wkid 4490坐标系判断。- else if (data.fullExtent.spatialReference.wkid === 4326 || data.fullExtent.spatialReference.wkid === 4490) {
- that._rectangle = Rectangle.fromDegrees(
- data.fullExtent.xmin,
- data.fullExtent.ymin,
- data.fullExtent.xmax,
- data.fullExtent.ymax
- );
- }
复制代码 代码位置:

2、修改GeographicTilingScheme类
GeographicTilingScheme类的位置是:\Source\Core\GeographicTilingScheme.js
通过增加4490坐标系的椭球、矩阵范围等定义,4490坐标系默认椭球为CGCS2000,矩阵范围为(-180,-90,180,90),开放矩阵范围的目的就是为了支持自定义的origin原点。- if (defined(options.tileInfo)
- && defined(options.tileInfo.spatialReference)
- && defined(options.tileInfo.spatialReference.wkid)
- && options.tileInfo.spatialReference.wkid == 4490) {
- this._tileInfo = options.tileInfo;
- this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.CGCS2000);
- this._rectangle = defaultValue(options.rectangle, Rectangle.fromDegrees(-180, -90, 180, 90));
- this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 4);
- this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 2);
- }
- else {
- this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
- this._rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE);
- this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 2);
- this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1);
- }
- this._projection = new GeographicProjection(this._ellipsoid);
复制代码 代码位置:

(2)修改切片矩阵计算获取行列号数量xy值的原型方法getNumberOfXTilesAtLevel和getNumberOfYTilesAtLeve
[code]/** * Gets the total number of tiles in the X direction at a specified level-of-detail. * * @param {Number} level The level-of-detail. * @returns {Number} The number of tiles in the X direction at the given level. */GeographicTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) { // return this._numberOfLevelZeroTilesX |