Cesium---1.133版本不修改源码支持arcgis MapServer 4490切片

发布于:2025-09-12 ⋅ 阅读:(22) ⋅ 点赞:(0)

参照了这篇博文:https://blog.csdn.net/qq_19689967/article/details/121449888https://blog.csdn.net/qq_19689967/article/details/121449888

利用新版本的源码进行了修改,可以实现服务加载:

Event.js

import { Check,defined} from "cesium";
/**
 * A generic utility class for managing subscribers for a particular event.
 * This class is usually instantiated inside of a container class and
 * exposed as a property for others to subscribe to.
 *
 * @alias Event
 * @template Listener extends (...args: any[]) => void = (...args: any[]) => void
 * @constructor
 * @example
 * MyObject.prototype.myListener = function(arg1, arg2) {
 *     this.myArg1Copy = arg1;
 *     this.myArg2Copy = arg2;
 * }
 *
 * const myObjectInstance = new MyObject();
 * const evt = new Cesium.Event();
 * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance);
 * evt.raiseEvent('1', '2');
 * evt.removeEventListener(MyObject.prototype.myListener);
 */
function Event() {
  this._listeners = [];
  this._scopes = [];
  this._toRemove = [];
  this._insideRaiseEvent = false;
}

Object.defineProperties(Event.prototype, {
  /**
   * The number of listeners currently subscribed to the event.
   * @memberof Event.prototype
   * @type {number}
   * @readonly
   */
  numberOfListeners: {
    get: function () {
      return this._listeners.length - this._toRemove.length;
    },
  },
});

/**
 * Registers a callback function to be executed whenever the event is raised.
 * An optional scope can be provided to serve as the <code>this</code> pointer
 * in which the function will execute.
 *
 * @param {Listener} listener The function to be executed when the event is raised.
 * @param {object} [scope] An optional object scope to serve as the <code>this</code>
 *        pointer in which the listener function will execute.
 * @returns {Event.RemoveCallback} A function that will remove this event listener when invoked.
 *
 * @see Event#raiseEvent
 * @see Event#removeEventListener
 */
Event.prototype.addEventListener = function (listener, scope) {
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.func("listener", listener);
  //>>includeEnd('debug');

  this._listeners.push(listener);
  this._scopes.push(scope);

  const event = this;
  return function () {
    event.removeEventListener(listener, scope);
  };
};

/**
 * Unregisters a previously registered callback.
 *
 * @param {Listener} listener The function to be unregistered.
 * @param {object} [scope] The scope that was originally passed to addEventListener.
 * @returns {boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event.
 *
 * @see Event#addEventListener
 * @see Event#raiseEvent
 */
Event.prototype.removeEventListener = function (listener, scope) {
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.func("listener", listener);
  //>>includeEnd('debug');

  const listeners = this._listeners;
  const scopes = this._scopes;

  let index = -1;
  for (let i = 0; i < listeners.length; i++) {
    if (listeners[i] === listener && scopes[i] === scope) {
      index = i;
      break;
    }
  }

  if (index !== -1) {
    if (this._insideRaiseEvent) {
      //In order to allow removing an event subscription from within
      //a callback, we don't actually remove the items here.  Instead
      //remember the index they are at and undefined their value.
      this._toRemove.push(index);
      listeners[index] = undefined;
      scopes[index] = undefined;
    } else {
      listeners.splice(index, 1);
      scopes.splice(index, 1);
    }
    return true;
  }

  return false;
};

function compareNumber(a, b) {
  return b - a;
}

/**
 * Raises the event by calling each registered listener with all supplied arguments.
 *
 * @param {...Parameters<Listener>} arguments This method takes any number of parameters and passes them through to the listener functions.
 *
 * @see Event#addEventListener
 * @see Event#removeEventListener
 */
