当前位置:网站首页>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
边栏推荐
- 模拟卷Leetcode【普通】1609. 奇偶树
- 【ChaosBlade:节点 CPU 负载、节点网络延迟、节点网络丢包、节点域名访问异常】
- 串口实验——简单数据收发
- Postman interface test (I. installation and use)
- Alibaba P8 teaches you how to realize multithreading in automated testing? Hurry up and stop
- Ppt template and material download website (pure dry goods, recommended Collection)
- Pytest+request+allure+excel interface automatic construction from 0 to 1 [five nails / flying Book notice]
- Reading notes of pyramid principle
- 面板显示技术:LCD与OLED
- Output a spiral matrix C language
猜你喜欢
Druid monitoring - Introduction to JMX usage and principle
C语言指针(习题篇)
使用Typora编辑markdown上传CSDN时图片大小调整麻烦问题
Output all composite numbers between 6 and 1000
端口复用和重映像
【Istio Network CRD VirtualService、Envoyfilter】
Output a spiral matrix C language
Common short chain design methods
Esp32-ulp coprocessor low power mode RTC GPIO interrupt wake up
H3C vxlan configuration
随机推荐
Calf problem
面板显示技术:LCD与OLED
Alibaba P8 teaches you how to realize multithreading in automated testing? Hurry up and stop
Esp32-ulp coprocessor low power mode RTC GPIO interrupt wake up
Register address name mapping
寄存器地址名映射
2021 year end summary
On December 8th, 2020, the memory of marketing MRC application suddenly increased, resulting in system oom
Postman interface debugging method
外部中断实现按键实验
徽商期货公司评级是多少?开户安全吗?我想开户,可以吗?
Postman interface test (I. installation and use)
模拟卷Leetcode【普通】1557. 可以到达所有点的最少点数目
Systick滴答定时器
Isomorphic C language
Simulation volume leetcode [general] 1706 Where does the ball meet
STM32串口寄存器库函数配置方法
MySQL common statements
C语言指针(上篇)
2022-07-06 Unity核心9——3D动画