added formulas
This commit is contained in:
@@ -3,9 +3,12 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import rasterio
|
||||
|
||||
from app.core import coverage as coverage_core
|
||||
from app.core.antenna import AntennaPattern, gain
|
||||
from app.core.coverage import compute_coverage
|
||||
from app.core.surface import SurfaceProfile, SurfaceSample
|
||||
from app.core.vegetation import WORLDCOVER_P833, p833_coefficients_for_class
|
||||
from app.models.coverage import CoverageRequest
|
||||
from app.services import jobs
|
||||
@@ -22,7 +25,94 @@ def test_jobs_store_roundtrip() -> None:
|
||||
|
||||
|
||||
def test_coverage_fspl_geojson() -> None:
|
||||
request = CoverageRequest(
|
||||
request = _coverage_request(format="geojson", radius_m=5000, range_step_m=500)
|
||||
result = compute_coverage(request)
|
||||
assert result["type"] == "FeatureCollection"
|
||||
assert len(result["features"]) >= 1
|
||||
|
||||
|
||||
def test_coverage_geotiff_export(tmp_path: Path) -> None:
|
||||
request = _coverage_request(format="geotiff")
|
||||
|
||||
result = compute_coverage(request, output_dir=tmp_path)
|
||||
|
||||
path = Path(result["uri"])
|
||||
assert path.exists()
|
||||
assert result["kind"] == "coverage_raster"
|
||||
assert result["format"] == "geotiff"
|
||||
assert result["metadata"]["value_units"] == "dBm"
|
||||
assert result["metadata"]["valid_pixels"] > 0
|
||||
with rasterio.open(path) as dataset:
|
||||
assert dataset.driver == "GTiff"
|
||||
assert dataset.count == 1
|
||||
assert dataset.crs is not None
|
||||
assert dataset.nodata == -9999.0
|
||||
data = dataset.read(1)
|
||||
assert data.shape == (2, 2)
|
||||
assert (data != -9999.0).any()
|
||||
|
||||
|
||||
def test_coverage_png_export(tmp_path: Path) -> None:
|
||||
request = _coverage_request(format="png")
|
||||
|
||||
result = compute_coverage(request, output_dir=tmp_path)
|
||||
|
||||
path = Path(result["uri"])
|
||||
assert path.exists()
|
||||
assert result["kind"] == "coverage_raster"
|
||||
assert result["format"] == "png"
|
||||
assert result["metadata"]["png_min_dbm"] is not None
|
||||
with rasterio.open(path) as dataset:
|
||||
assert dataset.driver == "PNG"
|
||||
assert dataset.count == 1
|
||||
assert dataset.read(1).shape == (2, 2)
|
||||
|
||||
|
||||
def test_coverage_surface_obstruction_reduces_rx_power(monkeypatch) -> None:
|
||||
def fake_surface_profile(points, *, include_buildings, include_canopy, db=None):
|
||||
midpoint = len(points) // 2
|
||||
samples = [
|
||||
SurfaceSample(
|
||||
i=index,
|
||||
lat=point.lat,
|
||||
lon=point.lon,
|
||||
distance_m=point.distance_m,
|
||||
ground_m=0.0,
|
||||
building_m=0.0,
|
||||
canopy_m=80.0 if include_canopy and index == midpoint else 0.0,
|
||||
surface_m=80.0 if include_canopy and index == midpoint else 0.0,
|
||||
)
|
||||
for index, point in enumerate(points)
|
||||
]
|
||||
return SurfaceProfile(distance_m=points[-1].distance_m, samples=samples)
|
||||
|
||||
monkeypatch.setattr(coverage_core, "surface_profile_from_points", fake_surface_profile)
|
||||
obstructed = _coverage_request(
|
||||
format="geojson",
|
||||
include_buildings=False,
|
||||
include_canopy=True,
|
||||
)
|
||||
clear = _coverage_request(
|
||||
format="geojson",
|
||||
include_buildings=False,
|
||||
include_canopy=False,
|
||||
)
|
||||
|
||||
obstructed_power = coverage_core._rx_power_dbm(obstructed, 1.0, 90.0)
|
||||
clear_power = coverage_core._rx_power_dbm(clear, 1.0, 90.0)
|
||||
|
||||
assert obstructed_power < clear_power
|
||||
|
||||
|
||||
def _coverage_request(
|
||||
*,
|
||||
format: str,
|
||||
radius_m: float = 1000,
|
||||
range_step_m: float = 1000,
|
||||
include_buildings: bool = False,
|
||||
include_canopy: bool = False,
|
||||
) -> CoverageRequest:
|
||||
return CoverageRequest(
|
||||
tx={
|
||||
"lat": 59.935,
|
||||
"lon": 30.305,
|
||||
@@ -33,16 +123,15 @@ def test_coverage_fspl_geojson() -> None:
|
||||
antenna={"pattern": "omni", "gain_dbi": 8},
|
||||
rx={"height_agl": 2, "sensitivity_dbm": -110, "gain_dbi": 2},
|
||||
model="fspl",
|
||||
radius_m=5000,
|
||||
radius_m=radius_m,
|
||||
azimuth_step_deg=90,
|
||||
range_step_m=500,
|
||||
range_step_m=range_step_m,
|
||||
include_buildings=include_buildings,
|
||||
include_canopy=include_canopy,
|
||||
include_vegetation=False,
|
||||
levels_dbm=[-90],
|
||||
format="geojson",
|
||||
format=format,
|
||||
)
|
||||
result = compute_coverage(request)
|
||||
assert result["type"] == "FeatureCollection"
|
||||
assert len(result["features"]) >= 1
|
||||
|
||||
|
||||
def test_worldcover_p833_mapping() -> None:
|
||||
|
||||
Reference in New Issue
Block a user