All files / core/geo geometry.ts

96.77% Statements 30/31
100% Branches 9/9
80% Functions 4/5
100% Lines 21/21

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                                            22x                     37191x 37191x 37191x 37191x 37191x       104267x         3486x 3486x 3486x 24449x 27902x 20963x 27902x 3486x       641x 641x 641x 641x 18559x 641x    
/** Shared planar geometry for grid overlays. Positions are [lon, lat] in degrees. */
import type { LatLon } from './ellipsoid'
 
export type Position = [number, number]
export type RGBA = [number, number, number, number]
 
export interface GridPath {
  path: Position[]
  width: number
}
 
export interface GridLabel {
  position: Position
  text: string
  size: number
}
 
export interface GridGeometry {
  paths: GridPath[]
  labels: GridLabel[]
}
 
export const emptyGrid = (): GridGeometry => ({ paths: [], labels: [] })
 
/** Box as [west, south, east, north]. */
export type Box = readonly [
  west: number,
  south: number,
  east: number,
  north: number,
]
 
export function intersectBoxes(a: Box, b: Box): Box | null {
  const w = Math.max(a[0], b[0])
  const s = Math.max(a[1], b[1])
  const e = Math.min(a[2], b[2])
  const n = Math.min(a[3], b[3])
  return w < e && s < n ? [w, s, e, n] : null
}
 
export function inBox(p: LatLon, b: Box): boolean {
  return p.lon >= b[0] && p.lon <= b[2] && p.lat >= b[1] && p.lat <= b[3]
}
 
/** Rectangle outline, densified so parallels follow the globe. */
export function boxPath([w, s, e, n]: Box, step = 1): Position[] {
  const pts: Position[] = []
  const nx = Math.max(1, Math.ceil((e - w) / step))
  const ny = Math.max(1, Math.ceil((n - s) / step))
  for (let i = 0; i <= nx; i++) pts.push([w + ((e - w) * i) / nx, s])
  for (let i = 1; i <= ny; i++) pts.push([e, s + ((n - s) * i) / ny])
  for (let i = 1; i <= nx; i++) pts.push([e - ((e - w) * i) / nx, n])
  for (let i = 1; i <= ny; i++) pts.push([w, n - ((n - s) * i) / ny])
  return pts
}
 
export function densify(a: Position, b: Position, step: number): Position[] {
  const len = Math.hypot(b[0] - a[0], b[1] - a[1])
  const k = Math.max(1, Math.ceil(len / step))
  const out: Position[] = []
  for (let i = 0; i <= k; i++)
    out.push([a[0] + ((b[0] - a[0]) * i) / k, a[1] + ((b[1] - a[1]) * i) / k])
  return out
}