mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-22 09:06:37 +00:00
53 lines
2.3 KiB
Python
53 lines
2.3 KiB
Python
import math
|
|
from typing import Tuple, Dict, Any
|
|
from pydantic import BaseModel
|
|
from abc import ABC, abstractmethod
|
|
|
|
class TileBounds(BaseModel):
|
|
nw: Tuple[float, float]
|
|
ne: Tuple[float, float]
|
|
sw: Tuple[float, float]
|
|
se: Tuple[float, float]
|
|
center: Tuple[float, float]
|
|
gsd: float
|
|
|
|
class IWebMercatorUtils(ABC):
|
|
@abstractmethod
|
|
def latlon_to_tile(self, lat: float, lon: float, zoom: int) -> Tuple[int, int]: pass
|
|
@abstractmethod
|
|
def tile_to_latlon(self, x: int, y: int, zoom: int) -> Tuple[float, float]: pass
|
|
@abstractmethod
|
|
def compute_tile_bounds(self, x: int, y: int, zoom: int) -> TileBounds: pass
|
|
@abstractmethod
|
|
def get_zoom_gsd(self, lat: float, zoom: int) -> float: pass
|
|
|
|
class WebMercatorUtils(IWebMercatorUtils):
|
|
"""H06: Web Mercator projection (EPSG:3857) for tile coordinates."""
|
|
def latlon_to_tile(self, lat: float, lon: float, zoom: int) -> Tuple[int, int]:
|
|
lat_rad = math.radians(lat)
|
|
n = 2.0 ** zoom
|
|
return int((lon + 180.0) / 360.0 * n), int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
|
|
|
|
def tile_to_latlon(self, x: int, y: int, zoom: int) -> Tuple[float, float]:
|
|
n = 2.0 ** zoom
|
|
lat_rad = math.atan(math.sinh(math.pi * (1.0 - 2.0 * y / n)))
|
|
return math.degrees(lat_rad), x / n * 360.0 - 180.0
|
|
|
|
def get_zoom_gsd(self, lat: float, zoom: int) -> float:
|
|
return 156543.03392 * math.cos(math.radians(lat)) / (2.0 ** zoom)
|
|
|
|
def compute_tile_bounds(self, x: int, y: int, zoom: int) -> TileBounds:
|
|
center = self.tile_to_latlon(x + 0.5, y + 0.5, zoom)
|
|
return TileBounds(
|
|
nw=self.tile_to_latlon(x, y, zoom), ne=self.tile_to_latlon(x + 1, y, zoom),
|
|
sw=self.tile_to_latlon(x, y + 1, zoom), se=self.tile_to_latlon(x + 1, y + 1, zoom),
|
|
center=center, gsd=self.get_zoom_gsd(center[0], zoom)
|
|
)
|
|
|
|
# Module-level proxies for backward compatibility with F04
|
|
_instance = WebMercatorUtils()
|
|
def latlon_to_tile(lat, lon, zoom): return _instance.latlon_to_tile(lat, lon, zoom)
|
|
def tile_to_latlon(x, y, zoom): return _instance.tile_to_latlon(x, y, zoom)
|
|
def compute_tile_bounds(x, y, zoom):
|
|
b = _instance.compute_tile_bounds(x, y, zoom)
|
|
return {"nw": b.nw, "ne": b.ne, "sw": b.sw, "se": b.se, "center": b.center, "gsd": b.gsd} |