@mytec: feat: Phase 3.0 Architecture Refactor ✅
Major refactoring of RFCP backend: - Modular propagation models (8 models) - SharedMemoryManager for terrain data - ProcessPoolExecutor parallel processing - WebSocket progress streaming - Building filtering pipeline (351k → 15k) - 82 unit tests Performance: Standard preset 38s → 5s (7.6x speedup) Known issue: Detailed preset timeout (fix in 3.1.0)
This commit is contained in:
83
backend/app/core/grid.py
Normal file
83
backend/app/core/grid.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
Grid generation for coverage calculations.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Tuple
|
||||
from app.geometry.haversine import haversine_distance
|
||||
|
||||
|
||||
@dataclass
|
||||
class BoundingBox:
|
||||
min_lat: float
|
||||
min_lon: float
|
||||
max_lat: float
|
||||
max_lon: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Grid:
|
||||
points: List[Tuple[float, float]]
|
||||
bounding_box: BoundingBox
|
||||
resolution: float
|
||||
radius: float
|
||||
|
||||
|
||||
class GridService:
|
||||
"""Generate coverage grid points."""
|
||||
|
||||
@staticmethod
|
||||
def generate(
|
||||
center_lat: float,
|
||||
center_lon: float,
|
||||
radius: float,
|
||||
resolution: float,
|
||||
) -> Grid:
|
||||
points = []
|
||||
|
||||
lat_step = resolution / 111000
|
||||
lon_step = resolution / (111000 * np.cos(np.radians(center_lat)))
|
||||
|
||||
lat_delta = radius / 111000
|
||||
lon_delta = radius / (111000 * np.cos(np.radians(center_lat)))
|
||||
|
||||
bbox = BoundingBox(
|
||||
min_lat=center_lat - lat_delta,
|
||||
min_lon=center_lon - lon_delta,
|
||||
max_lat=center_lat + lat_delta,
|
||||
max_lon=center_lon + lon_delta,
|
||||
)
|
||||
|
||||
lat = center_lat - lat_delta
|
||||
while lat <= center_lat + lat_delta:
|
||||
lon = center_lon - lon_delta
|
||||
while lon <= center_lon + lon_delta:
|
||||
dist = haversine_distance(center_lat, center_lon, lat, lon)
|
||||
if dist <= radius:
|
||||
points.append((lat, lon))
|
||||
lon += lon_step
|
||||
lat += lat_step
|
||||
|
||||
return Grid(points=points, bounding_box=bbox, resolution=resolution, radius=radius)
|
||||
|
||||
@staticmethod
|
||||
def generate_multi_site(sites: list, radius: float, resolution: float) -> Grid:
|
||||
all_points = set()
|
||||
min_lat = min_lon = float("inf")
|
||||
max_lat = max_lon = float("-inf")
|
||||
|
||||
for site in sites:
|
||||
grid = GridService.generate(site.lat, site.lon, radius, resolution)
|
||||
for p in grid.points:
|
||||
all_points.add((round(p[0], 7), round(p[1], 7)))
|
||||
min_lat = min(min_lat, grid.bounding_box.min_lat)
|
||||
min_lon = min(min_lon, grid.bounding_box.min_lon)
|
||||
max_lat = max(max_lat, grid.bounding_box.max_lat)
|
||||
max_lon = max(max_lon, grid.bounding_box.max_lon)
|
||||
|
||||
return Grid(
|
||||
points=list(all_points),
|
||||
bounding_box=BoundingBox(min_lat, min_lon, max_lat, max_lon),
|
||||
resolution=resolution, radius=radius,
|
||||
)
|
||||
Reference in New Issue
Block a user