Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/react-for-arcgis.api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ declare class ArcGISRasterLayerOverlayRenderer implements RasterLayerOverlayRend
constructor(holder: ArcGISViewHolder);
createRasterLayer(entity: RasterLayerEntity<Layer>): Promise<Layer | null>;
removeRasterLayer(layer: Layer): Promise<void>;
private readonly stackKeys;
private stackSequence;
/**
* Where a raster goes among the map's operational layers: the lowest overlay band, under the
* ground-image media layer and the graphics layers (js-sdk-core OVERLAY_STACK_ORDER), ordered
* by zIndex among the rasters. It used to be appended, on top of every overlay and marker.
* Marker tiles are mounted as a raster but belong with the markers.
*/
private stackIndex;
private stackKeyOf;
onAdd(data: RasterLayerAddParams[]): Promise<(Layer | null)[]>;
onChange(data: RasterLayerChangeParams<Layer>[]): Promise<(Layer | null)[]>;
onRemove(data: RasterLayerEntity<Layer>[]): Promise<void>;
Expand Down
42 changes: 41 additions & 1 deletion src/raster/ArcGISRasterLayerOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
type RasterLayerChangeParams,
type RasterLayerOverlayRenderer,
type RasterLayerSource,
type RasterLayerState,
overlayStackBeforeId,
type OverlayStackKey,
} from '@mapconductor/js-sdk-core';
import { ArcGISViewHolder } from '../ArcGISViewHolder';
import WebTileLayer from '@arcgis/core/layers/WebTileLayer';
Expand Down Expand Up @@ -38,7 +41,8 @@ export class ArcGISRasterLayerOverlayRenderer implements RasterLayerOverlayRende
try {
const layer = this.buildLayer(entity.state.source);
if (!layer) return null;
this.holder.map.map?.add(layer);
const map = this.holder.map.map;
if (map) map.add(layer, this.stackIndex(layer, entity.state));
return layer;
} catch (e) {
console.error('Failed to create raster layer:', e);
Expand All @@ -48,6 +52,42 @@ export class ArcGISRasterLayerOverlayRenderer implements RasterLayerOverlayRende

async removeRasterLayer(layer: Layer): Promise<void> {
this.holder.map.map?.remove(layer);
this.stackKeys.delete(layer);
}

// Stacking keys of the raster layers this renderer added.
private readonly stackKeys = new Map<Layer, OverlayStackKey>();
private stackSequence = 0;

/**
* Where a raster goes among the map's operational layers: the lowest overlay band, under the
* ground-image media layer and the graphics layers (js-sdk-core OVERLAY_STACK_ORDER), ordered
* by zIndex among the rasters. It used to be appended, on top of every overlay and marker.
* Marker tiles are mounted as a raster but belong with the markers.
*/
private stackIndex(layer: Layer, state: RasterLayerState): number {
const markerTiles = state.id === 'mc-marker-tiles';
const key: OverlayStackKey = markerTiles
? { kind: 'marker', sub: 0 }
: { kind: 'rasterLayer', zIndex: state.zIndex, sequence: ++this.stackSequence };
this.stackKeys.set(layer, key);
const layers = this.holder.map.map?.layers.toArray() ?? [];
const ids = layers.map((_, i) => String(i));
const beforeId = overlayStackBeforeId(ids, (id) => this.stackKeyOf(layers[Number(id)]), key);
return beforeId == null ? layers.length : Number(beforeId);
}

private stackKeyOf(layer: Layer): OverlayStackKey | null {
const own = this.stackKeys.get(layer);
if (own) return own;
switch (layer.id) {
case 'ground-image-layer': return { kind: 'groundImage' };
case 'polygon-layer': return { kind: 'polygon' };
case 'circle-layer': return { kind: 'circle' };
case 'polyline-layer': return { kind: 'polyline' };
case 'marker-layer': return { kind: 'marker', sub: 1 };
default: return null;
}
}

async onAdd(data: RasterLayerAddParams[]): Promise<(Layer | null)[]> {
Expand Down