@mytec: iter1.6.1 ready for testing

This commit is contained in:
2026-01-31 13:19:36 +02:00
parent c97355f444
commit 375a78f5b9
11 changed files with 1055 additions and 4 deletions

View File

@@ -12,6 +12,9 @@ from app.services.reflection_service import reflection_service
from app.services.spatial_index import get_spatial_index, SpatialIndex
from app.services.water_service import water_service, WaterBody
from app.services.vegetation_service import vegetation_service, VegetationArea
from app.services.weather_service import weather_service
from app.services.indoor_service import indoor_service
from app.services.atmospheric_service import atmospheric_service
class CoveragePoint(BaseModel):
@@ -24,6 +27,9 @@ class CoveragePoint(BaseModel):
building_loss: float # dB
reflection_gain: float = 0.0 # dB
vegetation_loss: float = 0.0 # dB
rain_loss: float = 0.0 # dB
indoor_loss: float = 0.0 # dB
atmospheric_loss: float = 0.0 # dB
class CoverageSettings(BaseModel):
@@ -44,6 +50,17 @@ class CoverageSettings(BaseModel):
# Vegetation season
season: str = "summer"
# Weather
rain_rate: float = 0.0 # mm/h (0=none, 5=light, 25=heavy)
# Indoor
indoor_loss_type: str = "none" # none, light, medium, heavy, vehicle
# Atmospheric
use_atmospheric: bool = False
temperature_c: float = 15.0
humidity_percent: float = 50.0
# Preset
preset: Optional[str] = None # fast, standard, detailed, full
@@ -419,9 +436,38 @@ class CoverageService:
if is_over_water:
reflection_gain = 3.0 # ~3dB boost over water
# Rain attenuation
rain_loss = 0.0
if settings.rain_rate > 0:
rain_loss = weather_service.calculate_rain_attenuation(
site.frequency,
distance / 1000, # km
settings.rain_rate
)
# Indoor penetration loss
indoor_loss = 0.0
if settings.indoor_loss_type != "none":
indoor_loss = indoor_service.calculate_indoor_loss(
site.frequency,
settings.indoor_loss_type
)
# Atmospheric absorption
atmo_loss = 0.0
if settings.use_atmospheric:
atmo_loss = atmospheric_service.calculate_atmospheric_loss(
site.frequency,
distance / 1000,
settings.temperature_c,
settings.humidity_percent
)
# Final RSRP
rsrp = (site.power + site.gain - path_loss - antenna_loss
- terrain_loss - building_loss - veg_loss + reflection_gain)
- terrain_loss - building_loss - veg_loss
- rain_loss - indoor_loss - atmo_loss
+ reflection_gain)
return CoveragePoint(
lat=lat,
@@ -432,7 +478,10 @@ class CoverageService:
terrain_loss=terrain_loss,
building_loss=building_loss,
reflection_gain=reflection_gain,
vegetation_loss=veg_loss
vegetation_loss=veg_loss,
rain_loss=rain_loss,
indoor_loss=indoor_loss,
atmospheric_loss=atmo_loss,
)
def _okumura_hata(