Event.prototype.raiseEvent = function () {
  this._insideRaiseEvent = true;

  let i;
  const listeners = this._listeners;
  const scopes = this._scopes;
  let length = listeners.length;

  for (i = 0; i < length; i++) {
    const listener = listeners[i];
    if (defined(listener)) {
      listeners[i].apply(scopes[i], arguments);
    }
  }

  //Actually remove items removed in removeEventListener.
  const toRemove = this._toRemove;
  length = toRemove.length;
  if (length > 0) {
    toRemove.sort(compareNumber);
    for (i = 0; i < length; i++) {
      const index = toRemove[i];
      listeners.splice(index, 1);
      scopes.splice(index, 1);
    }
    toRemove.length = 0;
  }

  this._insideRaiseEvent = false;
};

/**
 * A function that removes a listener.
 * @callback Event.RemoveCallback
 */

export default Event;

GeographicTilingScheme4490.js

import { defaultValue, defined, Ellipsoid, GeographicProjection, GeographicTilingScheme, Rectangle, Math as CesiumMath, Cartesian2 } from "cesium";

export class GeographicTilingScheme4490 extends GeographicTilingScheme {
    constructor(options) {
        super(options)
        this.options = options
        this.init()
    }
    init() {
        const EllipsoidExt = Ellipsoid;
        EllipsoidExt.CGCS2000 = Object.freeze(new Ellipsoid(6378137.0, 6378137.0, 6356752.31414035585));

        const { options } = this
        const self = this
        if (defined(options.tileInfo)
            && defined(options.tileInfo.spatialReference)
            && defined(options.tileInfo.spatialReference.wkid)
            && options.tileInfo.spatialReference.wkid == 4490) {
            self._tileInfo = options.tileInfo;
            self._ellipsoid = defaultValue(options.ellipsoid, EllipsoidExt.CGCS2000);
            self._rectangle = Rectangle.fromDegrees(-200, -90, 200, 90);
            self._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 4);
            self._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 2);
        }
        else {
            self._ellipsoid = defaultValue(options.ellipsoid,Ellipsoid.WGS84);
            self._rectangle = defaultValue(options.rectangle,Rectangle.MAX_VALUE);
            self._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 2);
            self._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1);
        }
        self._projection = new GeographicProjection(self._ellipsoid);
    }
    getNumberOfXTilesAtLevel(level) {
        const self = this
        if (!defined(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(CesiumMath.toDegrees(CesiumMath.TWO_PI) / (self._tileInfo.rows * currentResolution));
        }
    }
    getNumberOfYTilesAtLevel(level) {
        const self = this
        if (!defined(self._tileInfo)) {
            return self._numberOfLevelZeroTilesY << level;
        }
        else {
            var currentMatrix = self._tileInfo.lods.filter(function (item) {
                return item.level === level;
            });
            var currentResolution = currentMatrix[0].resolution;
            return Math.round(CesiumMath.toDegrees(CesiumMath.TWO_PI / 2) / (self._tileInfo.cols * currentResolution));
        }
    }
    rectangleToNativeRectangle(rectangle, result) {
        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;
    };
    tileXYToNativeRectangle(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;
    };
    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 (defined(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 = 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;
    };
    positionToTileXY(
        position,
        level,
        result
    ) {
        const self = this
        var rectangle = self._rectangle;
        if (!Rectangle.contains(rectangle, position)) {
            // outside the bounds of the tiling scheme
            return undefined;
        }

        if (defined(self._tileInfo)) {
            var currentMatrix = self._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 - self._tileInfo.origin.x) / (self._tileInfo.rows * currentResolution));
            var y_4490 = Math.floor((self._tileInfo.origin.y - degLat) / (self._tileInfo.cols * currentResolution));

            return new 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 += 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;
    }
}

ArcGisMapServerImageryProviderExt.js

import { Cartesian2, Cartesian3,Cartographic, Check, Credit, Frozen, defined, 
    GeographicProjection,GeographicTilingScheme,Rectangle,Resource,
RuntimeError,WebMercatorProjection,WebMercatorTilingScheme,
ArcGisMapService,DiscardMissingTileImagePolicy,
ImageryLayerFeatureInfo,ImageryProvider,ArcGisBaseMapType,DeveloperError,Math as CesiumMath} from "cesium";

import { GeographicTilingScheme4490 } from "./GeographicTilingScheme4490";
import Event from "./Event";

