Skip to main content

DynamicMapService

Integrates ArcGIS Dynamic Map Services with MapLibre GL JS and Mapbox GL JS, providing server-rendered raster tiles with dynamic layer control, server-side styling, advanced filtering, and identify operations.

Live Demo

Interactive demo showing server-rendered map tiles with dynamic layer controls, server-side styling, filtering, and click-to-identify functionality.

Quick Start

npm install esri-gl maplibre-gl
import { DynamicMapService } from 'esri-gl';

const service = new DynamicMapService('usa-source', map, {
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
layers: [0, 1, 2]
});

map.addLayer({
id: 'usa-layer',
type: 'raster',
source: 'usa-source'
});

Constructor

ArgumentTypeDescription
idstringAn id to assign to the MapLibre GL source
mapMapA MapLibre GL or Mapbox GL map instance
esriServiceOptionsobjectOptions passed when requesting the Esri MapService (see below)
rasterSourceOptionsobjectOptional object passed to the MapLibre GL raster source

Options

OptionTypeDefaultDescription
urlstringRequired URL of the MapService (does not end in a number)
fetchOptionsobjectOptions passed to fetch for authorization headers
layersArray<string>Array of layer IDs to restrict which layers to show (e.g., [1, 2, 3])
dynamicLayersArray<DynamicLayer>Server-side layer styling and filtering configuration
formatstring'png24'Output format of the image
transparentbooleantrueAllow the server to produce transparent images
layerDefsobjectSQL filters for features (e.g., { 3: "STATE_NAME='Kansas'" })
fromDateStart date for time-enabled layers
toDateEnd date for time-enabled layers
tokenstringAuthentication token for secured services
getAttributionFromServicebooleantrueRetrieve copyrightText from service and add as map attribution

Dynamic Layers

The dynamicLayers parameter enables server-side styling and filtering of individual layers. When used, it overrides the default layer drawing for the specified layers.

DynamicLayer Interface

PropertyTypeDescription
idnumberRequired Layer ID to customize
visiblebooleanShow/hide the layer
sourceobjectLayer source configuration (defaults to {type: 'mapLayer', mapLayerId: id})
definitionExpressionstringSQL WHERE clause to filter features
drawingInfoobjectStyling configuration including renderer and transparency
minScalenumberMinimum scale at which layer is visible
maxScalenumberMaximum scale at which layer is visible

Filter Types

Structured filter types for building SQL expressions:

type LayerFilter =
| ComparisonFilter // { field: 'STATE_NAME', op: '=', value: 'California' }
| BetweenFilter // { field: 'POP2000', op: 'BETWEEN', from: 1000000, to: 5000000 }
| InFilter // { field: 'STATE_ABBR', op: 'IN', values: ['CA', 'OR', 'WA'] }
| NullFilter // { field: 'DESCRIPTION', op: 'IS NULL' }
| GroupFilter // { op: 'AND', filters: [filter1, filter2] }
| string; // Raw SQL expression

Methods

Basic Operations

MethodReturnsDescription
identify(lngLat, returnGeometry?)Promise<IdentifyResponse>Identify features at a point
setLayers(layers)voidUpdate which layers are visible
setLayerDefs(layerDefs)voidUpdate layer definition filters
update()voidRefresh tiles with current parameters
remove()voidRemove the service source and layers from the map

Dynamic Layer Methods

MethodReturnsDescription
setDynamicLayers(layers)voidSet complete dynamic layers configuration (pass false to reset)
setLayerRenderer(layerId, renderer)voidApply custom renderer/styling to a layer
setLayerVisibility(layerId, visible)voidShow/hide a specific layer
setLayerDefinition(layerId, expression)voidApply SQL filter to a layer
setLayerFilter(layerId, filter)voidApply structured filter to a layer
setToken(token)voidUpdate the authentication token and refresh tiles

Labeling Methods

