Skip to content

Latest commit

 

History

History
142 lines (99 loc) · 7.84 KB

File metadata and controls

142 lines (99 loc) · 7.84 KB

Channels layer

Channel markers and popups — how Channel records from the active codeplug become points on the map.

See the map hub for overall data flow. This layer reads the internal model (Channel); CSV parsing belongs to the import/export surface, not here.

Purpose

Documents filtering, grouping, and rendering of channels from the central codeplug store. Zone hulls reuse the same plotted channel set via id lookup; see zones.md for zone-specific behaviour. Entity shapes are in the data model.

Code anchors

Symbol / region File Role
applyFilters src/lib/channels.ts Plot vs skip a Channel[] by coordinates, useLocation, hideFromMap
groupByCoords same Optional merge of channels at identical lat/lon
buildChannelById same Plotted channels indexed by internal id
markerColor / markerLabel / dominantMode same Per-marker colour, label, and merged-group mode
useCodeplug src/state/codeplugStore.tsx Central codeplug state (active project)
Marker rendering src/components/CodeplugMap/CodeplugMap.tsx react-leaflet divIcon markers + popups (sidecar)

The map is given Channel[] as a prop; it never reads CSV. A codeplug enters the store via the import layer (home page or Import & export panel) — see import/export.

Inputs — the Channel model

The map consumes these Channel fields:

Field Used for
name Popup title source, full-name label, zone member resolution
callsign Default marker label
name Human qualifier — used when Full channel name is on (callsign — name)
location ({ lat, lon } | null) Marker position; null → skipped
useLocation Filter — false excludes the channel when the Use-Location filter is on
hideFromMap Internal flag — always excludes the channel from markers and hulls
mode Marker colour and popup mode label; see channel-modes
multiMode, modeProfiles One marker per logical channel; label shows combined modes (e.g. GB7GL FM+DMR) — see multi-mode
rxFrequency, txFrequency Popup RX/TX MHz line
contactName, rxGroupListName Popup DMR rows (hidden when empty or None)

callsign and name are first-class model fields (#54); import splits CPS wire names via channel-name-parsing. Map labels use channelDisplayLabel — not the composed export wire string.

Channel record (in memory)

See data model — Channel. Example of the fields this layer reads:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "GB3CS Motherwell",
  "callsign": "GB3CS",
  "mode": "fm",
  "rxFrequency": "430.92500",
  "txFrequency": "438.52500",
  "contactName": "None",
  "rxGroupListName": "None",
  "location": { "lat": 55.78, "lon": -4.10 },
  "useLocation": true,
  "hideFromMap": false
}

Controls and filters

CodeplugMap exposes two display toggles via MapControls; the coordinate filters are fixed, not user-facing.

Control / filter Source Default Effect
Full channel name MapControls toggle off Label uses callsign — name qualifier parts; default is callsign only
Draw zones MapControls toggle on Show/hide zone hulls — see zones.md
Require useLocation fixed (DEFAULT_FILTER_OPTS) on Skips channels with useLocation === false
Skip 0,0 fixed (DEFAULT_FILTER_OPTS) on Skips channels at exactly 0, 0
Hide from map Channel.hideFromMap Always skips flagged channels

Markers and zone hulls recompute reactively via useMemo when the channel list or toggles change (no imperative refresh).

Behaviour

Plot vs skip

applyFilters marks a channel skipped when:

  1. location is null, or
  2. Skip 0,0 is on and both coordinates are exactly 0, or
  3. Require useLocation is on and useLocation is false, or
  4. hideFromMap is true.

Each skip carries a reason (missing coordinates, 0,0 coordinates, Use Location = No, hidden from map) for sidebar/report feedback. All other channels are plotted.

Marker appearance

Per-mode marker colours are defined in channel-modes (src/lib/channelModes.ts). Examples: fm #f0c419, dmr #e03131, dstar #7950f2.

Merged groups (channels at the same lat/lon to 5 decimal places) use the dominant mode: the most frequent specific mode in the co-located group (tie → first channel).

Multi-mode channels (multiMode: true) always plot as one marker per logical channel (not per export-expanded row). The label appends combined mode names (e.g. GB7GL FM+DMR). Marker colour uses the channel's primary mode field.

Markers use a divIcon with a dot and permanent label below. Merged sites use a slightly larger dot and a +N suffix on the label. highlightChannelId emphasises one marker on detail pages.

Popups

Click a marker for:

  • Title: callsign, or callsign (+N) when merged
  • Per channel: full name, mode label, RX/TX MHz, and for DMR rows contactName / rxGroupListName when not empty or None

Map bounds

FitMapBounds (via useMap) fits the view to marker, zone-hull, and operator points whenever they change. Points are gathered by collectMapPoints and the view computed by computeMapView (src/lib/mapView.ts) with padding [48, 48] and maxZoom: 11; degenerate single-point bounds use setView at zoom 11 to avoid an infinite tile load.

Initial map centre: [56.5, -4.0], zoom 6 (before any channels plot).

Browser storage

Key Purpose
mm9pdy-codeplug-tool.channel-map.mapboxToken Mapbox access token (optional)
mm9pdy-codeplug-tool.channel-map.tileProvider osm / mapbox / mapbox-sat

The codeplug itself persists via the projects store in LocalStorage (#9) — see persistence/. The map reads the active project's codeplug. Tile preferences use the separate keys above.

Manual verify

  1. Create or open a project with geolocated channels (import a codeplug on the home page — OpenGD77 CSV is the importer shipped today — or use an existing project).
  2. Run npm run dev and open http://localhost:5173/codeplug-tool/#/channels (or the live site).
  3. Confirm markers appear for known repeaters; open popups for frequency/contact fields.
  4. Edit a channel's location or toggle Hide from map — the marker should appear/disappear on save.
  5. Toggle Full channel name — labels switch between callsign-only and callsign — name.
  6. Co-located FM/DMR pairs should collapse to one merged marker with a combined popup.

Known gaps

  • Coordinate filters (useLocation, skip 0,0) are fixed on embedded maps — not user-adjustable per page.
  • Zone member resolution is exact-match on channel name (case-sensitive) — no fuzzy or callsign-only fallback.
  • No legend mapping mode → colour beyond the reference table.

Related