/**
 * 支撑arcGis4490坐标系的影像图层提供者
 * @param {*} options 
 */
function ImageryProviderBuilder(options) {
  this.useTiles = options.usePreCachedTilesIfAvailable ?? true;

  const ellipsoid = options.ellipsoid;
  this.tilingScheme =
    options.tilingScheme ??
    new GeographicTilingScheme({ ellipsoid: ellipsoid });
  this.rectangle = options.rectangle ?? this.tilingScheme.rectangle;
  this.ellipsoid = ellipsoid;

  let credit = options.credit;
  if (typeof credit === "string") {
    credit = new Credit(credit);
  }
  this.credit = credit;
  this.tileCredits = undefined;
  this.tileDiscardPolicy = options.tileDiscardPolicy;

  this.tileWidth = options.tileWidth ?? 256;
  this.tileHeight = options.tileHeight ?? 256;
  this.maximumLevel = options.maximumLevel;
}

ImageryProviderBuilder.prototype.build = function (provider) {
  provider._useTiles = this.useTiles;
  provider._tilingScheme = this.tilingScheme;
  provider._rectangle = this.rectangle;
  provider._credit = this.credit;
  provider._tileCredits = this.tileCredits;
  provider._tileDiscardPolicy = this.tileDiscardPolicy;
  provider._tileWidth = this.tileWidth;
  provider._tileHeight = this.tileHeight;
  provider._maximumLevel = this.maximumLevel;

  // Install the default tile discard policy if none has been supplied.
  if (this.useTiles && !defined(this.tileDiscardPolicy)) {
    provider._tileDiscardPolicy = new DiscardMissingTileImagePolicy({
      missingImageUrl: buildImageResource(provider, 0, 0, this.maximumLevel)
        .url,
      pixelsToCheck: [
        new Cartesian2(0, 0),
        new Cartesian2(200, 20),
        new Cartesian2(20, 200),
        new Cartesian2(80, 110),
        new Cartesian2(160, 130),
      ],
      disableCheckIfAllPixelsAreTransparent: true,
    });
  }
};

function metadataSuccess(data, imageryProviderBuilder) {
  const tileInfo = data.tileInfo;
  if (!defined(tileInfo)) {
    imageryProviderBuilder.useTiles = false;
  } else {
    imageryProviderBuilder.tileWidth = tileInfo.rows;
    imageryProviderBuilder.tileHeight = tileInfo.cols;

    if (
      tileInfo.spatialReference.wkid === 102100 ||
      tileInfo.spatialReference.wkid === 102113
    ) {
      imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({
        ellipsoid: imageryProviderBuilder.ellipsoid,
      });
    } else if (data.tileInfo.spatialReference.wkid === 4326) {
      imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({
        ellipsoid: imageryProviderBuilder.ellipsoid,
      });
    }else if (data.tileInfo.spatialReference.wkid === 4490) {
        const geoTilingScheme = new GeographicTilingScheme4490({
            tileInfo: tileInfo
        });
        imageryProviderBuilder.tilingScheme = geoTilingScheme
    }else {
      const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`;
      throw new RuntimeError(message);
    }
    imageryProviderBuilder.maximumLevel = data.tileInfo.lods.length - 1;

    if (defined(data.fullExtent)) {
      if (
        defined(data.fullExtent.spatialReference) &&
        defined(data.fullExtent.spatialReference.wkid)
      ) {
        if (
          data.fullExtent.spatialReference.wkid === 102100 ||
          data.fullExtent.spatialReference.wkid === 102113
        ) {
          const projection = new WebMercatorProjection();
          const extent = data.fullExtent;
          const sw = projection.unproject(
            new Cartesian3(
              Math.max(
                extent.xmin,
                -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
                  Math.PI,
              ),
              Math.max(
                extent.ymin,
                -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
                  Math.PI,
              ),
              0.0,
            ),
          );
          const ne = projection.unproject(
            new Cartesian3(
              Math.min(
                extent.xmax,
                imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
                  Math.PI,
              ),
              Math.min(
                extent.ymax,
                imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
                  Math.PI,
              ),
              0.0,
            ),
          );
            imageryProviderBuilder.rectangle = new Rectangle(
                sw.longitude,
                sw.latitude,
                ne.longitude,
                ne.latitude,
            );
        } else if (data.fullExtent.spatialReference.wkid === 4326) {
            imageryProviderBuilder.rectangle = Rectangle.fromDegrees(
                data.fullExtent.xmin,
                data.fullExtent.ymin,
                data.fullExtent.xmax,
                data.fullExtent.ymax,
            );
        }
        else  if (data.fullExtent.spatialReference.wkid === 4490) {
            imageryProviderBuilder.rectangle = Rectangle.fromDegrees(
                data.fullExtent.xmin,
                data.fullExtent.ymin,
                data.fullExtent.xmax,
                data.fullExtent.ymax
            );
        }
        else {
          const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`;
          throw new RuntimeError(extentMessage);
        }
      }
    } else {
      imageryProviderBuilder.rectangle =
        imageryProviderBuilder.tilingScheme.rectangle;
    }

    imageryProviderBuilder.useTiles = true;
  }

  if (defined(data.copyrightText) && data.copyrightText.length > 0) {
    if (defined(imageryProviderBuilder.credit)) {
      imageryProviderBuilder.tileCredits = [new Credit(data.copyrightText)];
    } else {
      imageryProviderBuilder.credit = new Credit(data.copyrightText);
    }
  }
}

