weatherCacheCells.ts

Defines the geographic cell grid used to key weather cache entries

Purpose

This module implements the geographic cell grid that underpins the weather cache. It partitions the globe into a fixed-resolution grid of cells, assigns each cell a deterministic string key, and provides helpers for working with cell geometry and distance.

Its responsibilities include:

  • Defining the cell resolution constant used throughout the cache system
  • Validating lat/lon coordinates before any grid computation
  • Computing the cache key for any coordinate pair
  • Computing the center lat/lon of any cell by its key
  • Computing the haversine great-circle distance between two coordinates

Invariants

Cell Resolution

All grid computations use WEATHER_CACHE_CELL_RESOLUTION_KM = 2.5 as the cell size in kilometers.

Changing this constant invalidates all existing cache keys.


Coordinate Validation

assertValidCoordinates enforces:

  • lat and lon must be finite numbers
  • lat ∈ [−90, 90]
  • lon ∈ [−180, 180]

Violations throw a descriptive RangeError.


Cosine-Corrected Longitude Grid

Longitude cell size varies with latitude to maintain approximately uniform cell dimensions in kilometers:

lonStep = WEATHER_CACHE_CELL_RESOLUTION_KM / (DEG_LAT_TO_KM × max(0.01, cos(lat)))

The max(0.01, ...) guard prevents division by zero near the poles.


Cell Key Format

Cell keys are strings of the form "i:j" where i and j are integer indices computed by Math.floor(coord / step).

parseCellKey rejects any key where either component is not an integer, returning null.


Cell Center Derivation

Cell centers are at (i + 0.5) × latStep and (j + 0.5) × lonStep.

The longitude step for the center is computed using the cosine of the center latitude, matching the key-generation convention.


Exports

WEATHER_CACHE_CELL_RESOLUTION_KM

const WEATHER_CACHE_CELL_RESOLUTION_KM = 2.5;

The grid cell size in kilometers. Exported for use by dailyWorkAreaService and weatherService.


assertValidCoordinates(...)

function assertValidCoordinates(lat: number, lon: number): void

Throws a RangeError if either coordinate is non-finite or out of range.


calcWeatherCacheKey(...)

function calcWeatherCacheKey(lat: number, lon: number): string

Returns the "i:j" cell key for the given coordinates.


cellCenterLatLon(...)

function cellCenterLatLon(cellId: string): { lat: number; lon: number } | null

Returns the center coordinates of the cell with the given key, or null if the key is malformed.


haversineKm(...)

function haversineKm(aLat: number, aLon: number, bLat: number, bLon: number): number

Returns the haversine great-circle distance in kilometers between two coordinate pairs.