import tempfile
import zipfile
from io import BytesIO
from pathlib import Path
import pyogrio
import pytest
from utils.kml_to_tab import KmlToTabError, convert_kml_to_tab_zip
MIXED_KML = b"""
Site A
Point feature
50.606051,26.261322,0
Sector A
Polygon feature
50.606051,26.261322,0
50.607051,26.261322,0
50.607051,26.262322,0
50.606051,26.261322,0
"""
RSRP_KML = b"""
DriveTest-LTE_UE_RSRP
-105.599998474121
normalPlacemark
-5.687045,11.305296
DriveTest-LTE_UE_RSRP
-116.099998474121
normalPlacemark
-5.687901,11.305419
"""
STRUCTURED_DESCRIPTION_KML = b"""
Busaiteen_1
<b>Sector Details:</b><br><b>code:</b> 1004<br><b>name:</b> Busaiteen_1<br><b>Azimut:</b> 30<br><b>Longitude:</b> 50.606051<br><b>Latitude:</b> 26.261322<br><b>size:</b> 1000<br><b>color:</b> 7fff0000<br>
50.606051,26.261322,0
50.607051,26.261322,0
50.607051,26.262322,0
50.606051,26.261322,0
"""
def test_convert_kml_to_tab_zip_splits_mixed_geometries():
result = convert_kml_to_tab_zip(MIXED_KML, "mixed sample.kml")
with zipfile.ZipFile(BytesIO(result.zip_bytes)) as zf:
names = sorted(zf.namelist())
assert "mixed_sample_point.tab" in names
assert "mixed_sample_point.dat" in names
assert "mixed_sample_point.map" in names
assert "mixed_sample_point.id" in names
assert "mixed_sample_polygon.tab" in names
assert "mixed_sample_polygon.dat" in names
assert "mixed_sample_polygon.map" in names
assert "mixed_sample_polygon.id" in names
assert [(layer.geometry_type, layer.feature_count) for layer in result.layers] == [
("Point", 1),
("Polygon", 1),
]
def test_convert_kml_to_tab_zip_preserves_measurement_values():
result = convert_kml_to_tab_zip(RSRP_KML, "rsrp.kml")
with tempfile.TemporaryDirectory() as tmp_dir_name:
tmp_dir = Path(tmp_dir_name)
with zipfile.ZipFile(BytesIO(result.zip_bytes)) as zf:
zf.extractall(tmp_dir)
metadata, _fids, _geometry, field_data = pyogrio.raw.read(tmp_dir / "rsrp.tab")
fields = metadata["fields"].tolist()
data = dict(zip(fields, field_data))
assert "value" in fields
assert "metric" not in fields
assert "parameter" not in fields
assert "legend" not in fields
assert "kml_color" not in fields
assert "style_rgb" not in fields
assert data["value"].tolist() == [-105.599998474121, -116.099998474121]
def test_convert_kml_to_tab_zip_expands_structured_description_fields():
result = convert_kml_to_tab_zip(STRUCTURED_DESCRIPTION_KML, "sectors.kml")
with tempfile.TemporaryDirectory() as tmp_dir_name:
tmp_dir = Path(tmp_dir_name)
with zipfile.ZipFile(BytesIO(result.zip_bytes)) as zf:
zf.extractall(tmp_dir)
metadata, _fids, _geometry, field_data = pyogrio.raw.read(
tmp_dir / "sectors.tab"
)
fields = metadata["fields"].tolist()
data = dict(zip(fields, field_data))
assert "value" not in fields
for field in [
"code",
"description_name",
"Azimut",
"Longitude",
"Latitude",
"size",
"color",
]:
assert field in fields
assert data["code"].tolist() == ["1004"]
assert data["description_name"].tolist() == ["Busaiteen_1"]
assert data["Azimut"].tolist() == ["30"]
assert data["Longitude"].tolist() == ["50.606051"]
assert data["Latitude"].tolist() == ["26.261322"]
assert data["size"].tolist() == ["1000"]
assert data["color"].tolist() == ["7fff0000"]
def test_convert_kml_to_tab_zip_rejects_empty_input():
with pytest.raises(KmlToTabError, match="vide"):
convert_kml_to_tab_zip(b"", "empty.kml")