function metadataFailure(resource, error) {
  let message = `An error occurred while accessing ${resource.url}`;
  if (defined(error) && defined(error.message)) {
    message += `: ${error.message}`;
  }

  throw new RuntimeError(message);
}

async function requestMetadata(resource, imageryProviderBuilder) {
  const jsonResource = resource.getDerivedResource({
    queryParameters: {
      f: "json",
    },
  });

  try {
    const data = await jsonResource.fetchJson();
    metadataSuccess(data, imageryProviderBuilder);
  } catch (error) {
    metadataFailure(resource, error);
  }
}


function ArcGisMapServerImageryProvider(options) {
  options = options ?? Frozen.EMPTY_OBJECT;

  this._defaultAlpha = undefined;
  this._defaultNightAlpha = undefined;
  this._defaultDayAlpha = undefined;
  this._defaultBrightness = undefined;
  this._defaultContrast = undefined;
  this._defaultHue = undefined;
  this._defaultSaturation = undefined;
  this._defaultGamma = undefined;
  this._defaultMinificationFilter = undefined;
  this._defaultMagnificationFilter = undefined;

  this._tileDiscardPolicy = options.tileDiscardPolicy;
  this._tileWidth = options.tileWidth ?? 256;
  this._tileHeight = options.tileHeight ?? 256;
  this._maximumLevel = options.maximumLevel;
  this._tilingScheme =
    options.tilingScheme ??
    new GeographicTilingScheme({ ellipsoid: options.ellipsoid });
  this._useTiles = options.usePreCachedTilesIfAvailable ?? true;
  this._rectangle = options.rectangle ?? this._tilingScheme.rectangle;
  this._layers = options.layers;
  this._credit = options.credit;
  this._tileCredits = undefined;

  let credit = options.credit;
  if (typeof credit === "string") {
    credit = new Credit(credit);
  }

  this.enablePickFeatures = options.enablePickFeatures ?? true;

  this._errorEvent = new Event();
}

