UNPKG

@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
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