美文网首页开源
An error occurred in "ArcGisMapS

An error occurred in "ArcGisMapS

作者: 彩色帆 | 来源:发表于2020-12-10 11:03 被阅读0次

    在cesium添加arcgis图层的时候,会遇到这个错误,显示4490坐标系不支持。
    通过修改源码,可以实现对于该数据的支持。
    目前,我的开发版本是1.62,仅供参考

    需要修改的部分有:
    1.修改 ArcGisMapServerImageryProvider.js
    177行

    } else if(data.tileInfo.spatialReference.wkid === 4490){
        that._tilingScheme = new GeographicTilingScheme({ 
            ellipsoid : options.ellipsoid,
            tileInfo:data.tileInfo
        });
    
    修改位置

    200行

    } 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);
    
    image.png

    2.修改GeographicTilingScheme.js
    我把全文都粘贴上了,可以自己看一下

    define([
            './Cartesian2',
            './Check',
            './defaultValue',
            './defined',
            './defineProperties',
            './Ellipsoid',
            './GeographicProjection',
            './Math',
            './Rectangle'
        ], function(
            Cartesian2,
            Check,
            defaultValue,
            defined,
            defineProperties,
            Ellipsoid,
            GeographicProjection,
            CesiumMath,
            Rectangle) {
        'use strict';
    
        /**
         * A tiling scheme for geometry referenced to a simple {@link GeographicProjection} where
         * longitude and latitude are directly mapped to X and Y.  This projection is commonly
         * known as geographic, equirectangular, equidistant cylindrical, or plate carrée.
         *
         * @alias GeographicTilingScheme
         * @constructor
         *
         * @param {Object} [options] Object with the following properties:
         * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to
         * the WGS84 ellipsoid.
         * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the tiling scheme.
         * @param {Number} [options.numberOfLevelZeroTilesX=2] The number of tiles in the X direction at level zero of
         * the tile tree.
         * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of
         * the tile tree.
         */
        function GeographicTilingScheme(options) {
            options = defaultValue(options, defaultValue.EMPTY_OBJECT);
    
            // this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
            // this._rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE);
            // this._projection = new GeographicProjection(this._ellipsoid);
            // this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 2);
            // this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1);
            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);
        }
    
        defineProperties(GeographicTilingScheme.prototype, {
            /**
             * Gets the ellipsoid that is tiled by this tiling scheme.
             * @memberof GeographicTilingScheme.prototype
             * @type {Ellipsoid}
             */
            ellipsoid : {
                get : function() {
                    return this._ellipsoid;
                }
            },
    
            /**
             * Gets the rectangle, in radians, covered by this tiling scheme.
             * @memberof GeographicTilingScheme.prototype
             * @type {Rectangle}
             */
            rectangle : {
                get : function() {
                    return this._rectangle;
                }
            },
    
            /**
             * Gets the map projection used by this tiling scheme.
             * @memberof GeographicTilingScheme.prototype
             * @type {MapProjection}
             */
            projection : {
                get : function() {
                    return this._projection;
                }
            }
        });
    
        /**
         * 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 << level;
            if(!defined(this._tileInfo))
            {
                return this._numberOfLevelZeroTilesX << level;
            }
            else 
            {
                var currentMatrix = this._tileInfo.lods.filter(function(item){
                    return item.level === level;
                });
                var currentResolution = currentMatrix[0].resolution;
                return Math.round(CesiumMath.toDegrees(CesiumMath.TWO_PI) / (this._tileInfo.rows * currentResolution));
            }
        };
    
        /**
         * Gets the total number of tiles in the Y direction at a specified level-of-detail.
         *
         * @param {Number} level The level-of-detail.
         * @returns {Number} The number of tiles in the Y direction at the given level.
         */
        GeographicTilingScheme.prototype.getNumberOfYTilesAtLevel = function(level) {
            // return this._numberOfLevelZeroTilesY << level;
            if(!defined(this._tileInfo))
            {
                return this._numberOfLevelZeroTilesY << level;
            }
            else 
            {
                var currentMatrix = this._tileInfo.lods.filter(function(item){
                    return item.level === level;
                });
                var currentResolution = currentMatrix[0].resolution;
                return Math.round(CesiumMath.toDegrees(CesiumMath.TWO_PI / 2) / (this._tileInfo.cols * currentResolution));
            }
        };
    
        /**
         * Transforms a rectangle specified in geodetic radians to the native coordinate system
         * of this tiling scheme.
         *
         * @param {Rectangle} rectangle The rectangle to transform.
         * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance
         *        should be created.
         * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result'
         *          is undefined.
         */
        GeographicTilingScheme.prototype.rectangleToNativeRectangle = function(rectangle, result) {
            //>>includeStart('debug', pragmas.debug);
            Check.defined('rectangle', rectangle);
            //>>includeEnd('debug');
    
            var west = CesiumMath.toDegrees(rectangle.west);
            var south = CesiumMath.toDegrees(rectangle.south);
            var east = CesiumMath.toDegrees(rectangle.east);
            var north = CesiumMath.toDegrees(rectangle.north);
    
            if (!defined(result)) {
                return new Rectangle(west, south, east, north);
            }
    
            result.west = west;
            result.south = south;
            result.east = east;
            result.north = north;
            return result;
        };
    
        /**
         * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates
         * of the tiling scheme.
         *
         * @param {Number} x The integer x coordinate of the tile.
         * @param {Number} y The integer y coordinate of the tile.
         * @param {Number} level The tile level-of-detail.  Zero is the least detailed.
         * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance
         *        should be created.
         * @returns {Rectangle} The specified 'result', or a new object containing the rectangle
         *          if 'result' is undefined.
         */
        GeographicTilingScheme.prototype.tileXYToNativeRectangle = function(x, y, level, result) {
            var rectangleRadians = this.tileXYToRectangle(x, y, level, result);
            rectangleRadians.west = CesiumMath.toDegrees(rectangleRadians.west);
            rectangleRadians.south = CesiumMath.toDegrees(rectangleRadians.south);
            rectangleRadians.east = CesiumMath.toDegrees(rectangleRadians.east);
            rectangleRadians.north = CesiumMath.toDegrees(rectangleRadians.north);
            return rectangleRadians;
        };
    
        /**
         * Converts tile x, y coordinates and level to a cartographic rectangle in radians.
         *
         * @param {Number} x The integer x coordinate of the tile.
         * @param {Number} y The integer y coordinate of the tile.
         * @param {Number} level The tile level-of-detail.  Zero is the least detailed.
         * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance
         *        should be created.
         * @returns {Rectangle} The specified 'result', or a new object containing the rectangle
         *          if 'result' is undefined.
         */
        GeographicTilingScheme.prototype.tileXYToRectangle = function(x, y, level, result) {
            // var rectangle = this._rectangle;
    
            // var xTiles = this.getNumberOfXTilesAtLevel(level);
            // var yTiles = this.getNumberOfYTilesAtLevel(level);
    
            // var xTileWidth = rectangle.width / xTiles;
            // var west = x * xTileWidth + rectangle.west;
            // var east = (x + 1) * xTileWidth + rectangle.west;
    
            // var yTileHeight = rectangle.height / yTiles;
            // var north = rectangle.north - y * yTileHeight;
            // var south = rectangle.north - (y + 1) * yTileHeight;
    
            // if (!defined(result)) {
            //     result = new Rectangle(west, south, east, north);
            // }
    
            // result.west = west;
            // result.south = south;
            // result.east = east;
            // result.north = north;
            // return result;
            var rectangle = this._rectangle;
            
            var west = 0;
            var east = 0;
            
            var north = 0;
            var south = 0;
            
            if(defined(this._tileInfo))
            {
                var currentMatrix = this._tileInfo.lods.filter(function(item){
                    return item.level === level;
                });
                var currentResolution = currentMatrix[0].resolution;
            
                north = this._tileInfo.origin.y - y * (this._tileInfo.cols * currentResolution);
                west = this._tileInfo.origin.x + x * (this._tileInfo.rows * currentResolution);
            
                south = this._tileInfo.origin.y - (y + 1) * (this._tileInfo.cols * currentResolution);
                east = this._tileInfo.origin.x + (x + 1) * (this._tileInfo.rows * currentResolution);
            
                west = CesiumMath.toRadians(west);
                north = CesiumMath.toRadians(north);
                east = CesiumMath.toRadians(east);
                south = CesiumMath.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 (!defined(result)) {
                result = new Rectangle(west, south, east, north);
            }
            
            result.west = west;
            result.south = south;
            result.east = east;
            result.north = north;
            return result;
        };
    
        /**
         * Calculates the tile x, y coordinates of the tile containing
         * a given cartographic position.
         *
         * @param {Cartographic} position The position.
         * @param {Number} level The tile level-of-detail.  Zero is the least detailed.
         * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance
         *        should be created.
         * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates
         *          if 'result' is undefined.
         */
        GeographicTilingScheme.prototype.positionToTileXY = function(position, level, result) {
            var rectangle = this._rectangle;
            if (!Rectangle.contains(rectangle, position)) {
                // outside the bounds of the tiling scheme
                return undefined;
            }
    
              if(defined(this._tileInfo))
                {
                    var currentMatrix = this._tileInfo.lods.filter(function(item){
                        return item.level === level;
                    });
                    var currentResolution = currentMatrix[0].resolution;
                    
                    var degLon = CesiumMath.toDegrees(position.longitude);
                    var degLat = CesiumMath.toDegrees(position.latitude);
             
                    var x_4490 = Math.floor( (degLon - this._tileInfo.origin.x) / (this._tileInfo.rows * currentResolution) );
                    var y_4490 = Math.floor( (this._tileInfo.origin.y - degLat) / (this._tileInfo.cols * currentResolution) );
             
                    return new Cartesian2(x_4490, y_4490);
                }
    
            var xTiles = this.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 += CesiumMath.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 (!defined(result)) {
                return new Cartesian2(xTileCoordinate, yTileCoordinate);
            }
    
            result.x = xTileCoordinate;
            result.y = yTileCoordinate;
            return result;
        };
    
        return GeographicTilingScheme;
    });
    

    3.修改Ellipsoid.js
    定义一个新的坐标系

    Ellipsoid.CGCS2000 = Object.freeze(new Ellipsoid(6378137.0, 6378137.0, 6356752.31414035585));
    
    image.png

    4.编译cesium

    因为这个示例的不支持跨域,所以考虑用vue设置了转发


    image.png image.png 结果

    参考文章:
    https://blog.csdn.net/yanasdf789/article/details/109103514

    相关文章

      网友评论

        本文标题:An error occurred in "ArcGisMapS

        本文链接:https://www.haomeiwen.com/subject/dqulgktx.html