# Module: Common/Utils/GeoUtils ## Purpose Static geographic computation utilities: coordinate conversions, distance calculations (Haversine), bearing computation, point interpolation, and bounding box calculation. ## Public Interface All methods are static on `GeoUtils`: - `WorldToTilePos(GeoPoint point, int zoom) → (int x, int y)`: converts lat/lon to slippy map tile coordinates at given zoom - `TileToWorldPos(int x, int y, int zoom) → GeoPoint`: converts tile coordinates back to lat/lon (NW corner of tile) - `ToRadians(double degrees) → double` - `ToDegrees(double radians) → double` - `DirectionTo(this GeoPoint p1, GeoPoint p2) → Direction` (extension method): Haversine distance + forward azimuth between two points - `GoDirection(this GeoPoint startPoint, Direction direction) → GeoPoint` (extension method): destination point given start + bearing + distance - `GetBoundingBox(GeoPoint center, double radiusM) → (minLat, maxLat, minLon, maxLon)`: axis-aligned bounding box around a center point - `CalculateIntermediatePoints(GeoPoint start, GeoPoint end, double maxSpacingMeters) → List`: generates evenly-spaced points along a great-circle path (returns empty if distance ≤ maxSpacing) - `CalculateDistance(GeoPoint p1, GeoPoint p2) → double`: convenience wrapper around `DirectionTo().Distance` - `CalculateCenter(GeoPoint northWest, GeoPoint southEast) → GeoPoint`: simple midpoint - `CalculatePolygonDiagonalDistance(GeoPoint northWest, GeoPoint southEast) → double`: diagonal distance of a bounding box ## Internal Logic - Earth radius constant: `6378137` meters (WGS-84 semi-major axis) - Distance calculation uses the Haversine formula - Bearing uses `atan2` of longitude/latitude components - `CalculateIntermediatePoints` divides the segment into equal sub-segments, each ≤ `maxSpacingMeters` - Tile conversion follows the standard Web Mercator / slippy map tile numbering scheme ## Dependencies - `SatelliteProvider.Common.DTO.GeoPoint` - `SatelliteProvider.Common.DTO.Direction` ## Consumers - `GoogleMapsDownloaderV2` — `WorldToTilePos`, `TileToWorldPos`, `GetBoundingBox` - `TileService` — indirectly via downloader - `RegionService` — `WorldToTilePos` for tile stitching - `RouteService` — `CalculateIntermediatePoints`, `CalculateDistance` - `RouteProcessingService` — `WorldToTilePos` for map stitching - `SatTile` constructor — `TileToWorldPos` - `Program.cs` (ServeTile handler) — `TileToWorldPos` ## Data Models None. ## Configuration None. ## External Integrations None (pure math). ## Security None. ## Tests No dedicated unit tests for GeoUtils.