All files / core/systems/tile system.ts

92.3% Statements 12/13
100% Branches 4/4
83.33% Functions 5/6
92.3% Lines 12/13

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 62 63 64 65 66 67 68 69 70 71                                14x         2058x 2058x             14x   14x 1002x 1002x                     14x 6016x     6016x     1002x               14x                      
import { Option, pipe } from 'effect'
 
import { cellBox } from '../cell'
import { makeParser } from '../parser'
import type { Formatter, Grid, Parser } from '../types'
import { tileGrid, tileOutline } from './grid'
import {
  type Tile,
  fromQuadkey,
  fromTilePath,
  tileCell,
  tilePath,
  toQuadkey,
  toTile,
} from './tile'
 
export const formatter: Formatter = {
  id: 'Tile',
  label: 'Map tile',
  maybeGridId: Option.some('Tile'),
  format: (point, { tileZoom }) => {
    const tile = toTile(point, tileZoom)
    return {
      lines: [tilePath(tile), `quadkey ${toQuadkey(tile)}`],
      copyText: tilePath(tile),
    }
  },
}
 
const QUADKEY_PREFIX_RE = /^(?:qk|quadkey):/i
 
const toParseResult = (tile: Tile) => {
  const cell = tileCell(tile)
  return {
    kind: 'Map tile',
    point: {
      lat: (cell.south + cell.north) / 2,
      lon: (cell.west + cell.east) / 2,
    },
    maybeBounds: Option.some(cellBox(cell)),
  }
}
 
/** Reads `z/x/y`, or a quadkey written as `qk:` followed by the digits. */
export const parser: Parser = makeParser('Map tile', text =>
  pipe(
    text.replace(/\s+/g, ''),
    Option.liftPredicate(
      compacted => compacted.includes('/') || QUADKEY_PREFIX_RE.test(compacted),
    ),
    Option.map(compacted =>
      QUADKEY_PREFIX_RE.test(compacted)
        ? fromQuadkey(compacted.replace(QUADKEY_PREFIX_RE, ''))
        : fromTilePath(compacted),
    ),
    Option.map(toParseResult),
  ),
)
 
export const grid: Grid = {
  id: 'Tile',
  label: 'Tiles',
  description: 'Web map tile boundaries, labelled z/x/y',
  colors: { onDark: [240, 200, 80, 140], onLight: [170, 120, 0, 170] },
  isEnabledByDefault: false,
  build: tileGrid,
  maybeCueOutline: Option.some((point, { tileZoom }) =>
    Option.some(tileOutline(toTile(point, tileZoom))),
  ),
}