Skip to content

Commit 961f2db

Browse files
committed
Normalize compact OFMX runway bearings
1 parent 818e2f3 commit 961f2db

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

src/ofmx2pgsql/parser.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ def iter_runway_ends(path: Path) -> Iterator[RunwayEnd]:
220220
runway_ofmx_id=rwy_uid.get("mid") if rwy_uid is not None else None,
221221
airport_ofmx_id=ahp_uid.get("mid") if ahp_uid is not None else None,
222222
designator=_text(rdn_uid, "txtDesig"),
223-
true_bearing=_to_float(_text(elem, "valTrueBrg")),
224-
mag_bearing=_to_float(_text(elem, "valMagBrg")),
223+
true_bearing=_parse_bearing(_text(elem, "valTrueBrg")),
224+
mag_bearing=_parse_bearing(_text(elem, "valMagBrg")),
225225
latitude=_parse_coordinate(_text(elem, "geoLat")),
226226
longitude=_parse_coordinate(_text(elem, "geoLong")),
227227
)
@@ -370,6 +370,23 @@ def _parse_coordinate(value: Optional[str]) -> Optional[float]:
370370
return parsed
371371

372372

373+
def _parse_bearing(value: Optional[str]) -> Optional[float]:
374+
parsed = _to_float(value)
375+
if parsed is None:
376+
return None
377+
if 0 <= parsed <= 360:
378+
return parsed
379+
if not value:
380+
return parsed
381+
raw = value.strip()
382+
if "." in raw or not raw.isdigit():
383+
return parsed
384+
scaled = int(raw) / 1000
385+
if 0 <= scaled <= 360:
386+
return round(scaled, 6)
387+
return parsed
388+
389+
373390
def _parse_gml_pos_list(value: Optional[str]) -> list[tuple[float, float]]:
374391
if not value:
375392
return []

tests/test_parser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ def test_iter_airspace_shapes_reads_sample(self) -> None:
4444
self.assertIsNotNone(first.ofmx_id)
4545
self.assertGreater(len(first.positions), 3)
4646

47+
def test_parse_bearing_normalizes_compact_out_of_range_value(self) -> None:
48+
self.assertEqual(parser._parse_bearing("232230"), 232.23)
49+
50+
def test_parse_bearing_keeps_normal_value(self) -> None:
51+
self.assertEqual(parser._parse_bearing("052"), 52.0)
52+
53+
def test_parse_bearing_preserves_leading_zero_fractional_value(self) -> None:
54+
self.assertEqual(parser._parse_bearing("006169"), 6.169)
55+
4756

4857
if __name__ == "__main__":
4958
unittest.main()

0 commit comments

Comments
 (0)