当前位置:网站首页>Cesium does not support 4490 problem solution and cesium modified source code packaging scheme
Cesium does not support 4490 problem solution and cesium modified source code packaging scheme
2022-07-07 09:12:00 【FOR. GET】
Reference address
- Cesium Source code packaging reference link
- Cesium Source code modification Support Arcgis service , Coordinate system 4490
- Vue in cesium I won't support it 4490 Solution to the problem
Pit encountered halfway
- install glup Be sure to switch to the administrator running state ,npm If the installation package cannot be installed, you can try it first
Cesium install
git
Method installation , This article is based onVScode
UseGit
Method to achieve
git clone https://github.com/CesiumGS/cesium.git
- It can also be downloaded from the official website
zip
package ,https://cesium.com/platform/cesiumjs/ git
Download needs to be packaged , It needs to be generated after packagingBuild
Folder , It is the development package we use in the project
Cesium Source code modification Support Arcgis service , Coordinate system 4490
First step : modify Source/Scene/ArcGisMapServerImageryProvider.js
// 256 Row or so , As the version changes, the location may be different
// Add and modify 1*************************************
}else if (data.tileInfo.spatialReference.wkid === 4490) {
var geoTilingScheme = new GeographicTilingScheme({
ellipsoid : options.ellipsoid,
tileInfo: data.tileInfo
});
that._tilingScheme = geoTilingScheme;
}
// Add and modify 1*************************************
// 355 Near the line
// Add and modify 2*************************
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
);
}
// Add and modify 2*************************
Complete code
import Cartesian2 from "../Core/Cartesian2.js";
import Cartesian3 from "../Core/Cartesian3.js";
import Cartographic from "../Core/Cartographic.js";
import Credit from "../Core/Credit.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import DeveloperError from "../Core/DeveloperError.js";
import Event from "../Core/Event.js";
import GeographicProjection from "../Core/GeographicProjection.js";
import GeographicTilingScheme from "../Core/GeographicTilingScheme.js";
import CesiumMath from "../Core/Math.js";
import Rectangle from "../Core/Rectangle.js";
import Resource from "../Core/Resource.js";
import RuntimeError from "../Core/RuntimeError.js";
import TileProviderError from "../Core/TileProviderError.js";
import WebMercatorProjection from "../Core/WebMercatorProjection.js";
import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js";
import when from "../ThirdParty/when.js";
import DiscardMissingTileImagePolicy from "./DiscardMissingTileImagePolicy.js";
import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js";
import ImageryProvider from "./ImageryProvider.js";
/** * @typedef {Object} ArcGisMapServerImageryProvider.ConstructorOptions * * Initialization options for the ArcGisMapServerImageryProvider constructor * * @property {Resource|String} url The URL of the ArcGIS MapServer service. * @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. If this value is not specified, a default * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a * {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case, * we request tile 0,0 at the maximum tile level and check pixels (0,0), (200,20), (20,200), * (80,110), and (160, 130). If all of these pixels are transparent, the discard check is * disabled and no tiles are discarded. If any of them have a non-transparent color, any * tile that has the same values in these pixel locations is discarded. The end result of * these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this * parameter. * @property {Boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached * tiles are used if they are available. If false, any pre-cached tiles are ignored and the * 'export' service is used. * @property {String} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. * @property {Boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke * the Identify service on the MapServer and return the features included in the response. If false, * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) * without communicating with the server. Set this property to false if you don't want this provider's features to * be pickable. Can be overridden by setting the {@link ArcGisMapServerImageryProvider#enablePickFeatures} property on the object. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing * a tiled layer. * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles. * This parameter is ignored when accessing a tiled server. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified and used, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server. * @property {Number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server. * @property {Number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. * @property {Number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing * a tiled server. */
/** * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are * used, if available. * * @alias ArcGisMapServerImageryProvider * @constructor * * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options Object describing initialization options * * @see BingMapsImageryProvider * @see GoogleEarthEnterpriseMapsProvider * @see OpenStreetMapImageryProvider * @see SingleTileImageryProvider * @see TileMapServiceImageryProvider * @see WebMapServiceImageryProvider * @see WebMapTileServiceImageryProvider * @see UrlTemplateImageryProvider * * * @example * var esri = new Cesium.ArcGisMapServerImageryProvider({ * url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' * }); * * @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */
function ArcGisMapServerImageryProvider(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
//>>includeStart('debug', pragmas.debug);
if (!defined(options.url)) {
throw new DeveloperError("options.url is required.");
}
//>>includeEnd('debug');
/** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * * @type {Number|undefined} * @default undefined */
this.defaultAlpha = undefined;
/** * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * * @type {Number|undefined} * @default undefined */
this.defaultNightAlpha = undefined;
/** * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * * @type {Number|undefined} * @default undefined */
this.defaultDayAlpha = undefined;
/** * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * * @type {Number|undefined} * @default undefined */
this.defaultBrightness = undefined;
/** * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * * @type {Number|undefined} * @default undefined */
this.defaultContrast = undefined;
/** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * * @type {Number|undefined} * @default undefined */
this.defaultHue = undefined;
/** * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * * @type {Number|undefined} * @default undefined */
this.defaultSaturation = undefined;
/** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * * @type {Number|undefined} * @default undefined */
this.defaultGamma = undefined;
/** * The default texture minification filter to apply to this provider. * * @type {TextureMinificationFilter} * @default undefined */
this.defaultMinificationFilter = undefined;
/** * The default texture magnification filter to apply to this provider. * * @type {TextureMagnificationFilter} * @default undefined */
this.defaultMagnificationFilter = undefined;
var resource = Resource.createIfNeeded(options.url);
resource.appendForwardSlash();
if (defined(options.token)) {
resource.setQueryParameters({
token: options.token,
});
}
this._resource = resource;
this._tileDiscardPolicy = options.tileDiscardPolicy;
this._tileWidth = defaultValue(options.tileWidth, 256);
this._tileHeight = defaultValue(options.tileHeight, 256);
this._maximumLevel = options.maximumLevel;
this._tilingScheme = defaultValue(
options.tilingScheme,
new GeographicTilingScheme({
ellipsoid: options.ellipsoid })
);
this._useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true);
this._rectangle = defaultValue(
options.rectangle,
this._tilingScheme.rectangle
);
this._layers = options.layers;
var credit = options.credit;
if (typeof credit === "string") {
credit = new Credit(credit);
}
this._credit = credit;
/** * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will * invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false, * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) * without communicating with the server. * @type {Boolean} * @default true */
this.enablePickFeatures = defaultValue(options.enablePickFeatures, true);
this._errorEvent = new Event();
this._ready = false;
this._readyPromise = when.defer();
// Grab the details of this MapServer.
var that = this;
var metadataError;
function metadataSuccess(data) {
var tileInfo = data.tileInfo;
if (!defined(tileInfo)) {
that._useTiles = false;
} else {
that._tileWidth = tileInfo.rows;
that._tileHeight = tileInfo.cols;
if (
tileInfo.spatialReference.wkid === 102100 ||
tileInfo.spatialReference.wkid === 102113
) {
that._tilingScheme = new WebMercatorTilingScheme({
ellipsoid: options.ellipsoid,
});
} else if (data.tileInfo.spatialReference.wkid === 4326) {
that._tilingScheme = new GeographicTilingScheme({
ellipsoid: options.ellipsoid,
});
} else if (data.tileInfo.spatialReference.wkid === 4490) {
var geoTilingScheme = new GeographicTilingScheme({
ellipsoid : options.ellipsoid,
tileInfo: data.tileInfo
});
that._tilingScheme = geoTilingScheme;
} else {
var message =
"Tile spatial reference WKID " +
data.tileInfo.spatialReference.wkid +
" is not supported.";
metadataError = TileProviderError.handleError(
metadataError,
that,
that._errorEvent,
message,
undefined,
undefined,
undefined,
requestMetadata
);
return;
}
that._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
) {
var projection = new WebMercatorProjection();
var extent = data.fullExtent;
var sw = projection.unproject(
new Cartesian3(
Math.max(
extent.xmin,
-that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
Math.max(
extent.ymin,
-that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
0.0
)
);
var ne = projection.unproject(
new Cartesian3(
Math.min(
extent.xmax,
that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
Math.min(
extent.ymax,
that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
0.0
)
);
that._rectangle = new Rectangle(
sw.longitude,
sw.latitude,
ne.longitude,
ne.latitude
);
} else if (data.fullExtent.spatialReference.wkid === 4326) {
that._rectangle = Rectangle.fromDegrees(
data.fullExtent.xmin,
data.fullExtent.ymin,
data.fullExtent.xmax,
data.fullExtent.ymax
);
} 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
);
} else {
var extentMessage =
"fullExtent.spatialReference WKID " +
data.fullExtent.spatialReference.wkid +
" is not supported.";
metadataError = TileProviderError.handleError(
metadataError,
that,
that._errorEvent,
extentMessage,
undefined,
undefined,
undefined,
requestMetadata
);
return;
}
}
} else {
that._rectangle = that._tilingScheme.rectangle;
}
// Install the default tile discard policy if none has been supplied.
if (!defined(that._tileDiscardPolicy)) {
that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({
missingImageUrl: buildImageResource(that, 0, 0, that._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,
});
}
that._useTiles = true;
}
if (defined(data.copyrightText) && data.copyrightText.length > 0) {
that._credit = new Credit(data.copyrightText);
}
that._ready = true;
that._readyPromise.resolve(true);
TileProviderError.handleSuccess(metadataError);
}
function metadataFailure(e) {
var message =
"An error occurred while accessing " + that._resource.url + ".";
metadataError = TileProviderError.handleError(
metadataError,
that,
that._errorEvent,
message,
undefined,
undefined,
undefined,
requestMetadata
);
that._readyPromise.reject(new RuntimeError(message));
}
function requestMetadata() {
var resource = that._resource.getDerivedResource({
queryParameters: {
f: "json",
},
});
var metadata = resource.fetchJsonp();
when(metadata, metadataSuccess, metadataFailure);
}
if (this._useTiles) {
requestMetadata();
} else {
this._ready = true;
this._readyPromise.resolve(true);
}
}
function 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 GeographicProjection
) {
query.bboxSR = 4326;
query.imageSR = 4326;
} 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. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */
tileWidth: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"tileWidth must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tileWidth;
},
},
/** * Gets the height of each tile, in pixels. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */
tileHeight: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"tileHeight must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tileHeight;
},
},
/** * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number|undefined} * @readonly */
maximumLevel: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"maximumLevel must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._maximumLevel;
},
},
/** * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */
minimumLevel: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"minimumLevel must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return 0;
},
},
/** * Gets the tiling scheme used by this provider. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {TilingScheme} * @readonly */
tilingScheme: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"tilingScheme must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tilingScheme;
},
},
/** * Gets the rectangle, in radians, of the imagery provided by this instance. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Rectangle} * @readonly */
rectangle: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"rectangle must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
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. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */
tileDiscardPolicy: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"tileDiscardPolicy must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
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 a value indicating whether or not the provider is ready for use. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Boolean} * @readonly */
ready: {
get: function () {
return this._ready;
},
},
/** * Gets a promise that resolves to true when the provider is ready for use. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Promise.<Boolean>} * @readonly */
readyPromise: {
get: function () {
return this._readyPromise.promise;
},
},
/** * Gets the credit to display when this imagery provider is active. Typically this is used to credit * the source of the imagery. This function should not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @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. If the imagery provider is not yet ready ({@link ArcGisMapServerImageryProvider#ready}), this function * will return the value of `options.usePreCachedTilesIfAvailable`, even if the MapServer does * not have pre-cached tiles. * @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;
},
},
});
/** * 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. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */
ArcGisMapServerImageryProvider.prototype.getTileCredits = function (
x, y, level
) {
return undefined;
};
/** * Requests the image for a given tile. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * * @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.<HTMLImageElement|HTMLCanvasElement>|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. The resolved image may be either an * Image or a Canvas DOM object. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */
ArcGisMapServerImageryProvider.prototype.requestImage = function (
x, y, level, request
) {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"requestImage must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
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. This function should not be called before {@link ImageryProvider#ready} returns true. * * @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. * * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. */
ArcGisMapServerImageryProvider.prototype.pickFeatures = function (
x, y, level, longitude, latitude
) {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"pickFeatures must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
if (!this.enablePickFeatures) {
return undefined;
}
var rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level);
var horizontal;
var vertical;
var sr;
if (this._tilingScheme.projection instanceof GeographicProjection) {
horizontal = CesiumMath.toDegrees(longitude);
vertical = CesiumMath.toDegrees(latitude);
sr = "4326";
} else {
var projected = this._tilingScheme.projection.project(
new Cartographic(longitude, latitude, 0.0)
);
horizontal = projected.x;
vertical = projected.y;
sr = "3857";
}
var layers = "visible";
if (defined(this._layers)) {
layers += ":" + this._layers;
}
var 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,
};
var resource = this._resource.getDerivedResource({
url: "identify",
queryParameters: query,
});
return resource.fetchJson().then(function (json) {
var result = [];
var features = json.results;
if (!defined(features)) {
return result;
}
for (var i = 0; i < features.length; ++i) {
var feature = features[i];
var 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) {
var wkid =
feature.geometry.spatialReference &&
feature.geometry.spatialReference.wkid
? feature.geometry.spatialReference.wkid
: 4326;
if (wkid === 4326 || wkid === 4283) {
featureInfo.position = Cartographic.fromDegrees(
feature.geometry.x,
feature.geometry.y,
feature.geometry.z
);
} else if (wkid === 102100 || wkid === 900913 || wkid === 3857) {
var projection = new WebMercatorProjection();
featureInfo.position = projection.unproject(
new Cartesian3(
feature.geometry.x,
feature.geometry.y,
feature.geometry.z
)
);
}
}
result.push(featureInfo);
}
return result;
});
};
export default ArcGisMapServerImageryProvider;
The second step : modify Source/Core/GeographicTilingScheme.js
import Cartesian2 from "./Cartesian2.js";
import Check from "./Check.js";
import defaultValue from "./defaultValue.js";
import defined from "./defined.js";
import Ellipsoid from "./Ellipsoid.js";
import GeographicProjection from "./GeographicProjection.js";
import CesiumMath from "./Math.js";
import Rectangle from "./Rectangle.js";
/** * 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);
}
Object.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; Source code
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; // Source code
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 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;
};
/* 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; }; */
/** * 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;
};
export default GeographicTilingScheme;
The third step : modify Source/Core/Ellipsoid.js
// 234 Near the line
Ellipsoid.CGCS2000 = Object.freeze(new Ellipsoid(6378137.0, 6378137.0, 6356752.31414035585));
Complete code :
import Cartesian3 from "./Cartesian3.js";
import Cartographic from "./Cartographic.js";
import Check from "./Check.js";
import defaultValue from "./defaultValue.js";
import defined from "./defined.js";
import DeveloperError from "./DeveloperError.js";
import CesiumMath from "./Math.js";
import scaleToGeodeticSurface from "./scaleToGeodeticSurface.js";
function initialize(ellipsoid, x, y, z) {
x = defaultValue(x, 0.0);
y = defaultValue(y, 0.0);
z = defaultValue(z, 0.0);
//>>includeStart('debug', pragmas.debug);
Check.typeOf.number.greaterThanOrEquals("x", x, 0.0);
Check.typeOf.number.greaterThanOrEquals("y", y, 0.0);
Check.typeOf.number.greaterThanOrEquals("z", z, 0.0);
//>>includeEnd('debug');
ellipsoid._radii = new Cartesian3(x, y, z);
ellipsoid._radiiSquared = new Cartesian3(x * x, y * y, z * z);
ellipsoid._radiiToTheFourth = new Cartesian3(
x * x * x * x,
y * y * y * y,
z * z * z * z
);
ellipsoid._oneOverRadii = new Cartesian3(
x === 0.0 ? 0.0 : 1.0 / x,
y === 0.0 ? 0.0 : 1.0 / y,
z === 0.0 ? 0.0 : 1.0 / z
);
ellipsoid._oneOverRadiiSquared = new Cartesian3(
x === 0.0 ? 0.0 : 1.0 / (x * x),
y === 0.0 ? 0.0 : 1.0 / (y * y),
z === 0.0 ? 0.0 : 1.0 / (z * z)
);
ellipsoid._minimumRadius = Math.min(x, y, z);
ellipsoid._maximumRadius = Math.max(x, y, z);
ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1;
if (ellipsoid._radiiSquared.z !== 0) {
ellipsoid._squaredXOverSquaredZ =
ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z;
}
}
/** * A quadratic surface defined in Cartesian coordinates by the equation * <code>(x / a)^2 + (y / b)^2 + (z / c)^2 = 1</code>. Primarily used * by Cesium to represent the shape of planetary bodies. * * Rather than constructing this object directly, one of the provided * constants is normally used. * @alias Ellipsoid * @constructor * * @param {Number} [x=0] The radius in the x direction. * @param {Number} [y=0] The radius in the y direction. * @param {Number} [z=0] The radius in the z direction. * * @exception {DeveloperError} All radii components must be greater than or equal to zero. * * @see Ellipsoid.fromCartesian3 * @see Ellipsoid.WGS84 * @see Ellipsoid.UNIT_SPHERE */
function Ellipsoid(x, y, z) {
this._radii = undefined;
this._radiiSquared = undefined;
this._radiiToTheFourth = undefined;
this._oneOverRadii = undefined;
this._oneOverRadiiSquared = undefined;
this._minimumRadius = undefined;
this._maximumRadius = undefined;
this._centerToleranceSquared = undefined;
this._squaredXOverSquaredZ = undefined;
initialize(this, x, y, z);
}
Object.defineProperties(Ellipsoid.prototype, {
/** * Gets the radii of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Cartesian3} * @readonly */
radii: {
get: function () {
return this._radii;
},
},
/** * Gets the squared radii of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Cartesian3} * @readonly */
radiiSquared: {
get: function () {
return this._radiiSquared;
},
},
/** * Gets the radii of the ellipsoid raise to the fourth power. * @memberof Ellipsoid.prototype * @type {Cartesian3} * @readonly */
radiiToTheFourth: {
get: function () {
return this._radiiToTheFourth;
},
},
/** * Gets one over the radii of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Cartesian3} * @readonly */
oneOverRadii: {
get: function () {
return this._oneOverRadii;
},
},
/** * Gets one over the squared radii of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Cartesian3} * @readonly */
oneOverRadiiSquared: {
get: function () {
return this._oneOverRadiiSquared;
},
},
/** * Gets the minimum radius of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Number} * @readonly */
minimumRadius: {
get: function () {
return this._minimumRadius;
},
},
/** * Gets the maximum radius of the ellipsoid. * @memberof Ellipsoid.prototype * @type {Number} * @readonly */
maximumRadius: {
get: function () {
return this._maximumRadius;
},
},
});
/** * Duplicates an Ellipsoid instance. * * @param {Ellipsoid} ellipsoid The ellipsoid to duplicate. * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new * instance should be created. * @returns {Ellipsoid} The cloned Ellipsoid. (Returns undefined if ellipsoid is undefined) */
Ellipsoid.clone = function (ellipsoid, result) {
if (!defined(ellipsoid)) {
return undefined;
}
var radii = ellipsoid._radii;
if (!defined(result)) {
return new Ellipsoid(radii.x, radii.y, radii.z);
}
Cartesian3.clone(radii, result._radii);
Cartesian3.clone(ellipsoid._radiiSquared, result._radiiSquared);
Cartesian3.clone(ellipsoid._radiiToTheFourth, result._radiiToTheFourth);
Cartesian3.clone(ellipsoid._oneOverRadii, result._oneOverRadii);
Cartesian3.clone(ellipsoid._oneOverRadiiSquared, result._oneOverRadiiSquared);
result._minimumRadius = ellipsoid._minimumRadius;
result._maximumRadius = ellipsoid._maximumRadius;
result._centerToleranceSquared = ellipsoid._centerToleranceSquared;
return result;
};
/** * Computes an Ellipsoid from a Cartesian specifying the radii in x, y, and z directions. * * @param {Cartesian3} [cartesian=Cartesian3.ZERO] The ellipsoid's radius in the x, y, and z directions. * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new * instance should be created. * @returns {Ellipsoid} A new Ellipsoid instance. * * @exception {DeveloperError} All radii components must be greater than or equal to zero. * * @see Ellipsoid.WGS84 * @see Ellipsoid.UNIT_SPHERE */
Ellipsoid.fromCartesian3 = function (cartesian, result) {
if (!defined(result)) {
result = new Ellipsoid();
}
if (!defined(cartesian)) {
return result;
}
initialize(result, cartesian.x, cartesian.y, cartesian.z);
return result;
};
/** * An Ellipsoid instance initialized to the WGS84 standard. * * @type {Ellipsoid} * @constant */
Ellipsoid.WGS84 = Object.freeze(
new Ellipsoid(6378137.0, 6378137.0, 6356752.3142451793)
);
Ellipsoid.CGCS2000 = Object.freeze(new Ellipsoid(6378137.0, 6378137.0, 6356752.31414035585));
/** * An Ellipsoid instance initialized to radii of (1.0, 1.0, 1.0). * * @type {Ellipsoid} * @constant */
Ellipsoid.UNIT_SPHERE = Object.freeze(new Ellipsoid(1.0, 1.0, 1.0));
/** * An Ellipsoid instance initialized to a sphere with the lunar radius. * * @type {Ellipsoid} * @constant */
Ellipsoid.MOON = Object.freeze(
new Ellipsoid(
CesiumMath.LUNAR_RADIUS,
CesiumMath.LUNAR_RADIUS,
CesiumMath.LUNAR_RADIUS
)
);
/** * Duplicates an Ellipsoid instance. * * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new * instance should be created. * @returns {Ellipsoid} The cloned Ellipsoid. */
Ellipsoid.prototype.clone = function (result) {
return Ellipsoid.clone(this, result);
};
/** * The number of elements used to pack the object into an array. * @type {Number} */
Ellipsoid.packedLength = Cartesian3.packedLength;
/** * Stores the provided instance into the provided array. * * @param {Ellipsoid} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */
Ellipsoid.pack = function (value, array, startingIndex) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("value", value);
Check.defined("array", array);
//>>includeEnd('debug');
startingIndex = defaultValue(startingIndex, 0);
Cartesian3.pack(value._radii, array, startingIndex);
return array;
};
/** * Retrieves an instance from a packed array. * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Ellipsoid} [result] The object into which to store the result. * @returns {Ellipsoid} The modified result parameter or a new Ellipsoid instance if one was not provided. */
Ellipsoid.unpack = function (array, startingIndex, result) {
//>>includeStart('debug', pragmas.debug);
Check.defined("array", array);
//>>includeEnd('debug');
startingIndex = defaultValue(startingIndex, 0);
var radii = Cartesian3.unpack(array, startingIndex);
return Ellipsoid.fromCartesian3(radii, result);
};
/** * Computes the unit vector directed from the center of this ellipsoid toward the provided Cartesian position. * @function * * @param {Cartesian3} cartesian The Cartesian for which to to determine the geocentric normal. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. */
Ellipsoid.prototype.geocentricSurfaceNormal = Cartesian3.normalize;
/** * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. * * @param {Cartographic} cartographic The cartographic position for which to to determine the geodetic normal. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. */
Ellipsoid.prototype.geodeticSurfaceNormalCartographic = function (
cartographic, result
) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("cartographic", cartographic);
//>>includeEnd('debug');
var longitude = cartographic.longitude;
var latitude = cartographic.latitude;
var cosLatitude = Math.cos(latitude);
var x = cosLatitude * Math.cos(longitude);
var y = cosLatitude * Math.sin(longitude);
var z = Math.sin(latitude);
if (!defined(result)) {
result = new Cartesian3();
}
result.x = x;
result.y = y;
result.z = z;
return Cartesian3.normalize(result, result);
};
/** * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. * * @param {Cartesian3} cartesian The Cartesian position for which to to determine the surface normal. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided, or undefined if a normal cannot be found. */
Ellipsoid.prototype.geodeticSurfaceNormal = function (cartesian, result) {
if (
Cartesian3.equalsEpsilon(cartesian, Cartesian3.ZERO, CesiumMath.EPSILON14)
) {
return undefined;
}
if (!defined(result)) {
result = new Cartesian3();
}
result = Cartesian3.multiplyComponents(
cartesian,
this._oneOverRadiiSquared,
result
);
return Cartesian3.normalize(result, result);
};
var cartographicToCartesianNormal = new Cartesian3();
var cartographicToCartesianK = new Cartesian3();
/** * Converts the provided cartographic to Cartesian representation. * * @param {Cartographic} cartographic The cartographic position. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. * * @example * //Create a Cartographic and determine it's Cartesian representation on a WGS84 ellipsoid. * var position = new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000); * var cartesianPosition = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position); */
Ellipsoid.prototype.cartographicToCartesian = function (cartographic, result) {
//`cartographic is required` is thrown from geodeticSurfaceNormalCartographic.
var n = cartographicToCartesianNormal;
var k = cartographicToCartesianK;
this.geodeticSurfaceNormalCartographic(cartographic, n);
Cartesian3.multiplyComponents(this._radiiSquared, n, k);
var gamma = Math.sqrt(Cartesian3.dot(n, k));
Cartesian3.divideByScalar(k, gamma, k);
Cartesian3.multiplyByScalar(n, cartographic.height, n);
if (!defined(result)) {
result = new Cartesian3();
}
return Cartesian3.add(k, n, result);
};
/** * Converts the provided array of cartographics to an array of Cartesians. * * @param {Cartographic[]} cartographics An array of cartographic positions. * @param {Cartesian3[]} [result] The object onto which to store the result. * @returns {Cartesian3[]} The modified result parameter or a new Array instance if none was provided. * * @example * //Convert an array of Cartographics and determine their Cartesian representation on a WGS84 ellipsoid. * var positions = [new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 0), * new Cesium.Cartographic(Cesium.Math.toRadians(21.321), Cesium.Math.toRadians(78.123), 100), * new Cesium.Cartographic(Cesium.Math.toRadians(21.645), Cesium.Math.toRadians(78.456), 250)]; * var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(positions); */
Ellipsoid.prototype.cartographicArrayToCartesianArray = function (
cartographics, result
) {
//>>includeStart('debug', pragmas.debug);
Check.defined("cartographics", cartographics);
//>>includeEnd('debug')
var length = cartographics.length;
if (!defined(result)) {
result = new Array(length);
} else {
result.length = length;
}
for (var i = 0; i < length; i++) {
result[i] = this.cartographicToCartesian(cartographics[i], result[i]);
}
return result;
};
var cartesianToCartographicN = new Cartesian3();
var cartesianToCartographicP = new Cartesian3();
var cartesianToCartographicH = new Cartesian3();
/** * Converts the provided cartesian to cartographic representation. * The cartesian is undefined at the center of the ellipsoid. * * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation. * @param {Cartographic} [result] The object onto which to store the result. * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid. * * @example * //Create a Cartesian and determine it's Cartographic representation on a WGS84 ellipsoid. * var position = new Cesium.Cartesian3(17832.12, 83234.52, 952313.73); * var cartographicPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); */
Ellipsoid.prototype.cartesianToCartographic = function (cartesian, result) {
//`cartesian is required.` is thrown from scaleToGeodeticSurface
var p = this.scaleToGeodeticSurface(cartesian, cartesianToCartographicP);
if (!defined(p)) {
return undefined;
}
var n = this.geodeticSurfaceNormal(p, cartesianToCartographicN);
var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH);
var longitude = Math.atan2(n.y, n.x);
var latitude = Math.asin(n.z);
var height =
CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h);
if (!defined(result)) {
return new Cartographic(longitude, latitude, height);
}
result.longitude = longitude;
result.latitude = latitude;
result.height = height;
return result;
};
/** * Converts the provided array of cartesians to an array of cartographics. * * @param {Cartesian3[]} cartesians An array of Cartesian positions. * @param {Cartographic[]} [result] The object onto which to store the result. * @returns {Cartographic[]} The modified result parameter or a new Array instance if none was provided. * * @example * //Create an array of Cartesians and determine their Cartographic representation on a WGS84 ellipsoid. * var positions = [new Cesium.Cartesian3(17832.12, 83234.52, 952313.73), * new Cesium.Cartesian3(17832.13, 83234.53, 952313.73), * new Cesium.Cartesian3(17832.14, 83234.54, 952313.73)] * var cartographicPositions = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(positions); */
Ellipsoid.prototype.cartesianArrayToCartographicArray = function (
cartesians, result
) {
//>>includeStart('debug', pragmas.debug);
Check.defined("cartesians", cartesians);
//>>includeEnd('debug');
var length = cartesians.length;
if (!defined(result)) {
result = new Array(length);
} else {
result.length = length;
}
for (var i = 0; i < length; ++i) {
result[i] = this.cartesianToCartographic(cartesians[i], result[i]);
}
return result;
};
/** * Scales the provided Cartesian position along the geodetic surface normal * so that it is on the surface of this ellipsoid. If the position is * at the center of the ellipsoid, this function returns undefined. * * @param {Cartesian3} cartesian The Cartesian position to scale. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. */
Ellipsoid.prototype.scaleToGeodeticSurface = function (cartesian, result) {
return scaleToGeodeticSurface(
cartesian,
this._oneOverRadii,
this._oneOverRadiiSquared,
this._centerToleranceSquared,
result
);
};
/** * Scales the provided Cartesian position along the geocentric surface normal * so that it is on the surface of this ellipsoid. * * @param {Cartesian3} cartesian The Cartesian position to scale. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. */
Ellipsoid.prototype.scaleToGeocentricSurface = function (cartesian, result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("cartesian", cartesian);
//>>includeEnd('debug');
if (!defined(result)) {
result = new Cartesian3();
}
var positionX = cartesian.x;
var positionY = cartesian.y;
var positionZ = cartesian.z;
var oneOverRadiiSquared = this._oneOverRadiiSquared;
var beta =
1.0 /
Math.sqrt(
positionX * positionX * oneOverRadiiSquared.x +
positionY * positionY * oneOverRadiiSquared.y +
positionZ * positionZ * oneOverRadiiSquared.z
);
return Cartesian3.multiplyByScalar(cartesian, beta, result);
};
/** * Transforms a Cartesian X, Y, Z position to the ellipsoid-scaled space by multiplying * its components by the result of {@link Ellipsoid#oneOverRadii}. * * @param {Cartesian3} position The position to transform. * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and * return a new instance. * @returns {Cartesian3} The position expressed in the scaled space. The returned instance is the * one passed as the result parameter if it is not undefined, or a new instance of it is. */
Ellipsoid.prototype.transformPositionToScaledSpace = function (
position, result
) {
if (!defined(result)) {
result = new Cartesian3();
}
return Cartesian3.multiplyComponents(position, this._oneOverRadii, result);
};
/** * Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying * its components by the result of {@link Ellipsoid#radii}. * * @param {Cartesian3} position The position to transform. * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and * return a new instance. * @returns {Cartesian3} The position expressed in the unscaled space. The returned instance is the * one passed as the result parameter if it is not undefined, or a new instance of it is. */
Ellipsoid.prototype.transformPositionFromScaledSpace = function (
position, result
) {
if (!defined(result)) {
result = new Cartesian3();
}
return Cartesian3.multiplyComponents(position, this._radii, result);
};
/** * Compares this Ellipsoid against the provided Ellipsoid componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Ellipsoid} [right] The other Ellipsoid. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */
Ellipsoid.prototype.equals = function (right) {
return (
this === right ||
(defined(right) && Cartesian3.equals(this._radii, right._radii))
);
};
/** * Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'. * * @returns {String} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'. */
Ellipsoid.prototype.toString = function () {
return this._radii.toString();
};
/** * Computes a point which is the intersection of the surface normal with the z-axis. * * @param {Cartesian3} position the position. must be on the surface of the ellipsoid. * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2 * @param {Cartesian3} [result] The cartesian to which to copy the result, or undefined to create and * return a new instance. * @returns {Cartesian3 | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise * * @exception {DeveloperError} position is required. * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0. */
Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function (
position, buffer, result
) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("position", position);
if (
!CesiumMath.equalsEpsilon(
this._radii.x,
this._radii.y,
CesiumMath.EPSILON15
)
) {
throw new DeveloperError(
"Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)"
);
}
Check.typeOf.number.greaterThan("Ellipsoid.radii.z", this._radii.z, 0);
//>>includeEnd('debug');
buffer = defaultValue(buffer, 0.0);
var squaredXOverSquaredZ = this._squaredXOverSquaredZ;
if (!defined(result)) {
result = new Cartesian3();
}
result.x = 0.0;
result.y = 0.0;
result.z = position.z * (1 - squaredXOverSquaredZ);
if (Math.abs(result.z) >= this._radii.z - buffer) {
return undefined;
}
return result;
};
var abscissas = [
0.14887433898163,
0.43339539412925,
0.67940956829902,
0.86506336668898,
0.97390652851717,
0.0,
];
var weights = [
0.29552422471475,
0.26926671930999,
0.21908636251598,
0.14945134915058,
0.066671344308684,
0.0,
];
/** * Compute the 10th order Gauss-Legendre Quadrature of the given definite integral. * * @param {Number} a The lower bound for the integration. * @param {Number} b The upper bound for the integration. * @param {Ellipsoid~RealValuedScalarFunction} func The function to integrate. * @returns {Number} The value of the integral of the given function over the given domain. * * @private */
function gaussLegendreQuadrature(a, b, func) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.number("a", a);
Check.typeOf.number("b", b);
Check.typeOf.func("func", func);
//>>includeEnd('debug');
// The range is half of the normal range since the five weights add to one (ten weights add to two).
// The values of the abscissas are multiplied by two to account for this.
var xMean = 0.5 * (b + a);
var xRange = 0.5 * (b - a);
var sum = 0.0;
for (var i = 0; i < 5; i++) {
var dx = xRange * abscissas[i];
sum += weights[i] * (func(xMean + dx) + func(xMean - dx));
}
// Scale the sum to the range of x.
sum *= xRange;
return sum;
}
/** * A real valued scalar function. * @callback Ellipsoid~RealValuedScalarFunction * * @param {Number} x The value used to evaluate the function. * @returns {Number} The value of the function at x. * * @private */
/** * Computes an approximation of the surface area of a rectangle on the surface of an ellipsoid using * Gauss-Legendre 10th order quadrature. * * @param {Rectangle} rectangle The rectangle used for computing the surface area. * @returns {Number} The approximate area of the rectangle on the surface of this ellipsoid. */
Ellipsoid.prototype.surfaceArea = function (rectangle) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("rectangle", rectangle);
//>>includeEnd('debug');
var minLongitude = rectangle.west;
var maxLongitude = rectangle.east;
var minLatitude = rectangle.south;
var maxLatitude = rectangle.north;
while (maxLongitude < minLongitude) {
maxLongitude += CesiumMath.TWO_PI;
}
var radiiSquared = this._radiiSquared;
var a2 = radiiSquared.x;
var b2 = radiiSquared.y;
var c2 = radiiSquared.z;
var a2b2 = a2 * b2;
return gaussLegendreQuadrature(minLatitude, maxLatitude, function (lat) {
// phi represents the angle measured from the north pole
// sin(phi) = sin(pi / 2 - lat) = cos(lat), cos(phi) is similar
var sinPhi = Math.cos(lat);
var cosPhi = Math.sin(lat);
return (
Math.cos(lat) *
gaussLegendreQuadrature(minLongitude, maxLongitude, function (lon) {
var cosTheta = Math.cos(lon);
var sinTheta = Math.sin(lon);
return Math.sqrt(
a2b2 * cosPhi * cosPhi +
c2 *
(b2 * cosTheta * cosTheta + a2 * sinTheta * sinTheta) *
sinPhi *
sinPhi
);
})
);
});
};
export default Ellipsoid;
The last step : Pack and use
npm run release // [ The most complete package ]
// Pack to Build Under the table of contents , Including the online running version , Debug version and API file
npm run makeZipFile // [ Generate distribution zip package ]***** Use this method
// Package to the root directory Cesium-< Version number >.zip , Delete unnecessary development files
// Pack to Build In the catalog Cesium Catalog
npm run minifyRelease //[ Online operation packaging ]
npm run minify [ Online operation leaves Debug Information packaging ]
// Pack to Build In the catalog CesiumUnminified Catalog
npm run combine //[ Do not compress and leave Debug Information packaging ]
npm run combineRelease // [ No compression and no retention Debug Information packaging ]
// Run the local help documentation , Sample code service
npm start <--port Optional port >
// Run the help document in the LAN , Sample code service
npm startPublic
adopt git download , The result of packaging after changing the source code
边栏推荐
- E-commerce campaign Guide
- NVIC中断优先级管理
- Register address name mapping
- 模拟卷Leetcode【普通】1567. 乘积为正数的最长子数组长度
- Alibaba P8 teaches you how to realize multithreading in automated testing? Hurry up and stop
- Hard core sharing: a common toolkit for hardware engineers
- Led analog and digital dimming
- PMP experience learning and sharing process
- Implement custom memory allocator
- 2022-06-30 Unity核心8——模型导入
猜你喜欢
C language for calculating the product of two matrices
使用Typora编辑markdown上传CSDN时图片大小调整麻烦问题
Platformization, a fulcrum of strong chain complementing chain
Do you have any certificates with high gold content?
H3C VXLAN配置
C language pointer (special article)
外部中断实现按键实验
2022-06-30 unity core 8 - model import
Output a spiral matrix C language
Selenium mouse sliding operation event
随机推荐
When inputting an expression in the input box, an error is reported: incorrect string value:'\xf0\x9f... ' for column 'XXX' at row 1
C语言指针(上篇)
Simulation volume leetcode [general] 1706 Where does the ball meet
External interrupt to realize key experiment
OpenGL 3D graphics rendering
5A summary: seven stages of PMP learning
Systick滴答定时器
H3C VXLAN配置
Output a spiral matrix C language
Platformization, a fulcrum of strong chain complementing chain
【Istio Network CRD VirtualService、Envoyfilter】
Full link voltage test of the e-commerce campaign Guide
Hard core sharing: a common toolkit for hardware engineers
模拟卷Leetcode【普通】1557. 可以到达所有点的最少点数目
Several stages of PMP preparation study
Original collection of hardware bear (updated on June 2022)
Druid monitoring - Introduction to JMX usage and principle
MySQL master-slave delay solution
2022-06-30 Unity核心8——模型导入
【ChaosBlade:根据标签删除POD、Pod 域名访问异常场景、Pod 文件系统 I/O 故障场景】