All files / map features.ts

100% Statements 11/11
100% Branches 0/0
100% Functions 4/4
100% Lines 11/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61        5x     5x         5x   5x 4368x   5x 408x           5x               4368x                       5x         386x                      
import type { GridLabel, Position, RGBA } from '../core/geo/geometry'
import type { MapTone } from '../core/systems/types'
 
/** The order lines draw in, bottom first: grids, then range rings, then the cue's cells. */
export const LineRank = { Grid: 0, Rings: 100, CueCells: 200 } as const
 
/** A halo in the base map's own background colour keeps labels readable over lines and features. */
export const labelHalo: Record<MapTone, string> = {
  onDark: 'rgba(17, 17, 19, 0.9)',
  onLight: 'rgba(255, 255, 255, 0.92)',
}
 
const MAX_CHANNEL = 255
 
export const cssColor = ([red, green, blue, alpha]: RGBA): string =>
  `rgba(${red}, ${green}, ${blue}, ${alpha / MAX_CHANNEL})`
 
export const opaqueCssColor = ([red, green, blue]: RGBA): string =>
  `rgb(${red}, ${green}, ${blue})`
 
/**
 * One overlay line. `layer` names what drew it (a grid id, "range-rings" or "cue-cells"), and
 * `rank` orders it within the single MapLibre line layer.
 */
export const lineFeature = (
  path: ReadonlyArray<Position>,
  properties: Readonly<{
    layer: string
    color: RGBA
    width: number
    rank: number
  }>,
): GeoJSON.Feature<GeoJSON.LineString> => ({
  type: 'Feature',
  geometry: { type: 'LineString', coordinates: [...path] },
  properties: {
    layer: properties.layer,
    color: cssColor(properties.color),
    width: properties.width,
    rank: properties.rank,
  },
})
 
/** A label point. A lower rank wins when labels collide. */
export const labelFeature = (
  label: GridLabel,
  rank: number,
  color: RGBA,
  tone: MapTone,
): GeoJSON.Feature<GeoJSON.Point> => ({
  type: 'Feature',
  geometry: { type: 'Point', coordinates: label.position },
  properties: {
    text: label.text,
    size: label.size,
    rank,
    color: opaqueCssColor(color),
    halo: labelHalo[tone],
  },
})