Skip to Content
This documentation is provided with the HEAT environment and is relevant for this HEAT instance only.
Dashboard ComponentsNextTacticalMap (Next)

TacticalMap (Next)

Renders tracked entities (crew vehicle, targets) as NATO-style symbols on a static, per-range background image rather than tiled map imagery. Built for ranges that have no internet access at runtime, unlike MapDisplay, which loads tiles from a mapURL.

Dashboard generation

Value
Runner nodedashboard-v2
Frontendui/dashboard (TacticalMapDS -> TacticalMap)
Data envelope$heat-dataservice (contract)

Layout component identifier

TacticalMap: the value of configuration.component in v2 layout rows.

Layout configuration

FieldDescription
component"TacticalMap"
nameInternal name
titleContentPanel title
channelsChannel id(s) bound to this widget, mapdisplay shape
defaultRealmRealm for data lookup
showOpenModalButtonExpand to modal

TacticalMap has no mapDisplayItem-equivalent config block: there is no tile URL, zoom, or marker-cone styling to set. The background image and its geographic bounds are a fixed frontend constant (FIXED_RANGE_BOUNDS in ui/dashboard/src/utils/tactical-map/CoordinateProjection.ts), not something a session template configures.

Data contract

Envelope

Publish canonical $heat-dataservice with realms, groups, and channels per the dashboard-v2 upstream contract.

Map channel

PropertyValue
shape"mapdisplay"
dataSame movements[] envelope as MapDisplay

TacticalMap reads the same mapdisplay channel shape as MapDisplay, but interprets each movement point differently and requires more fields:

FieldRequiredDescription
movements[].entityConfigYes{ allegiance, domain, unitType }. A movement with no entityConfig is silently dropped, not shown with a generic icon.
movements[].movement[].latitude/longitudeYesReal WGS84 degrees. Projected against the fixed range image bounds, so a session that took place outside that range will not land correctly on the image.
movements[].movement[].healthNo0-100. A target’s health reaching 0 removes its marker from the map (see TacticalMap.tsx’s visibleTargets filter).
movements[].movement[].headingNoCompass degrees, hull orientation. Drives marker rotation for tracked vehicles.
movements[].movement[].yawNoTurret orientation, independent of heading. Drives the vision-cone rotation; falls back to heading when absent.
movements[].movement[].engagementTypeNo"fire" | "lase". Marks that point as a permanent “Engagement” marker on the map.
movements[].movement[].engagementTargetIdNoWhich target an engagement point targeted, if known.

entityConfig’s allegiance/domain/unitType are the same enums as NatoSymbol. There is no channel-level affiliation source in the underlying capture (protobuf unit_type_data carries no friend/hostile field), so entityConfig has to be assigned upstream, in the arbex/processor script that builds the channel, not inferred by the frontend.

Example channel payload

{ "id": "tactical-map-tracks", "name": "tactical-map-tracks", "groupId": "map", "shape": "mapdisplay", "data": { "movements": [ { "name": "Puma", "entityConfig": { "allegiance": "friend", "domain": "ground", "unitType": "tank" }, "movement": [ { "latitude": "53.4701", "longitude": "8.3850", "heading": "45", "yaw": "60", "health": "100", "capturedDate": "2026-08-17T11:56:40.029Z" } ] }, { "name": "land_zbt_scheibe_58_pzturm_falling (482)", "entityConfig": { "allegiance": "hostile", "domain": "ground", "unitType": "tank" }, "movement": [ { "latitude": "53.4712", "longitude": "8.3862", "heading": "0", "health": "100", "capturedDate": "2026-08-17T11:56:40.029Z" }, { "latitude": "53.4712", "longitude": "8.3862", "heading": "0", "health": "0", "engagementType": "fire", "capturedDate": "2026-08-17T11:58:12.500Z" } ] } ] } }

Behaviour notes

  • Playback-driven, not a live-updating track. TacticalMapDS samples every target’s track at the same fraction of a shared session duration (via useClock and interpolateTrack), throttled to a 100ms cadence. It does not render a raw point-by-point trail; short-lived and long-lived targets are kept in sync against one shared timeline rather than each target’s own span.
  • Vision cone. Rendered for any non-hostile entityConfig.allegiance, oriented by yaw when present, falling back to heading.
  • Tracked-vehicle marker. A friendly target with more than one track point renders as a rotating vehicle sprite (VehicleMarker) instead of a NATO symbol. Everything else (hostile targets, single-point tracks) renders as a NatoSymbol.
  • No external tiles, no internet dependency. The background is a bundled static image (public/assets/tactical-map/rme-range-map.png), matching the platform’s air-gapped runtime requirement.