Map: pins and paths look exact when they aren't — confidence styling, type-gated paths, impossible-speed stops #236

Closed
opened 2026-10-05 02:08:35 -04:00 by logan · 0 comments
Owner

Problem

  • Precision is invisible: intelligence.py:779 accepts ROOFTOP, RANGE_INTERPOLATED and GEOMETRIC_CENTER, but location_type is not persisted on the call or incident, so a route centroid draws the same teardrop as a rooftop.
  • IncidentPathLayer (MapView.tsx:1019-1045) draws a numbered polyline for ANY incident with >= 2 geocoded calls, regardless of type: a structure fire with mutual-aid 'responding from Station 3' becomes a pursuit-looking path.
  • No outlier rejection: one bad geocode zig-zags a path across the county; #189's sink drew a 37 km path. The backend already has _MAX_PURSUIT_SPEED_KM_PER_MIN = 8.0 (incident_correlator.py:92).
  • Legacy pins are 5-in-6 wrong with no backfill (#28, DEFERRED.md _verified_pin row).

Who asked

NOC, RCC, GSOC, OEM, FD, HOBBY (6 of 8). 'If the map is honest about a 300 m error, I can trust it at 30 m.'

Proposal

  • Persist location_type (and place_verifier outcome where present) on the call and incident at geocode time.
  • Render: ROOFTOP solid pin; RANGE_INTERPOLATED small ring; GEOMETRIC_CENTER dashed uncertainty ring with the spoken location string as label; incidents without location_coords_source (pre-#23) hollow/ghosted.
  • Paths: draw numbered paths only for movement incidents (police/accident with pursuit tags); fire/EMS/hazmat render a pin with call locations as small unnumbered dots.
  • Dash segments across long time gaps or talkgroup changes; ghost a stop implying > 8 km/min; badge 'may be merged' when path length exceeds a threshold.

Data source and terms

Internal (Google geocode location_type already returned; no new API).

Effort

M (S backend field + S/M frontend)

Acceptance criteria

  • A GEOMETRIC_CENTER-geocoded incident visibly differs from a ROOFTOP one.
  • A fire with 3 geocoded calls shows no numbered path.
  • Replaying #189's call set draws ghosted/dashed segments rather than a solid 37 km pursuit.
  • Display-only: no correlation decision changes (no drb-correlation-review needed unless the persisted field feeds a decision).

Notes

Ceiling is set by geocode/extraction quality (#28, #160, #163). This issue makes the error visible; it does not fix it.


Reviewed against Server origin/main c4e1f9a (2026-10-05), from code only. Source: map persona panel 2026-10-05 (tracking issue lists all items).
Persona key: TOC = county PD real-time crime center supervisor; NOC = Con Ed electric ops NOC; RCC = MTA rail/bus control desk; GSOC = corporate security operations analyst; OEM = county emergency management duty officer; NEWS = TV newsroom assignment editor; FD = volunteer fire chief / county fire dispatcher; HOBBY = scanner power user / local journalist.

## Problem - Precision is invisible: `intelligence.py:779` accepts ROOFTOP, RANGE_INTERPOLATED and GEOMETRIC_CENTER, but `location_type` is not persisted on the call or incident, so a route centroid draws the same teardrop as a rooftop. - `IncidentPathLayer` (`MapView.tsx:1019-1045`) draws a numbered polyline for ANY incident with >= 2 geocoded calls, regardless of type: a structure fire with mutual-aid 'responding from Station 3' becomes a pursuit-looking path. - No outlier rejection: one bad geocode zig-zags a path across the county; #189's sink drew a 37 km path. The backend already has `_MAX_PURSUIT_SPEED_KM_PER_MIN = 8.0` (`incident_correlator.py:92`). - Legacy pins are 5-in-6 wrong with no backfill (#28, DEFERRED.md `_verified_pin` row). ## Who asked NOC, RCC, GSOC, OEM, FD, HOBBY (6 of 8). 'If the map is honest about a 300 m error, I can trust it at 30 m.' ## Proposal - Persist `location_type` (and place_verifier outcome where present) on the call and incident at geocode time. - Render: ROOFTOP solid pin; RANGE_INTERPOLATED small ring; GEOMETRIC_CENTER dashed uncertainty ring with the spoken location string as label; incidents without `location_coords_source` (pre-#23) hollow/ghosted. - Paths: draw numbered paths only for movement incidents (police/accident with pursuit tags); fire/EMS/hazmat render a pin with call locations as small unnumbered dots. - Dash segments across long time gaps or talkgroup changes; ghost a stop implying > 8 km/min; badge 'may be merged' when path length exceeds a threshold. ## Data source and terms Internal (Google geocode `location_type` already returned; no new API). ## Effort M (S backend field + S/M frontend) ## Acceptance criteria - A GEOMETRIC_CENTER-geocoded incident visibly differs from a ROOFTOP one. - A fire with 3 geocoded calls shows no numbered path. - Replaying #189's call set draws ghosted/dashed segments rather than a solid 37 km pursuit. - Display-only: no correlation decision changes (no drb-correlation-review needed unless the persisted field feeds a decision). ## Notes Ceiling is set by geocode/extraction quality (#28, #160, #163). This issue makes the error visible; it does not fix it. --- Reviewed against Server origin/main c4e1f9a (2026-10-05), from code only. Source: map persona panel 2026-10-05 (tracking issue lists all items). Persona key: TOC = county PD real-time crime center supervisor; NOC = Con Ed electric ops NOC; RCC = MTA rail/bus control desk; GSOC = corporate security operations analyst; OEM = county emergency management duty officer; NEWS = TV newsroom assignment editor; FD = volunteer fire chief / county fire dispatcher; HOBBY = scanner power user / local journalist.
logan added the
type
feature
area/ai-pipelinearea/maparea/frontend
priority
p1
labels 2026-10-05 02:08:35 -04:00
logan closed this issue 2026-10-05 03:33:21 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#236