UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

259 lines (256 loc) • 14.4 kB
import type Extent from "../geometry/Extent.js"; import type Multipoint from "../geometry/Multipoint.js"; import type Point from "../geometry/Point.js"; import type Polyline from "../geometry/Polyline.js"; import type SpatialReference from "../geometry/SpatialReference.js"; import type Layer from "./Layer.js"; import type ElevationSampler from "./support/ElevationSampler.js"; import type TileInfo from "./support/TileInfo.js"; import type { EsriPromiseMixin } from "../core/Promise.js"; import type { AbortOptions } from "../core/promiseUtils.js"; import type { ScaleRangeLayer, ScaleRangeLayerProperties } from "./mixins/ScaleRangeLayer.js"; import type { ElevationQueryResult, ElevationQueryGeometry, ElevationQueryOptions, CreateElevationSamplerOptions, ElevationTileData } from "./support/types.js"; import type { TileInfoProperties } from "./support/TileInfo.js"; import type { SpatialReferenceProperties } from "../geometry/SpatialReference.js"; import type { LayerProperties } from "./Layer.js"; export interface BaseElevationLayerProperties extends LayerProperties, ScaleRangeLayerProperties { /** * The spatial reference of the layer. * * @default {@link geometry/SpatialReference#WebMercator} */ spatialReference?: SpatialReferenceProperties; /** The tiling scheme information for the layer. */ tileInfo?: TileInfoProperties; } export interface FetchTileOptions extends AbortOptions { /** * The value representing pixels * in the tile that don't contain an elevation value. */ noDataValue?: number; } /** * BaseElevationLayer is intended to be extended for creating custom elevation layers. * You create a custom * [ElevationLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/) by calling * [Accessor.createSubclass()](https://developers.arcgis.com/javascript/latest/references/core/core/Accessor/#createSubclass) on the * `BaseElevationLayer`. * * If the new layer needs to fetch and prepare resources, you can initialize properties * asynchronously prior to loading the layer. This is handled in the [load()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#load) method. * This method is called once, either by you or by the view, when the layer is about to be displayed. * In the body of the method you can call [addResolvingPromise()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#addResolvingPromise) * to add a promise that has to be resolved before the layer is considered [loaded](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#loaded). * * You must overwrite the logic in the [fetchTile()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#fetchTile) * method to return the values of the custom elevation data. * This can be done to exaggerate actual elevation values or for mapping * thematic data as an elevation layer. * When transforming the values of the elevation data it is recommended to * keep the no data value unchanged. * * ```js * const ExaggeratedElevationLayer = BaseElevationLayer.createSubclass({ * load: function() { * // add loadable dependencies here and include * // their returned promises in the * // addResolvingPromise() method * this._elevation = new ElevationLayer({ * url: "//elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" * }); * this.addResolvingPromise(this._elevation.load()); * }, * * fetchTile: function(level, row, col, options) { * // must resolve to an object with the following properties: * // values <number[]>: an array of elevation values for each pixel * // width <number>: the width of the tile in pixels * // height <number>: the height of the tile in pixels * // noDataValue <number>: value of pixels where no elevation data is present * return this._elevation.fetchTile(level, row, col, options).then(function(data) { * let exaggeration = this.exaggeration; * // `data` is an object that contains the width of the tile in pixels, * // the height of the tile in pixels, and the values of each pixel * for (let i = 0; i < data.values.length; i++) { * // each value represents an elevation sample for the * // given pixel position in the tile * // check if the value is a no data value * if (data.values[i] !== data.noDataValue) { * // multiply the elevation value by the exaggeration value * data.values[i] *= exaggeration; * } * } * return data; * }.bind(this)) * } * }); * ``` * * Once the layer is created, you must add it to the layers of the * [Map.ground](https://developers.arcgis.com/javascript/latest/references/core/Map/#ground) property and add the map to a * [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) instance. * * ```js * let map = new Map({ * basemap: "satellite", * ground: { * layers: [ new ExaggeratedElevationLayer() ] * } * }); * sceneView.map = map; * ``` * * @since 4.4 * @see [Creating Custom Elevation Layers (slides) - 2017 Esri Dev Summit](https://proceedings.esri.com/library/userconf/devsummit17/papers/dev_int_97.pdf#page=13) * @see [Creating Custom Layers and LayerViews (video)](https://www.youtube.com/watch?v=QOoZ1lgWESA&t=20m11s) * @see [Sample - Custom ElevationLayer: Exaggerating elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-exaggerated/) * @see [Sample - Custom ElevationLayer: Thematic data as elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-thematic/) * @see [Tiled Elevation Service documentation](https://developers.arcgis.com/documentation/tiled-elevation-service/) */ export default abstract class BaseElevationLayer extends BaseElevationLayerSuperclass { constructor(properties?: BaseElevationLayerProperties); /** * The spatial reference of the layer. * * @default {@link geometry/SpatialReference#WebMercator} */ get spatialReference(): SpatialReference; set spatialReference(value: SpatialReferenceProperties); /** The tiling scheme information for the layer. */ get tileInfo(): TileInfo; set tileInfo(value: TileInfoProperties); /** The layer type provides a convenient way to check the type of the layer without the need to import specific layer modules. */ get type(): "base-elevation"; /** * Adds a promise to the layer's loadable chain. * This is typically used in the [load()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#load) method to ensure that all * loadable resources required for the layer * to function are loaded prior to this layer resolving and becoming [loaded](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#loaded). * * @param promiseToLoad - A promise that must resolve for the layer * to resolve and move from the `loading` [status](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#loadStatus) to being * [loaded](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#loaded). * @example * // the _elevationLayer must load() prior to the ExaggeratedElevationLayer * // resolving and moving to the "loaded" status * const ExaggeratedElevationLayer = BaseElevationLayer.createSubclass({ * load: function() { * this._elevationLayer = new ElevationLayer({ * url: "//elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" * }); * * this.addResolvingPromise(this._elevationLayer.load()); * } * }); */ addResolvingPromise<U, V extends EsriPromiseMixin>(promiseToLoad: PromiseLike<U> | V | PromiseLike<V> | null | undefined): void; /** * Creates an elevation sampler for the given [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/) by querying the service layer for * elevation data and caching it so values may be sampled quickly afterwards. * * The resolution of the cached data can be set using the `demResolution` option. In many cases, `auto` demResolution * can be used to get high quality elevation samples without the need to know exactly where the data in the service * is located. This is particularly useful for services which combine elevation data from many sources (such as the * world elevation service). If more control, or higher quality samples are required, use either `finest-contiguous` * or a fixed `{number}` resolution. * * @param extent - The extent for which to create the sampler. * @param options - Additional query options. * @returns An elevation sampler. * @since 4.12 */ createElevationSampler(extent: Extent, options?: CreateElevationSamplerOptions): Promise<ElevationSampler>; /** * Fetches a tile at the given level, row, and column present in the view. * This method must be overwritten to display custom elevation values in the * [Map.ground](https://developers.arcgis.com/javascript/latest/references/core/Map/#ground). Note that this method must return * a promise that resolves to an object with the properties defined in * [ElevationTileData](https://developers.arcgis.com/javascript/latest/references/core/layers/support/types/#ElevationTileData). * * See the following samples for * examples of how to overwrite this method: * * * [Sample - Custom ElevationLayer: Exaggerating elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-exaggerated/) * * [Sample - Custom ElevationLayer: Thematic data as elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-thematic/) * * @param level - The level of detail of the tile to fetch. * @param row - The row (y) position of the tile to fetch. * @param column - The column (x) position of the tile to fetch. * @param options - Optional settings for the tile request. * @returns Resolves to an instance of [ElevationTileData](https://developers.arcgis.com/javascript/latest/references/core/layers/support/types/#ElevationTileData). */ fetchTile(level: number, row: number, column: number, options?: FetchTileOptions): Promise<ElevationTileData>; /** * Returns the bounds of the tile as an array of four numbers that can * be readily converted to an [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/) object. * See the table in the `returns` section below for more details about the * values returned by this method. * * This function can be used inside [fetchTile()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseElevationLayer/#fetchTile) so you can get the * bounds of the current tile, convert it to an extent object, and request * the desired data for the given extent. See the * [Custom ElevationLayer: Thematic data as elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-thematic/) sample for an example of how this method works. * * @param level - The level of detail (LOD) of the tile. * @param row - The tile's row (y) position in the dataset. * @param column - The tiles column (x) position in the dataset. * @param out - Array for storing the tile bounds or extent. * @returns Returns an array representing the tile bounds or extent. The array * has four items, each representing one bound of the extent. The values of each * item are described in the table below. * * Index | Value * ------|------ * 0 | Minimum x-value * 1 | Minimum y-value * 2 | Maximum x-value * 3 | Maximum y-value * @see [Creating custom layers (slides) - 2017 Esri Dev Summit](https://proceedings.esri.com/library/userconf/devsummit17/papers/dev_int_97.pdf#page=15) * @see [Sample - Custom ElevationLayer: Thematic data as elevation](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-elevation-thematic/) */ getTileBounds(level: number, row: number, column: number, out?: [ number, number, number, number ]): [ number, number, number, number ]; /** * @param geometry * @param options */ queryElevation(geometry: Point, options?: ElevationQueryOptions): Promise<ElevationQueryResult<Point>>; /** * @param geometry * @param options */ queryElevation(geometry: Multipoint, options?: ElevationQueryOptions): Promise<ElevationQueryResult<Multipoint>>; /** * @param geometry * @param options */ queryElevation(geometry: Polyline, options?: ElevationQueryOptions): Promise<ElevationQueryResult<Polyline>>; /** * Queries the service layer for elevation values for the given geometry. * * The returned result contains a copy of the geometry with z-values sampled from elevation data from the service. * The resolution from which the elevation is queried can be set using the `demResolution` option. In many cases, * `auto` demResolution can be used to get high quality elevation samples without the need to know exactly where the * data in the service is located. This is particularly useful for services which combine elevation data from many * sources (such as the world elevation service). If more control, or higher quality samples are required, use either * `finest-contiguous` or a fixed `{number}` resolution. * * @param geometry - The geometry to use for sampling elevation data. * @param options - Additional query options. * @returns Resolves to an object with the sampled geometry, resolution information, and no data value. * @since 4.12 * @see [ElevationLayer.queryElevation()](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/#queryElevation) */ queryElevation(geometry: ElevationQueryGeometry, options?: ElevationQueryOptions): Promise<ElevationQueryResult<ElevationQueryGeometry>>; } declare const BaseElevationLayerSuperclass: typeof Layer & typeof ScaleRangeLayer