ArcGisMapServerImageryProvider.fromBasemapType = async function (
  style,
  options,
) {
  //>>includeStart('debug', pragmas.debug);
  Check.defined("style", style);
  //>>includeEnd('debug');

  options = options ?? Frozen.EMPTY_OBJECT;
  let accessToken;
  let server;
  let warningCredit;
  switch (style) {
    case ArcGisBaseMapType.SATELLITE:
      {
        accessToken = options.token ?? ArcGisMapService.defaultAccessToken;
        server = Resource.createIfNeeded(
          ArcGisMapService.defaultWorldImageryServer,
        );
        server.appendForwardSlash();
        const defaultTokenCredit =
          ArcGisMapService.getDefaultTokenCredit(accessToken);
        if (defined(defaultTokenCredit)) {
          warningCredit = Credit.clone(defaultTokenCredit);
        }
      }
      break;
    case ArcGisBaseMapType.OCEANS:
      {
        accessToken = options.token ?? ArcGisMapService.defaultAccessToken;
        server = Resource.createIfNeeded(
          ArcGisMapService.defaultWorldOceanServer,
        );
        server.appendForwardSlash();
        const defaultTokenCredit =
          ArcGisMapService.getDefaultTokenCredit(accessToken);
        if (defined(defaultTokenCredit)) {
          warningCredit = Credit.clone(defaultTokenCredit);
        }
      }
      break;
    case ArcGisBaseMapType.HILLSHADE:
      {
        accessToken = options.token ?? ArcGisMapService.defaultAccessToken;
        server = Resource.createIfNeeded(
          ArcGisMapService.defaultWorldHillshadeServer,
        );
        server.appendForwardSlash();
        const defaultTokenCredit =
          ArcGisMapService.getDefaultTokenCredit(accessToken);
        if (defined(defaultTokenCredit)) {
          warningCredit = Credit.clone(defaultTokenCredit);
        }
      }
      break;
    default:
      //>>includeStart('debug', pragmas.debug);
      throw new DeveloperError(`Unsupported basemap type: ${style}`);
    //>>includeEnd('debug');
  }

  return ArcGisMapServerImageryProvider.fromUrl(server, {
    ...options,
    token: accessToken,
    credit: warningCredit,
    usePreCachedTilesIfAvailable: true, // ArcGIS Base Map Service Layers only support Tiled views
  });
};

