dailyWorkAreaService.ts

Generates weather cache cell locations covering a work area circle

Purpose

This module takes a geographic work area circle and produces the set of weather cache cell coordinates that must be pre-fetched to fully cover that area. It is the bridge between the user-defined work area and the weather pre-caching pipeline.

Its responsibilities include:

  • Validating the circle center coordinates and radius before computation
  • Expanding the radius by a configurable safety margin
  • Iterating over the latitude-band grid to enumerate candidate cache cells
  • Computing longitude step sizes correctly for each latitude band using cosine correction
  • Filtering candidates to only those whose centers fall within the expanded radius via haversine distance
  • Deduplicating cells by cellId and returning them in deterministic sorted order

Invariants

Coordinate and Radius Validation

centerLat, centerLon, and radiusKm are validated before any cell enumeration begins.

  • Coordinates delegate to assertValidCoordinates from weatherCacheCells
  • radiusKm must be a positive finite number
  • safetyMarginKm must be a non-negative finite number

Invalid inputs throw a RangeError.


Safety Margin Expansion

The expanded search radius is always radiusKm + safetyMarginKm.

The default safety margin equals WEATHER_CACHE_CELL_RESOLUTION_KM (2.5 km), ensuring that cells adjacent to the circle boundary are included to prevent edge-of-circle cache misses.


Cosine-Corrected Longitude Steps

Longitude cell size varies with latitude. All longitude grid computations use:

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

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


Haversine Inclusion Test

Only cells whose center (computed via cellCenterLatLon) falls within expandedRadiusKm of the circle center are included.

Cells for which cellCenterLatLon returns null (malformed cell ID) are skipped silently.


Deduplication and Sort

The result map keyed by cellId ensures each cell appears at most once even if the grid enumeration visits it from multiple latitude bands.

The returned array is sorted lexicographically by cellId for deterministic ordering.


Exports

DailyWorkAreaCacheLocation

type DailyWorkAreaCacheLocation = {
	cellId: string;
	lat: number;
	lon: number;
};

Represents a single weather cache cell within the work area:

FieldDescription
cellIdCache key string from calcWeatherCacheKey
latCell center latitude
lonCell center longitude

generateDailyWorkAreaCacheLocations(...)

function generateDailyWorkAreaCacheLocations(
	circle: Pick<DailyWorkAreaCircle, "centerLat" | "centerLon" | "radiusKm">,
	safetyMarginKm?: number,
): DailyWorkAreaCacheLocation[]

Returns all weather cache cell locations covering the given circle, sorted by cellId.

Parameters

ParameterDescription
circleCenter coordinates and radius of the work area
safetyMarginKmExtra radius added to catch edge cells (default: WEATHER_CACHE_CELL_RESOLUTION_KM)

Throws

Throws RangeError when coordinates, radius, or safety margin are invalid.