added bootstrap buildings

This commit is contained in:
2026-06-23 09:53:39 +03:00
parent bcf0ce76e7
commit 69d63e9152
23 changed files with 507 additions and 17 deletions
+29 -3
View File
@@ -1,12 +1,14 @@
from __future__ import annotations
import numpy as np
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from app.config import get_settings
from app.core import dem
from app.core.diffraction import deygout
from app.core.fresnel import los_analysis
from app.core.geo import GeoPoint, linestring_geojson, sample_path
from app.core.geo import GeoPoint, PathPoint, linestring_geojson, sample_path
from app.core.surface import build_surface_profile
from app.models.terrain import (
ElevationResponse,
@@ -17,6 +19,7 @@ from app.models.terrain import (
TerrainProfileRequest,
TerrainProfileResponse,
)
from app.services import buildings as buildings_service
def elevation_at(lat: float, lon: float, surface: str) -> ElevationResponse:
@@ -25,7 +28,10 @@ def elevation_at(lat: float, lon: float, surface: str) -> ElevationResponse:
return ElevationResponse(lat=lat, lon=lon, elevation_m=elevation_m, surface=surface)
def terrain_profile(request: TerrainProfileRequest) -> TerrainProfileResponse:
def terrain_profile(
request: TerrainProfileRequest,
db: Session | None = None,
) -> TerrainProfileResponse:
points = sample_path(
GeoPoint(lat=request.start.lat, lon=request.start.lon),
GeoPoint(lat=request.end.lat, lon=request.end.lon),
@@ -36,9 +42,11 @@ def terrain_profile(request: TerrainProfileRequest) -> TerrainProfileResponse:
except dem.DemNotConfiguredError:
ground_elevations = np.zeros(len(points), dtype=float).tolist()
building_heights = _building_heights(points, request.include_buildings, db)
profile = build_surface_profile(
points,
ground_elevations=ground_elevations,
building_heights=building_heights,
include_buildings=request.include_buildings,
include_canopy=request.include_canopy,
)
@@ -49,7 +57,10 @@ def terrain_profile(request: TerrainProfileRequest) -> TerrainProfileResponse:
)
def los(request: LosRequest) -> LosResponse:
def los(
request: LosRequest,
db: Session | None = None,
) -> LosResponse:
profile_request = TerrainProfileRequest(
start=request.tx,
end=request.rx,
@@ -68,9 +79,11 @@ def los(request: LosRequest) -> LosResponse:
except dem.DemNotConfiguredError:
ground_elevations = np.zeros(len(points), dtype=float).tolist()
building_heights = _building_heights(points, request.include_buildings, db)
surface_profile = build_surface_profile(
points,
ground_elevations=ground_elevations,
building_heights=building_heights,
include_buildings=request.include_buildings,
include_canopy=request.include_canopy,
)
@@ -105,3 +118,16 @@ def los(request: LosRequest) -> LosResponse:
diffraction_loss_db=diffraction_loss,
profile_ref=f"inline:{profile_request.samples}",
)
def _building_heights(
points: list[PathPoint],
include_buildings: bool,
db: Session | None,
) -> list[float] | None:
if not include_buildings or db is None:
return None
try:
return buildings_service.building_heights_along(points, db)
except SQLAlchemyError:
return None