feat: 增加干扰小区方位角

This commit is contained in:
2026-08-03 15:25:51 +08:00
parent 9776391ad1
commit 60e5c1ce6a
4 changed files with 71 additions and 32 deletions
+21 -6
View File
@@ -38,7 +38,7 @@ class PipelineTest(unittest.TestCase):
self.assertEqual(len(rows), 7)
self.assertEqual(
list(rows[0]),
["hour_start", "hour_end", "cgi", "cell_name", "interference_dbm", "longitude", "latitude"],
["hour_start", "hour_end", "cgi", "cell_name", "interference_dbm", "longitude", "latitude", "azimuth"],
)
rows_by_type = {row["cell_name"].removesuffix("-小区"): row for row in rows}
self.assertEqual(rows_by_type["5G干扰监控"]["cgi"], "460-00-200-1")
@@ -48,7 +48,9 @@ class PipelineTest(unittest.TestCase):
self.assertTrue(all(row["interference_dbm"] == "-100.5" for row in rows))
self.assertEqual(rows_by_type["5G干扰监控"]["longitude"], "113.123456")
self.assertEqual(rows_by_type["5G干扰监控"]["latitude"], "22.654321")
self.assertEqual(rows_by_type["5G干扰监控"]["azimuth"], "30")
self.assertTrue(all(not row["longitude"] and not row["latitude"] for row in rows if row["cgi"] == "460-00-100-1"))
self.assertTrue(all(row["azimuth"] == "0" for row in rows if row["cgi"] == "460-00-100-1"))
manifest = json.loads((result / "manifest.json").read_text(encoding="utf-8"))
self.assertEqual(manifest["source_file_count"], 7)
@@ -103,12 +105,17 @@ class PipelineTest(unittest.TestCase):
with self.assertRaisesRegex(main.ProcessingError, "missing columns.*纬度"):
main.parse_cell_data_workbook(raw, "bad.xlsx")
def test_conflicting_cell_data_coordinates_are_rejected(self) -> None:
def test_conflicting_cell_data_metadata_are_rejected(self) -> None:
first = create_cell_data_workbook(longitude=113.1)
second = create_cell_data_workbook(longitude=113.2)
with self.assertRaisesRegex(main.ProcessingError, "Conflicting CellData coordinates"):
main.load_cell_coordinates([("first.xlsx", first), ("second.xlsx", second)])
with self.assertRaisesRegex(main.ProcessingError, "Conflicting CellData metadata"):
main.load_cell_metadata([("first.xlsx", first), ("second.xlsx", second)])
def test_empty_cell_data_azimuth_defaults_to_zero(self) -> None:
metadata = main.parse_cell_data_workbook(create_cell_data_workbook(azimuth=None), "cell-data.xlsx")
self.assertEqual(metadata["460-00-200-1"], ("113.123456", "22.654321", "0"))
def test_api_store_replaces_same_hour_and_deletes_other_hours(self) -> None:
client = FakeApiClient("2026-07-31T10:00:00")
@@ -124,10 +131,11 @@ class PipelineTest(unittest.TestCase):
self.assertTrue(any("CREATE DATABASE IF NOT EXISTS `interference_etl`" in query for query in queries))
self.assertTrue(any("ADD COLUMN `longitude`" in query for query in queries))
self.assertTrue(any("ADD COLUMN `latitude`" in query for query in queries))
self.assertTrue(any("ADD COLUMN `azimuth`" in query for query in queries))
script = next(payload for endpoint, payload in client.posts if endpoint.endswith("/run-script"))
self.assertTrue(script["single_session"])
self.assertIn("START TRANSACTION", script["content"])
self.assertIn("NULL, NULL)", script["content"])
self.assertIn("NULL, NULL, 0", script["content"])
self.assertIn("CONVERT(0x", script["content"])
self.assertNotIn("source_type", script["content"])
self.assertNotIn("source_path", script["content"])
@@ -226,6 +234,7 @@ def database_row() -> dict[str, str]:
"interference_dbm": "-100.5",
"longitude": "",
"latitude": "",
"azimuth": "0",
}
@@ -283,17 +292,23 @@ def create_cell_data_sources(root: Path) -> None:
(directory / f"江门小区信息表{index}-20260728.xlsx").write_bytes(raw)
def create_cell_data_workbook(longitude: float = 113.123456, include_latitude: bool = True) -> bytes:
def create_cell_data_workbook(
longitude: float = 113.123456,
include_latitude: bool = True,
azimuth: float | None = 30,
) -> bytes:
workbook = Workbook()
sheet = workbook.active
sheet.title = "小区信息表"
header = ["小区名称", "eNB/gNB", "CI", "经度"]
if include_latitude:
header.append("纬度")
header.append("方向角")
sheet.append(header)
row: list[object] = ["测试小区", 200, 1, longitude]
if include_latitude:
row.append(22.654321)
row.append(azimuth)
sheet.append(row)
content = io.BytesIO()
workbook.save(content)