Layers from the Portal
Half the map never touches this repo. Basemaps, fire perimeters, weather, camera site points —
they all arrive bundled in a WebMap, a portal item authored in ArcGIS Online and loaded by id
(MASTER_MAP_PORTAL_ITEM_ID) at startup. This lesson covers our side of that handshake: what the
app does with the layers it's handed, how the Layers Menu toggles them, and the trick behind
basemap switching.
Arrival: three filters at the door
When the WebMap loads, useFeatureMapAGOLLayers.processLayers walks every layer and applies
three policies:
The menu list. Any layer whose title isn't in LAYERS_TO_IGNORE becomes a row in the Layers
Menu. The ignore list is basemap layers (toggled by the basemap button instead) plus
CLIENT_LAYERS — our own arrows/FOV/LOS, which no operator should be able to switch off.
The eviction. A layer whose loadError looks like an auth failure is removed from the WebMap
entirely — better a missing layer than a map that renders half-broken tiles forever.
The popup silencer. Camera and alert layers get their native ESRI popups disabled, because the app draws its own MUI popups via the click pipeline below.
If you create a new programmatic layer in layerFactories.ts and forget to add its title to
CLIENT_LAYERS, it appears in the Layers Menu as a user-toggleable row. Operators can then
switch off a layer the app assumes is always present.
Toggling: one pipeline for everything
Layer visibility lives in one place — the layersOnMap array in mapCameraInteractiveStore —
and everything that changes what's visible flows through the same four steps:
onLayerVisibilityChange adds the layer to the map on first use — at index 0, the bottom of
the stack, so data layers never cover cameras — then flips its visible flag. A
shouldProcessLayerUpdate guard skips client layers and no-op changes so ESRI never redraws for
nothing. And the result is durable: visibility preferences persist to the server through
layerVisibilityStore, so an operator's layer setup follows them across sessions.
Basemaps are layers wearing a trench coat
Here's the part that makes basemap switching almost anticlimactic: in ArcGIS, basemaps are
layers. data/basemaps.ts defines two options — Topographic and Imagery — each with an
associatedLayerLabels array naming the actual AGOL layers involved. The basemap button just
shows one set and hides the other, through the exact same visibility pipeline you saw above.
No special basemap machinery exists.
Clicks on portal layers
addLayerClickHandler registers one click listener on the MapView. On click it runs hitTest,
filters for graphics belonging to a named AGOL layer (client-side graphics are excluded — they
have their own interactions), and hands the layer name + graphic to the app, which decides which
custom popup to show. This is how clicking an Alert polygon or a camera site circle opens an MUI
panel instead of an ESRI popup.
Wrapping up
The portal ships the layers; the app curates them — menu list, auth eviction, popup takeover —
and routes every visibility change, basemaps included, through one store-driven pipeline. If a
portal layer misbehaves, start at processLayers; if a toggle misbehaves, start at
layersOnMap.
Next: ArcGIS Authentication — how the map earns the token that makes AGOL answer at all.