diff --git a/metar_taf_parser/command/metar.py b/metar_taf_parser/command/metar.py index faeaa98..cd97fe8 100644 --- a/metar_taf_parser/command/metar.py +++ b/metar_taf_parser/command/metar.py @@ -2,7 +2,7 @@ from metar_taf_parser.commons import converter from metar_taf_parser.commons.exception import ParseError -from metar_taf_parser.model.enum import DepositType, DepositCoverage +from metar_taf_parser.model.enum import DepositType, DepositCoverage, LengthUnit from metar_taf_parser.model.model import RunwayInfo, Metar from metar_taf_parser.commons.i18n import _ @@ -42,11 +42,16 @@ def execute(self, metar: Metar, input: str): metar.altimeter = int(converter.convert_inches_mercury_to_pascal(mercury)) +def _parse_runway_unit(input: str): + return LengthUnit.FEET if input == 'FT' else LengthUnit.METERS + + def _parse_runway(matches, metar, runway): runway.name = matches[0][0] runway.indicator = matches[0][1] runway.min_range = int(matches[0][2]) runway.trend = matches[0][3] + runway.unit = _parse_runway_unit(matches[0][4]) metar.add_runway_info(runway) @@ -55,6 +60,7 @@ def _parse_runway_max_range(matches, metar, runway): runway.min_range = int(matches[0][1]) runway.max_range = int(matches[0][2]) runway.trend = matches[0][3] + runway.unit = _parse_runway_unit(matches[0][4]) metar.add_runway_info(runway) diff --git a/metar_taf_parser/model/enum.py b/metar_taf_parser/model/enum.py index c9de352..4642b06 100644 --- a/metar_taf_parser/model/enum.py +++ b/metar_taf_parser/model/enum.py @@ -61,6 +61,17 @@ def __repr__(self): return _('DepositType.' + self.name) +class LengthUnit(enum.Enum): + METERS = 'M' + FEET = 'FT' + + def __str__(self): + return self.value + + def __repr__(self): + return self.value + + class Descriptive(enum.Enum): SHOWERS = 'SH' SHALLOW = 'MI' diff --git a/metar_taf_parser/model/model.py b/metar_taf_parser/model/model.py index 02651a0..83c908b 100644 --- a/metar_taf_parser/model/model.py +++ b/metar_taf_parser/model/model.py @@ -211,6 +211,7 @@ def __init__(self): self._name = None self._min_range = None self._max_range = None + self._unit = None self._trend = None self._indicator = None self._deposit_type = None @@ -236,6 +237,12 @@ def _get_max_range(self): def _set_max_range(self, value): self._max_range = value + def _get_unit(self): + return self._unit + + def _set_unit(self, value): + self._unit = value + def _get_trend(self): return self._trend @@ -273,13 +280,14 @@ def _set_braking_capacity(self, value): self._braking_capacity = value def __repr__(self): - return f'RunwayInfo[name={self.name}, min_range={self.min_range}, max_range={self.max_range}, '\ + return f'RunwayInfo[name={self.name}, min_range={self.min_range}, max_range={self.max_range}, unit={self.unit}, '\ f'trend={self.trend}, indicator={self.indicator}, deposit_type={self.deposit_type}, '\ f'coverage={self.coverage}, thickness={self.thickness}, braking_capacity={self.braking_capacity}]'\ name = property(_get_name, _set_name) min_range = property(_get_min_range, _set_min_range) max_range = property(_get_max_range, _set_max_range) + unit = property(_get_unit, _set_unit) trend = property(_get_trend, _set_trend) indicator = property(_get_indicator, _set_indicator) deposit_type = property(_get_deposit_type, _set_deposit_type) diff --git a/metar_taf_parser/tests/command/test_metar.py b/metar_taf_parser/tests/command/test_metar.py index 126fdf2..a0786a3 100644 --- a/metar_taf_parser/tests/command/test_metar.py +++ b/metar_taf_parser/tests/command/test_metar.py @@ -2,7 +2,7 @@ from metar_taf_parser.command.metar import RunwayCommand, CommandSupplier from metar_taf_parser.commons.exception import ParseError -from metar_taf_parser.model.enum import DepositType, DepositCoverage +from metar_taf_parser.model.enum import DepositType, DepositCoverage, LengthUnit from metar_taf_parser.model.model import Metar from metar_taf_parser.commons.i18n import _ @@ -20,6 +20,7 @@ def test_runway_command_execute(self): self.assertEqual('26', runway_info.name) self.assertEqual(600, runway_info.min_range) self.assertEqual('U', runway_info.trend) + self.assertEqual(LengthUnit.METERS, runway_info.unit) def test_runway_command_execute_runway(self): metar = Metar() @@ -34,6 +35,7 @@ def test_runway_command_execute_runway(self): self.assertEqual(550, runway_info.min_range) self.assertEqual(700, runway_info.max_range) self.assertEqual('U', runway_info.trend) + self.assertEqual(LengthUnit.METERS, runway_info.unit) def test_runway_command_execute_wrong_runway(self): metar = Metar() @@ -54,6 +56,7 @@ def test_parse_runwway_visual_range_feet_variable(self): self.assertEqual(600, metar.runways_info[0].min_range) self.assertEqual(1000, metar.runways_info[0].max_range) self.assertEqual('', metar.runways_info[0].trend) + self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit) def test_parse_runway_visual_range_feet_simple(self): metar = Metar() @@ -65,6 +68,7 @@ def test_parse_runway_visual_range_feet_simple(self): self.assertEqual('01L', metar.runways_info[0].name) self.assertEqual(800, metar.runways_info[0].min_range) self.assertEqual('', metar.runways_info[0].trend) + self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit) def test_parse_runway_deposit(self): metar = Metar() @@ -101,6 +105,7 @@ def test_parse_runway_with_less_than_indicator_and_unit(self): self.assertEqual('01L', metar.runways_info[0].name) self.assertEqual('M', metar.runways_info[0].indicator) self.assertEqual(600, metar.runways_info[0].min_range) + self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit) def test_parse_runway_with_greater_than_indicator(self): metar = Metar() @@ -108,6 +113,7 @@ def test_parse_runway_with_greater_than_indicator(self): self.assertEqual('01L', metar.runways_info[0].name) self.assertEqual('P', metar.runways_info[0].indicator) self.assertEqual(600, metar.runways_info[0].min_range) + self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit) def test_parse_runway_missing_info(self): metar = Metar() diff --git a/metar_taf_parser/tests/parser/test_parser.py b/metar_taf_parser/tests/parser/test_parser.py index 88c9c29..97b3856 100644 --- a/metar_taf_parser/tests/parser/test_parser.py +++ b/metar_taf_parser/tests/parser/test_parser.py @@ -3,7 +3,7 @@ from parameterized import parameterized from metar_taf_parser.model.enum import Intensity, Phenomenon, Descriptive, DepositType, DepositCoverage, WeatherChangeType, CloudQuantity, CloudType, \ - TimeIndicator, TurbulenceIntensity, IcingIntensity + TimeIndicator, TurbulenceIntensity, IcingIntensity, LengthUnit from metar_taf_parser.model.model import AbstractWeatherContainer, Visibility, Wind from metar_taf_parser.parser.parser import AbstractParser, MetarParser, _parse_validity, _parse_temperature, TAFParser, \ RemarkParser @@ -90,6 +90,15 @@ def test_parse(self): self.assertEqual('27L', metar.runways_info[0].name) self.assertEqual(375, metar.runways_info[0].min_range) self.assertEqual('N', metar.runways_info[0].trend) + self.assertEqual(LengthUnit.METERS, metar.runways_info[0].unit) + + def test_parse_with_runway_visual_range_in_feet(self): + metar = MetarParser().parse('KJFK 121651Z 18012KT 9999 R24L/2400FT SCT015 18/12 A2992') + + self.assertEqual(1, len(metar.runways_info)) + self.assertEqual('24L', metar.runways_info[0].name) + self.assertEqual(2400, metar.runways_info[0].min_range) + self.assertEqual(LengthUnit.FEET, metar.runways_info[0].unit) def test_parse_with_tempo(self): metar = MetarParser().parse(