@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
185 lines (183 loc) • 10.8 kB
TypeScript
import type Extent from "../geometry/Extent.js";
import type Layer from "./Layer.js";
import type { EsriPromiseMixin } from "../core/Promise.js";
import type { AbortOptions } from "../core/promiseUtils.js";
import type { BlendLayer, BlendLayerProperties } from "./mixins/BlendLayer.js";
import type { RefreshableLayer, RefreshableLayerProperties } from "./mixins/RefreshableLayer.js";
import type { ScaleRangeLayer, ScaleRangeLayerProperties } from "./mixins/ScaleRangeLayer.js";
import type { LayerProperties } from "./Layer.js";
export interface BaseDynamicLayerProperties extends LayerProperties, RefreshableLayerProperties, ScaleRangeLayerProperties, BlendLayerProperties {}
/**
* This class may be extended to create dynamic map layers. Dynamic layers display
* an image dynamically generated on the server based on a request, including the
* extent and size of the image. The exported image covers the entire view extent.
* Each interaction on the view (e.g. panning, zooming) will result in an export of
* a new image on the server.
* Each export is unique so it cannot be cached in the browser.
*
* You can create a custom [DynamicLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/) by calling its
* [Accessor.createSubclass()](https://developers.arcgis.com/javascript/latest/references/core/core/Accessor/#createSubclass)
* method. You may create a custom dynamic layer for one of the following reasons:
*
* * The source of the images isn't explicitly supported by the ArcGIS Maps SDK for JavaScript
* * Images need to be preprocessed prior to display in the view
*
* ### Request images as they are defined
*
* To request images as they are predefined from a data source, overwrite the [getImageUrl()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#getImageUrl)
* method so it returns the URL for the requested tile for a given level, row and column.
*
* ```js
* let MyCustomDynamicLayer = BaseDynamicLayer.createSubclass({
* // properties of the custom dynamic layer
* properties: {
* getMapUrl: null,
* getMapParameters: null
* },
*
* // override getImageUrl() to generate URL to the image
* getImageUrl: function (extent, width, height) {
* // generate the URL for the map image
* let urlVariables = this._prepareQuery(this.getMapParameters, extent, width, height);
* let queryString = this._joinUrlVariables(urlVariables);
*
* // return the URL to the generated image
* return this.getMapUrl + "?" + queryString;
* },
* ...
* });
* ```
* See the [Custom DynamicLayer sample](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-dynamiclayer/)
* for an example of this workflow.
*
* ### Preprocess images prior to display
*
* If data needs to be preprocessed prior to display, then override the [fetchImage()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#fetchImage)
* method to generate
* an [html image element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) or
* [canvas element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement) by
* processing the data returned by the server. For example, if you need to apply a
* [compositing operation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
* to the image returned from the server before the image is displayed then you would
* override this method.
*
* ```js
* // Fetches images for given extent and size
* fetchImage: function (extent, width, height){
* let url = this.getImageUrl(extent, width, height);
*
* // request for the image based on the generated url
* return esriRequest(url, {
* responseType: "image"
* })
* .then(function(response) {
* let image = response.data;
*
* // create a canvas with teal fill
* let canvas = document.createElement("canvas");
* let context = canvas.getContext("2d");
* canvas.width = width;
* canvas.height = height;
*
* // Apply destination-atop operation to the image returned from the server
* context.fillStyle = "rgb(0,200,200)";
* context.fillRect(0, 0, width, height);
* context.globalCompositeOperation = "destination-atop";
* context.drawImage(image, 0, 0, width, height);
*
* return canvas;
* }.bind(this));
* }
* ```
* The layer is responsible for generating the image URL and fetching the image from the server for
* the extent and size provided by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/). The
* LayerView displays the fetched tiles.
*
* If the custom dynamic layer requires loadable resources, then you must load all loadable
* dependencies on the layer, within the [load()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#load) method. Add the promise returned
* from the loadable resource with the [addResolvingPromise()](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#addResolvingPromise) method.
* The layer will then wait for all of dependencies to
* finish loading before it is considered [loaded](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#loaded).
*
* @since 4.4
* @see [Creating Custom Layers and LayerViews (slides) - 2017 Esri Dev Summit](https://proceedings.esri.com/library/userconf/devsummit17/papers/dev_int_97.pdf)
* @see [Creating Custom Layers and LayerViews (video)](https://youtu.be/QOoZ1lgWESA)
* @see [Sample - Custom DynamicLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-dynamiclayer/)
*/
export default abstract class BaseDynamicLayer extends BaseDynamicLayerSuperclass {
constructor(properties?: BaseDynamicLayerProperties);
/** 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-dynamic";
/**
* 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/BaseDynamicLayer/#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/BaseDynamicLayer/#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/BaseDynamicLayer/#loadStatus) to being
* [loaded](https://developers.arcgis.com/javascript/latest/references/core/layers/BaseDynamicLayer/#loaded).
* @example
* // the externalLayer must load() prior to the MyDynamicLayer
* // resolving and moving to the "loaded" status
* let MyDynamicLayer = BaseElevationLayer.createSubclass({
* load: function() {
* let promise = this.requiredLayer.load();
* this.addResolvingPromise(promise);
* }
* });
*/
addResolvingPromise<U, V extends EsriPromiseMixin>(promiseToLoad: PromiseLike<U> | V | PromiseLike<V> | null | undefined): void;
/**
* This method fetches the image for the specified extent and size. Override this method if the data returned
* from the server needs to be processed before it can be displayed. For example, if the server returns binary
* data, override this method to convert the binary data to an image.
*
* @param extent - The extent of the view. This value is provided by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @param width - The width of the view in pixels. This value is provided by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @param height - The height of the view in pixels. This value is provided by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @param options - The parameter options is an object with the following properties.
* @returns Returns a promise that resolves to an
* [HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) or
* [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement).
* @example
* // Fetches images for given extent and size
* fetchImage: function (extent, width, height){
* let url = this.getImageUrl(extent, width, height);
*
* // request for the image based on the generated url
* return esriRequest(url, {
* responseType: "image"
* })
* .then(function(response) {
* let image = response.data;
*
* let canvas = document.createElement("canvas");
* let context = canvas.getContext("2d");
* canvas.width = width;
* canvas.height = height;
*
* // Apply destination-atop operation to the image returned from the server
* context.fillStyle = "rgb(0,200,200)";
* context.fillRect(0, 0, width, height);
* context.globalCompositeOperation = "destination-atop";
* context.drawImage(image, 0, 0, width, height);
*
* return canvas;
* }.bind(this));
* }
*/
fetchImage(extent: Extent, width: number, height: number, options?: AbortOptions): Promise<HTMLImageElement | HTMLCanvasElement>;
/**
* This method returns a URL to an image for a given extent, width, and height.
* Override this method to construct the URL for the image based on user interaction.
*
* @param extent - Extent of the view. This value is populated by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @param width - Width of the view in pixels. This value is populated by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @param height - Height of the view in pixels. This value is populated by the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/).
* @returns Returns a string or a promise that resolves to a string. The string is the URL to the image.
* @see [Sample - Custom DynamicLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-dynamiclayer/)
*/
getImageUrl(extent: Extent, width: number, height: number): string | Promise<string>;
}
declare const BaseDynamicLayerSuperclass: typeof Layer & typeof RefreshableLayer & typeof ScaleRangeLayer & typeof BlendLayer