Repository: python-metar/python-metar

Issue:
Feet vs. Meters
This METAR has R28L/2600FT but reduction reads:

visual range: on runway 28L, 2600 meters
(should read: visual range: on runway 28L, 2600 feet)

Reference: METAR KPIT 091955Z COR 22015G25KT 3/4SM R28L/2600FT TSRA OVC010CB 18/16 A2992 RMK SLP045 T01820159

Comments:

Patch:
diff --git a/MANIFEST b/MANIFEST
deleted file mode 100644
index 4de8082..0000000
--- a/MANIFEST
+++ /dev/null
@@ -1,19 +0,0 @@
-README
-CHANGES
-NOTES
-LICENSE
-get_report.py
-parse_metar.py
-sample.py
-setup.py
-metar/Datatypes.py
-metar/Metar.py
-metar/__init__.py
-test/all_tests.py
-test/test_direction.py
-test/test_distance.py
-test/test_metar.py
-test/test_precipitation.py
-test/test_pressure.py
-test/test_speed.py
-test/test_temperature.py
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..bbb2df3
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,5 @@
+include README.md
+include CHANGES
+include NOTES
+include LICENSE
+recursive-include test *.py
diff --git a/metar/Metar.py b/metar/Metar.py
index 0e773cb..338e172 100755
--- a/metar/Metar.py
+++ b/metar/Metar.py
@@ -587,7 +587,7 @@ class Metar(object):
               self.vis_dir = direction(vis_dir)
           self.vis = distance(vis_dist, vis_units, vis_less)
                           
-  def _handleRunway( self, d ):
+  def _handleRunway(self, d):
       """
       Parse a runway visual range group.
       
@@ -596,15 +596,17 @@ class Metar(object):
           . name  [string]
           . low   [distance]
           . high  [distance]
-      """
-      if d['name']:
-          name = d['name']
-          low = distance(d['low'])
-          if d['high']:
-              high = distance(d['high'])
-          else:
-              high = low
-          self.runway.append((name,low,high))
+          . unit  [string]
+      """
+      if d['name'] is None:
+          return
+      unit = d['unit'] if d['unit'] is not None else 'FT'
+      low = distance(d['low'], unit)
+      if d['high'] is None:
+          high = low
+      else:
+          high = distance(d['high'], unit)
+      self.runway.append([d['name'], low, high, unit])
                           
   def _handleWeather( self, d ):
       """
@@ -1119,16 +1121,23 @@ class Metar(object):
               text += "; %s" % self.max_vis.string(units)
       return text
   
-  def runway_visual_range( self, units=None ):
+  def runway_visual_range(self, units=None):
       """
       Return a textual description of the runway visual range.
       """
       lines = []
-      for name,low,high in self.runway:
+      for name, low, high, unit in self.runway:
+          reportunits = unit if units is None else units
           if low != high:
-              lines.append("on runway %s, from %d to %s" % (name, low.value(units), high.string(units)))
+              lines.append(
+                  ("on runway %s, from %d to %s"
+                   ) % (name, low.value(reportunits),
+                        high.string(reportunits))
+              )
           else:
-              lines.append("on runway %s, %s" % (name, low.string(units)))
+              lines.append(
+                  "on runway %s, %s" % (name, low.string(reportunits))
+              )
       return "; ".join(lines)
   
   def present_weather( self ):
diff --git a/setup.py b/setup.py
index af7cfab..2ce9dfd 100755
--- a/setup.py
+++ b/setup.py
@@ -36,6 +36,7 @@ setup(
     long_description=LONG_DESCRIPTION,
     license="MIT",
     packages=["metar"],
+    package_data={'metar': ['nsd_cccc.txt', ]},
     platforms="Python 2.5 and later.",
     classifiers=[
         "Development Status :: 5 - Production/Stable",


Test patch:
diff --git a/test/test_metar.py b/test/test_metar.py
index 76147e1..e6c8fee 100644
--- a/test/test_metar.py
+++ b/test/test_metar.py
@@ -17,6 +17,17 @@ class MetarTest(unittest.TestCase):
   def raisesParserError(self, code):
     self.assertRaises(Metar.ParserError, Metar.Metar, code )
 
+  def test_issue40_runwayunits(self):
+    """Check reported units on runway visual range."""
+    report = Metar.Metar(
+      "METAR KPIT 091955Z COR 22015G25KT 3/4SM R28L/2600FT TSRA OVC010CB "
+      "18/16 A2992 RMK SLP045 T01820159"
+    )
+    res = report.runway_visual_range()
+    self.assertEquals(res, 'on runway 28L, 2600 feet')
+    res = report.runway_visual_range('M')
+    self.assertTrue(res, 'on runway 28L, 792 meters')
+
   def test_010_parseType_default(self):
     """Check default value of the report type."""
     self.assertEqual( Metar.Metar("KEWR").type, "METAR" )