Skip to content

Commit 6f0d08a

Browse files
authored
Merge pull request #125 from mivek/copilot/implement-pr-789-changes
feat: Add explicit runway visual range unit to parsed METAR runway data
2 parents 17822fe + 0cc12e4 commit 6f0d08a

5 files changed

Lines changed: 44 additions & 4 deletions

File tree

metar_taf_parser/command/metar.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from metar_taf_parser.commons import converter
44
from metar_taf_parser.commons.exception import ParseError
5-
from metar_taf_parser.model.enum import DepositType, DepositCoverage
5+
from metar_taf_parser.model.enum import DepositType, DepositCoverage, LengthUnit
66
from metar_taf_parser.model.model import RunwayInfo, Metar
77
from metar_taf_parser.commons.i18n import _
88

@@ -42,11 +42,16 @@ def execute(self, metar: Metar, input: str):
4242
metar.altimeter = int(converter.convert_inches_mercury_to_pascal(mercury))
4343

4444

45+
def _parse_runway_unit(input: str):
46+
return LengthUnit.FEET if input == 'FT' else LengthUnit.METERS
47+
48+
4549
def _parse_runway(matches, metar, runway):
4650
runway.name = matches[0][0]
4751
runway.indicator = matches[0][1]
4852
runway.min_range = int(matches[0][2])
4953
runway.trend = matches[0][3]
54+
runway.unit = _parse_runway_unit(matches[0][4])
5055
metar.add_runway_info(runway)
5156

5257

@@ -55,6 +60,7 @@ def _parse_runway_max_range(matches, metar, runway):
5560
runway.min_range = int(matches[0][1])
5661
runway.max_range = int(matches[0][2])
5762
runway.trend = matches[0][3]
63+
runway.unit = _parse_runway_unit(matches[0][4])
5864
metar.add_runway_info(runway)
5965

6066

metar_taf_parser/model/enum.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ def __repr__(self):
6161
return _('DepositType.' + self.name)
6262

6363

64+
class LengthUnit(enum.Enum):
65+
METERS = 'M'
66+
FEET = 'FT'
67+
68+
def __str__(self):
69+
return self.value
70+
71+
def __repr__(self):
72+
return self.value
73+
74+
6475
class Descriptive(enum.Enum):
6576
SHOWERS = 'SH'
6677
SHALLOW = 'MI'

metar_taf_parser/model/model.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ def __init__(self):
211211
self._name = None
212212
self._min_range = None
213213
self._max_range = None
214+
self._unit = None
214215
self._trend = None
215216
self._indicator = None
216217
self._deposit_type = None
@@ -236,6 +237,12 @@ def _get_max_range(self):
236237
def _set_max_range(self, value):
237238
self._max_range = value
238239

240+
def _get_unit(self):
241+
return self._unit
242+
243+
def _set_unit(self, value):
244+
self._unit = value
245+
239246
def _get_trend(self):
240247
return self._trend
241248

@@ -273,13 +280,14 @@ def _set_braking_capacity(self, value):
273280
self._braking_capacity = value
274281

275282
def __repr__(self):
276-
return f'RunwayInfo[name={self.name}, min_range={self.min_range}, max_range={self.max_range}, '\
283+
return f'RunwayInfo[name={self.name}, min_range={self.min_range}, max_range={self.max_range}, unit={self.unit}, '\
277284
f'trend={self.trend}, indicator={self.indicator}, deposit_type={self.deposit_type}, '\
278285
f'coverage={self.coverage}, thickness={self.thickness}, braking_capacity={self.braking_capacity}]'\
279286

280287
name = property(_get_name, _set_name)
281288
min_range = property(_get_min_range, _set_min_range)
282289
max_range = property(_get_max_range, _set_max_range)
290+
unit = property(_get_unit, _set_unit)
283291
trend = property(_get_trend, _set_trend)
284292
indicator = property(_get_indicator, _set_indicator)
285293
deposit_type = property(_get_deposit_type, _set_deposit_type)

metar_taf_parser/tests/command/test_metar.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from metar_taf_parser.command.metar import RunwayCommand, CommandSupplier
44
from metar_taf_parser.commons.exception import ParseError
5-
from metar_taf_parser.model.enum import DepositType, DepositCoverage
5+
from metar_taf_parser.model.enum import DepositType, DepositCoverage, LengthUnit
66
from metar_taf_parser.model.model import Metar
77
from metar_taf_parser.commons.i18n import _
88

