All files / core/systems/utm gzd.ts

100% Statements 42/42
93.93% Branches 31/33
100% Functions 3/3
100% Lines 31/31

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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                                          16x 16x 16x   320x 320x 320x 19200x 19200x 19200x 19200x 19200x 960x 912x 912x 912x 912x   19152x     16x               16x               16x               16x               16x     37191x     21x 21x 21x 25221x 3444x       3444x 24x             21x    
/** MGRS grid zone designations (UTM zones by latitude band) as a map grid. */
import {
  type Box,
  type GridGeometry,
  type GridLabel,
  type GridPath,
  boxPath,
  intersectBoxes,
} from '../../geo/geometry'
import { LAT_BANDS } from './utm'
 
export interface Cell {
  zone: number | null
  band: string
  west: number
  south: number
  east: number
  north: number
}
 
/** Every MGRS grid zone designation cell, with the Norway/Svalbard exceptions and UPS caps. */
export const GZD_CELLS: Cell[] = (() => {
  const cells: Cell[] = []
  for (let b = 0; b < 20; b++) {
    const band = LAT_BANDS[b]!
    const south = -80 + b * 8
    const north = band === 'X' ? 84 : south + 8
    for (let zone = 1; zone <= 60; zone++) {
      let west = -180 + (zone - 1) * 6
      let east = west + 6
      if (band === 'V' && zone === 31) east = 3
      if (band === 'V' && zone === 32) west = 3
      if (band === 'X') {
        if (zone === 32 || zone === 34 || zone === 36) continue
        if (zone === 31) east = 9
        if (zone === 33) [west, east] = [9, 21]
        if (zone === 35) [west, east] = [21, 33]
        if (zone === 37) [west, east] = [33, 42]
      }
      cells.push({ zone, band, west, south, east, north })
    }
  }
  cells.push({
    zone: null,
    band: 'A',
    west: -180,
    south: -90,
    east: 0,
    north: -80,
  })
  cells.push({
    zone: null,
    band: 'B',
    west: 0,
    south: -90,
    east: 180,
    north: -80,
  })
  cells.push({
    zone: null,
    band: 'Y',
    west: -180,
    south: 84,
    east: 0,
    north: 90,
  })
  cells.push({
    zone: null,
    band: 'Z',
    west: 0,
    south: 84,
    east: 180,
    north: 90,
  })
  return cells
})()
 
export const cellBox = (c: Cell): Box => [c.west, c.south, c.east, c.north]
 
export function gzdGrid(view: Box, zoom: number): GridGeometry {
  const paths: GridPath[] = []
  const labels: GridLabel[] = []
  for (const c of GZD_CELLS) {
    if (!intersectBoxes(view, cellBox(c))) continue
    paths.push({
      path: boxPath([c.west, c.south, c.east, c.north]),
      width: 1.5,
    })
    if (zoom >= 2.5) {
      labels.push({
        position: [(c.west + c.east) / 2, (c.south + c.north) / 2],
        text: `${c.zone ?? ''}${c.band}`,
        size: zoom < 4 ? 11 : 14,
      })
    }
  }
  return { paths, labels }
}