146 lines
4.2 KiB
Python
146 lines
4.2 KiB
Python
import httpx
|
|
import numpy as np
|
|
import pytest
|
|
import rasterio
|
|
from rasterio.transform import from_origin
|
|
|
|
from pipeline.download import noise
|
|
|
|
|
|
def test_download_tile_splits_after_retries(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "MAX_RETRIES", 1)
|
|
monkeypatch.setattr(noise, "MIN_TILE_SIZE", 50)
|
|
|
|
def fake_fetch_tile_bytes(
|
|
wcs_base,
|
|
coverage_id,
|
|
min_e,
|
|
min_n,
|
|
max_e,
|
|
max_n,
|
|
wcs_version="1.0.0",
|
|
):
|
|
if max_e - min_e > 50 or max_n - min_n > 50:
|
|
raise httpx.TimeoutException("too large")
|
|
return b"II*\x00fake-tiff"
|
|
|
|
monkeypatch.setattr(noise, "_fetch_tile_bytes", fake_fetch_tile_bytes)
|
|
|
|
paths, failures = noise._download_tile("base", "coverage", 0, 0, 100, 100, tmp_path)
|
|
|
|
assert failures == []
|
|
assert len(paths) == 4
|
|
assert sorted(path.name for path in paths) == [
|
|
"tile_0_0_50_50.tif",
|
|
"tile_0_50_50_100.tif",
|
|
"tile_50_0_100_50.tif",
|
|
"tile_50_50_100_100.tif",
|
|
]
|
|
|
|
|
|
def test_download_tile_reports_unsplittable_failure(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "MAX_RETRIES", 1)
|
|
monkeypatch.setattr(noise, "MIN_TILE_SIZE", 100)
|
|
|
|
def fake_fetch_tile_bytes(*args, **kwargs):
|
|
raise httpx.ConnectError("offline")
|
|
|
|
monkeypatch.setattr(noise, "_fetch_tile_bytes", fake_fetch_tile_bytes)
|
|
|
|
paths, failures = noise._download_tile("base", "coverage", 0, 0, 100, 100, tmp_path)
|
|
|
|
assert paths == []
|
|
assert failures == [(0, 0, 100, 100)]
|
|
|
|
|
|
def test_download_tile_treats_non_tiff_response_as_failure(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "MAX_RETRIES", 1)
|
|
monkeypatch.setattr(noise, "MIN_TILE_SIZE", 100)
|
|
|
|
def fake_fetch_tile_bytes(*args, **kwargs):
|
|
raise noise.NoGeoTiffError("xml exception")
|
|
|
|
monkeypatch.setattr(noise, "_fetch_tile_bytes", fake_fetch_tile_bytes)
|
|
|
|
paths, failures = noise._download_tile("base", "coverage", 0, 0, 100, 100, tmp_path)
|
|
|
|
assert paths == []
|
|
assert failures == [(0, 0, 100, 100)]
|
|
|
|
|
|
def test_download_raster_tolerates_missing_tiles_when_allowed(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "BNG_MIN_E", 0)
|
|
monkeypatch.setattr(noise, "BNG_MAX_E", 100)
|
|
monkeypatch.setattr(noise, "BNG_MIN_N", 0)
|
|
monkeypatch.setattr(noise, "BNG_MAX_N", 100)
|
|
monkeypatch.setattr(noise, "TILE_SIZE", 100)
|
|
|
|
def fake_download_tile(*args, **kwargs):
|
|
return [], [(0, 0, 100, 100)]
|
|
|
|
monkeypatch.setattr(noise, "_download_tile", fake_download_tile)
|
|
|
|
paths = noise.download_raster(
|
|
tmp_path,
|
|
"base",
|
|
"coverage",
|
|
"Airport",
|
|
allow_missing_tiles=True,
|
|
)
|
|
|
|
assert paths == []
|
|
|
|
|
|
def test_download_raster_raises_on_missing_strict_tiles(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "BNG_MIN_E", 0)
|
|
monkeypatch.setattr(noise, "BNG_MAX_E", 100)
|
|
monkeypatch.setattr(noise, "BNG_MIN_N", 0)
|
|
monkeypatch.setattr(noise, "BNG_MAX_N", 100)
|
|
monkeypatch.setattr(noise, "TILE_SIZE", 100)
|
|
|
|
def fake_download_tile(*args, **kwargs):
|
|
return [], [(0, 0, 100, 100)]
|
|
|
|
monkeypatch.setattr(noise, "_download_tile", fake_download_tile)
|
|
|
|
with pytest.raises(RuntimeError, match=r"\[Road\] Failed to download"):
|
|
noise.download_raster(tmp_path, "base", "coverage", "Road")
|
|
|
|
|
|
def test_sample_noise_at_postcodes_uses_local_maximum(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(noise, "POSTCODE_NOISE_RADIUS_M", 15)
|
|
monkeypatch.setattr(noise, "RESOLUTION", 10)
|
|
tile_path = tmp_path / "noise.tif"
|
|
data = np.array(
|
|
[
|
|
[0, 0, 0, 0, 0],
|
|
[0, 70, 0, 0, 0],
|
|
[0, 0, 55, 0, 0],
|
|
[0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0],
|
|
],
|
|
dtype=np.float32,
|
|
)
|
|
with rasterio.open(
|
|
tile_path,
|
|
"w",
|
|
driver="GTiff",
|
|
height=data.shape[0],
|
|
width=data.shape[1],
|
|
count=1,
|
|
dtype=data.dtype,
|
|
crs="EPSG:27700",
|
|
transform=from_origin(0, 50, 10, 10),
|
|
nodata=0,
|
|
) as dataset:
|
|
dataset.write(data, 1)
|
|
|
|
result = noise.sample_noise_at_postcodes(
|
|
[tile_path],
|
|
easting=np.array([25.0]),
|
|
northing=np.array([25.0]),
|
|
label="Road",
|
|
col_name="road_noise_lden_db",
|
|
)
|
|
|
|
assert result.to_list() == [70.0]
|