@@ -20,6 +20,7 @@ def test_runway_command_execute(self):
2020
self.assertEqual('26', runway_info.name)
2121
self.assertEqual(600, runway_info.min_range)
2222
self.assertEqual('U', runway_info.trend)
23+
self.assertEqual(LengthUnit.METERS, runway_info.unit)
2324

2425
def test_runway_command_execute_runway(self):
2526
metar = Metar()
@@ -34,6 +35,7 @@ def test_runway_command_execute_runway(self):
3435
self.assertEqual(550, runway_info.min_range)
3536
self.assertEqual(700, runway_info.max_range)
3637
self.assertEqual('U', runway_info.trend)
38+
self.assertEqual(LengthUnit.METERS, runway_info.unit)
3739

3840
def test_runway_command_execute_wrong_runway(self):
3941
metar = Metar()
@@ -54,6 +56,7 @@ def test_parse_runwway_visual_range_feet_variable(self):
5456
self.assertEqual(600, metar.runways_info[0].min_range)
5557
self.assertEqual(1000, metar.runways_info[0].max_range)
5658
self.assertEqual('', metar.runways_info[0].trend)
59+
self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit)
5760

5861
def test_parse_runway_visual_range_feet_simple(self):
5962
metar = Metar()
@@ -65,6 +68,7 @@ def test_parse_runway_visual_range_feet_simple(self):
6568
self.assertEqual('01L', metar.runways_info[0].name)
6669
self.assertEqual(800, metar.runways_info[0].min_range)
6770
self.assertEqual('', metar.runways_info[0].trend)
71+
self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit)
6872

6973
def test_parse_runway_deposit(self):
7074
metar = Metar()
@@ -101,13 +105,15 @@ def test_parse_runway_with_less_than_indicator_and_unit(self):
101105
self.assertEqual('01L', metar.runways_info[0].name)
102106
self.assertEqual('M', metar.runways_info[0].indicator)
103107
self.assertEqual(600, metar.runways_info[0].min_range)
108+
self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit)
104109

105110
def test_parse_runway_with_greater_than_indicator(self):
106111
metar = Metar()
107112
RunwayCommand().execute(metar, 'R01L/P0600FT')
108113
self.assertEqual('01L', metar.runways_info[0].name)
109114
self.assertEqual('P', metar.runways_info[0].indicator)
110115
self.assertEqual(600, metar.runways_info[0].min_range)
116+
self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit)
111117

112118
def test_parse_runway_missing_info(self):
113119
metar = Metar()

metar_taf_parser/tests/parser/test_parser.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from parameterized import parameterized
44

55
from metar_taf_parser.model.enum import Intensity, Phenomenon, Descriptive, DepositType, DepositCoverage, WeatherChangeType, CloudQuantity, CloudType, \
6-
TimeIndicator, TurbulenceIntensity, IcingIntensity
6+
TimeIndicator, TurbulenceIntensity, IcingIntensity, LengthUnit
77
from metar_taf_parser.model.model import AbstractWeatherContainer, Visibility, Wind
88
from metar_taf_parser.parser.parser import AbstractParser, MetarParser, _parse_validity, _parse_temperature, TAFParser, \
99
RemarkParser
@@ -90,6 +90,15 @@ def test_parse(self):
9090
self.assertEqual('27L', metar.runways_info[0].name)
9191
self.assertEqual(375, metar.runways_info[0].min_range)
9292
self.assertEqual('N', metar.runways_info[0].trend)
93+
self.assertEqual(LengthUnit.METERS, metar.runways_info[0].unit)
94+
95+
def test_parse_with_runway_visual_range_in_feet(self):
96+
metar = MetarParser().parse('KJFK 121651Z 18012KT 9999 R24L/2400FT SCT015 18/12 A2992')
97+
98+
self.assertEqual(1, len(metar.runways_info))
99+
self.assertEqual('24L', metar.runways_info[0].name)
100+
self.assertEqual(2400, metar.runways_info[0].min_range)
101+
self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit)
93102

94103
def test_parse_with_tempo(self):
95104
metar = MetarParser().parse(

0 commit comments

Comments
 (0)