MethodReturnsDescription
setLayerLabels(layerId, labelingInfo)voidApply server-side text labels with custom styling
setLayerLabelsVisible(layerId, visible)voidToggle label visibility for a layer

Time-Aware Methods

MethodReturnsDescription
setLayerTimeOptions(layerId, timeOptions)voidConfigure temporal data settings for a layer
animateTime(options)Promise<void>Animate through time extents with frame callbacks

Query & Statistics Methods

MethodReturnsDescription
getLayerStatistics(layerId, statisticFields, options?)Promise<StatisticResult[]>Get statistical analysis (count, sum, avg, etc.)
queryLayerFeatures(layerId, options?)Promise<FeatureSet>Query features with spatial/attribute filters

Export Methods

MethodReturnsDescription
exportMapImage(options)Promise<Blob>Export high-resolution map images

Metadata Methods

MethodReturnsDescription
getMetadata()Promise<ServiceMetadata>Retrieve full service metadata
setAttributionFromService()Promise<void>Set map attribution from service copyrightText
generateLegend(layerIds?)Promise<LegendInfo[]>Retrieve layer symbology information
getLayerInfo(layerId)Promise<LayerMetadata>Get detailed layer metadata and capabilities
getLayerFields(layerId)Promise<FieldInfo[]>Get field definitions and types
getLayerExtent(layerId)Promise<Extent>Get spatial extent of a layer
discoverLayers()Promise<LayerInfo[]>Discover all layers in the service

Batch Methods

MethodReturnsDescription
setBulkLayerProperties(operations)voidApply multiple layer operations atomically
beginUpdate()voidBegin a batch update transaction
commitUpdate()voidCommit all pending updates
rollbackUpdate()voidRollback pending updates
isInTransactionbooleanCheck if currently in a transaction

Examples

Server-side Styling

// Polygon fill
service.setLayerRenderer(2, {
type: 'simple',
symbol: {
type: 'esriSFS',
style: 'esriSFSSolid',
color: [0, 122, 255, 90],
outline: { type: 'esriSLS', style: 'esriSLSSolid', color: [0, 82, 204, 255], width: 1 }
}
});

// Point symbols
service.setLayerRenderer(0, {
type: 'simple',
symbol: {
type: 'esriSMS',
style: 'esriSMSCircle',
color: [255, 0, 0, 255],
size: 8,
outline: { color: [255, 255, 255, 255], width: 2 }
}
});

Structured Filters

service.setLayerFilter(2, { field: 'STATE_NAME', op: '=', value: 'California' });

service.setLayerFilter(2, { field: 'POP2000', op: 'BETWEEN', from: 1000000, to: 5000000 });

service.setLayerFilter(2, { field: 'STATE_ABBR', op: 'IN', values: ['CA', 'OR', 'WA'] });

// Grouped conditions
service.setLayerFilter(2, {
op: 'AND',
filters: [
{ field: 'POP2000', op: '>', value: 1000000 },
{ field: 'SUB_REGION', op: '=', value: 'Pacific' }
]
});

Identify Features

map.on('click', async (e) => {
const results = await service.identify(e.lngLat, true);
results.features.forEach(feature => {
console.log(`Layer ${feature.layerId}:`, feature.attributes);
});
});

Dynamic Layer Configuration

service.setDynamicLayers([
{
id: 0,
visible: true,
definitionExpression: "POP_2000 > 100000",
drawingInfo: {
renderer: {
type: 'simple',
symbol: { type: 'esriSMS', style: 'esriSMSCircle', color: [255, 0, 0, 255], size: 8 }
}
}
},
{
id: 2,
visible: true,
definitionExpression: "SUB_REGION = 'Pacific'",
drawingInfo: {
renderer: {
type: 'simple',
symbol: {
type: 'esriSFS',
color: [0, 122, 255, 90],
outline: { color: [0, 82, 204, 255], width: 2 }
}
}
}
}
]);

// Reset to default server styling
service.setDynamicLayers(false);