function buildImageResource(imageryProvider, x, y, level, request) {
  let resource;
  if (imageryProvider._useTiles) {
    resource = imageryProvider._resource.getDerivedResource({
      url: `tile/${level}/${y}/${x}`,
      request: request,
    });
  } else {
    const nativeRectangle =
      imageryProvider._tilingScheme.tileXYToNativeRectangle(x, y, level);
    const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;

    const query = {
      bbox: bbox,
      size: `${imageryProvider._tileWidth},${imageryProvider._tileHeight}`,
      format: "png32",
      transparent: true,
      f: "image",
    };

    if (
      imageryProvider._tilingScheme.projection instanceof 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;
}

Object.defineProperties(ArcGisMapServerImageryProvider.prototype, {
  /**
   * Gets the URL of the ArcGIS MapServer.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {string}
   * @readonly
   */
  url: {
    get: function () {
      return this._resource._url;
    },
  },

  /**
   * Gets the ArcGIS token used to authenticate with the ArcGis MapServer service.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {string}
   * @readonly
   */
  token: {
    get: function () {
      return this._resource.queryParameters.token;
    },
  },

  /**
   * Gets the proxy used by this provider.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {Proxy}
   * @readonly
   */
  proxy: {
    get: function () {
      return this._resource.proxy;
    },
  },

  /**
   * Gets the width of each tile, in pixels.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {number}
   * @readonly
   */
  tileWidth: {
    get: function () {
      return this._tileWidth;
    },
  },

  /**
   * Gets the height of each tile, in pixels.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {number}
   * @readonly
   */
  tileHeight: {
    get: function () {
      return this._tileHeight;
    },
  },

  /**
   * Gets the maximum level-of-detail that can be requested.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {number|undefined}
   * @readonly
   */
  maximumLevel: {
    get: function () {
      return this._maximumLevel;
    },
  },

  /**
   * Gets the minimum level-of-detail that can be requested.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {number}
   * @readonly
   */
  minimumLevel: {
    get: function () {
      return 0;
    },
  },

  /**
   * Gets the tiling scheme used by this provider.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {TilingScheme}
   * @readonly
   */
  tilingScheme: {
    get: function () {
      return this._tilingScheme;
    },
  },

  /**
   * Gets the rectangle, in radians, of the imagery provided by this instance.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {Rectangle}
   * @readonly
   */
  rectangle: {
    get: function () {
      return this._rectangle;
    },
  },

  /**
   * Gets the tile discard policy.  If not undefined, the discard policy is responsible
   * for filtering out "missing" tiles via its shouldDiscardImage function.  If this function
   * returns undefined, no tiles are filtered.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {TileDiscardPolicy}
   * @readonly
   */
  tileDiscardPolicy: {
    get: function () {
      return this._tileDiscardPolicy;
    },
  },

  /**
   * Gets an event that is raised when the imagery provider encounters an asynchronous error.  By subscribing
   * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
   * are passed an instance of {@link TileProviderError}.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {Event}
   * @readonly
   */
  errorEvent: {
    get: function () {
      return this._errorEvent;
    },
  },

  /**
   * Gets the credit to display when this imagery provider is active.  Typically this is used to credit
   * the source of the imagery.
   * @memberof ArcGisMapServerImageryProvider.prototype
   * @type {Credit}
   * @readonly
   */
  credit: {
    get: function () {
      return this._credit;
    },
  },

  /**
   * Gets a value indicating whether this imagery provider is using pre-cached tiles from the
   * ArcGIS MapServer.
   * @memberof ArcGisMapServerImageryProvider.prototype
   *
   * @type {boolean}
   * @readonly
   * @default true
   */
  usingPrecachedTiles: {
    get: function () {
      return this._useTiles;
    },
  },

  /**
   * Gets a value indicating whether or not the images provided by this imagery provider
   * include an alpha channel.  If this property is false, an alpha channel, if present, will
   * be ignored.  If this property is true, any images without an alpha channel will be treated
   * as if their alpha is 1.0 everywhere.  When this property is false, memory usage
   * and texture upload time are reduced.
   * @memberof ArcGisMapServerImageryProvider.prototype
   *
   * @type {boolean}
   * @readonly
   * @default true
   */
  hasAlphaChannel: {
    get: function () {
      return true;
    },
  },

  /**
   * Gets the comma-separated list of layer IDs to show.
   * @memberof ArcGisMapServerImageryProvider.prototype
   *
   * @type {string}
   */
  layers: {
    get: function () {
      return this._layers;
    },
  },
});

/**
 * Creates an {@link ImageryProvider} which provides tiled imagery hosted by an ArcGIS MapServer.  By default, the server's pre-cached tiles are
 * used, if available.
 *
 * @param {Resource|String} url The URL of the ArcGIS MapServer service.
 * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options.
 * @returns {Promise<ArcGisMapServerImageryProvider>} A promise that resolves to the created ArcGisMapServerImageryProvider.
 *
 * @example
 * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
 *     "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
 * );
 *
 * @exception {RuntimeError} metadata spatial reference specifies an unknown WKID
 * @exception {RuntimeError} metadata fullExtent.spatialReference specifies an unknown WKID
 */
ArcGisMapServerImageryProvider.fromUrl = async function (url, options) {
  //>>includeStart('debug', pragmas.debug);
  Check.defined("url", url);
  //>>includeEnd('debug');
  options = options ?? Frozen.EMPTY_OBJECT;

  const resource = Resource.createIfNeeded(url);
  resource.appendForwardSlash();

  if (defined(options.token)) {
    resource.setQueryParameters({
      token: options.token,
    });
  }

  const provider = new ArcGisMapServerImageryProvider(options);
  provider._resource = resource;
  const imageryProviderBuilder = new ImageryProviderBuilder(options);
  const useTiles = options.usePreCachedTilesIfAvailable ?? true;
  if (useTiles) {
    await requestMetadata(resource, imageryProviderBuilder);
  }

  imageryProviderBuilder.build(provider);
  return provider;
};

/**
 * Gets the credits to be displayed when a given tile is displayed.
 *
 * @param {number} x The tile X coordinate.
 * @param {number} y The tile Y coordinate.
 * @param {number} level The tile level;
 * @returns {Credit[]} The credits to be displayed when the tile is displayed.
 */
ArcGisMapServerImageryProvider.prototype.getTileCredits = function (
  x,
  y,
  level,
) {
  return this._tileCredits;
};

/**
 * Requests the image for a given tile.
 *
 * @param {number} x The tile X coordinate.
 * @param {number} y The tile Y coordinate.
 * @param {number} level The tile level.
 * @param {Request} [request] The request object. Intended for internal use only.
 * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or
 *          undefined if there are too many active requests to the server, and the request should be retried later.
 */
ArcGisMapServerImageryProvider.prototype.requestImage = function (
  x,
  y,
  level,
  request,
) {
  return ImageryProvider.loadImage(
    this,
    buildImageResource(this, x, y, level, request),
  );
};

/**
    /**
     * Asynchronously determines what features, if any, are located at a given longitude and latitude within
     * a tile.
     *
     * @param {number} x The tile X coordinate.
     * @param {number} y The tile Y coordinate.
     * @param {number} level The tile level.
     * @param {number} longitude The longitude at which to pick features.
     * @param {number} latitude  The latitude at which to pick features.
     * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
     *                   picking completes.  The resolved value is an array of {@link ImageryLayerFeatureInfo}
     *                   instances.  The array may be empty if no features are found at the given location.
     */
ArcGisMapServerImageryProvider.prototype.pickFeatures = function (
  x,
  y,
  level,
  longitude,
  latitude,
) {
  if (!this.enablePickFeatures) {
    return undefined;
  }

  const rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level);

  let horizontal;
  let vertical;
  let sr;
  if (this._tilingScheme.projection instanceof GeographicProjection) {
    horizontal = CesiumMath.toDegrees(longitude);
    vertical = CesiumMath.toDegrees(latitude);
    sr = "4490";
  } else {
    const projected = this._tilingScheme.projection.project(
      new Cartographic(longitude, latitude, 0.0),
    );
    horizontal = projected.x;
    vertical = projected.y;
    sr = "3857";
  }

  let layers = "visible";
  if (defined(this._layers)) {
    layers += `:${this._layers}`;
  }

  const query = {
    f: "json",
    tolerance: 2,
    geometryType: "esriGeometryPoint",
    geometry: `${horizontal},${vertical}`,
    mapExtent: `${rectangle.west},${rectangle.south},${rectangle.east},${rectangle.north}`,
    imageDisplay: `${this._tileWidth},${this._tileHeight},96`,
    sr: sr,
    layers: layers,
  };

  const resource = this._resource.getDerivedResource({
    url: "identify",
    queryParameters: query,
  });

  return resource.fetchJson().then(function (json) {
    const result = [];

    const features = json.results;
    if (!defined(features)) {
      return result;
    }

    for (let i = 0; i < features.length; ++i) {
      const feature = features[i];

      const featureInfo = new ImageryLayerFeatureInfo();
      featureInfo.data = feature;
      featureInfo.name = feature.value;
      featureInfo.properties = feature.attributes;
      featureInfo.configureDescriptionFromProperties(feature.attributes);

      // If this is a point feature, use the coordinates of the point.
      if (feature.geometryType === "esriGeometryPoint" && feature.geometry) {
        const wkid =
          feature.geometry.spatialReference &&
          feature.geometry.spatialReference.wkid
            ? feature.geometry.spatialReference.wkid
            : 4490;
        if (wkid === 4326 || wkid === 4283 || wkid === 4490) {
          featureInfo.position = Cartographic.fromDegrees(
            feature.geometry.x,
            feature.geometry.y,
            feature.geometry.z,
          );
        } else if (wkid === 102100 || wkid === 900913 || wkid === 3857) {
          const projection = new WebMercatorProjection();
          featureInfo.position = projection.unproject(
            new Cartesian3(
              feature.geometry.x,
              feature.geometry.y,
              feature.geometry.z,
            ),
          );
        }
      }

      result.push(featureInfo);
    }

    return result;
  });
};
ArcGisMapServerImageryProvider._metadataCache = {};
export default ArcGisMapServerImageryProvider;

调用如下:

import ArcGisMapServerImageryProvider from '@/utils/mapUtils/extend/ArcGisMapServerImageryProviderExt.js';

const esri = await ArcGisMapServerImageryProvider.fromUrl(
    '{url}/geoscene/rest/services/dom/GZ_DOM_80CM_2019/MapServer',{
    }
 viewer.imageryLayers.addImageryProvider(res);


网站公告

今日签到

点亮在社区的每一天
去签到