Skip to content

Commit 1f78965

Browse files
authored
Merge pull request #26 from TaskarCenterAtUW/feature-2304
[Issue-2304] Preserve incline and infer climb during OSW to OSM conversion
2 parents 8ca11d5 + 13715c5 commit 1f78965

File tree

6 files changed

+102
-5
lines changed

6 files changed

+102
-5
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# Change log
22

3+
### 0.2.9
4+
- Retain existing `incline` and `climb` tags when converting OSW to OSM
5+
- Add `climb` tag when missing and `incline` is provided
6+
- Expanded unit tests for incline/climb handling
7+
38
### 0.2.8
49
- Fixed [BUG 2040](https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/2040)
5-
- Removing the width tag if the width is not float or integer
10+
- Removing the width tag if the width is not float or integer
611
- Added unit test cases
712

813
### 0.2.7

src/osm_osw_reformatter/serializer/osm/osm_normalizer.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,23 @@ def filter_tags(self, tags):
4040
tags.pop('_u_id', '')
4141
tags.pop('_v_id', '')
4242
tags.pop('_w_id', '')
43-
tags.pop('incline', '')
4443
tags.pop('length', '')
4544
if 'foot' in tags and tags['foot'] == 'yes' and 'highway' in tags and tags['highway'] in self.OSM_IMPLIED_FOOTWAYS:
4645
tags.pop('foot', '')
4746

4847
# OSW fields with similar OSM field names
49-
tags['incline'] = tags.pop('climb', '')
48+
if 'incline' in tags:
49+
try:
50+
incline_val = float(str(tags['incline']).rstrip('%'))
51+
except (ValueError, TypeError):
52+
incline_val = None
53+
else:
54+
tags['incline'] = str(incline_val)
55+
if 'climb' not in tags:
56+
if incline_val > 0:
57+
tags['climb'] = 'up'
58+
elif incline_val < 0:
59+
tags['climb'] = 'down'
5060

5161
self._check_datatypes(tags)
5262

src/osm_osw_reformatter/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.2.8'
1+
__version__ = '0.2.9'
1.28 MB
Binary file not shown.

tests/unit_tests/test_osw2osm/test_osw2osm.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.dirname(ROOT_DIR)), 'output')
88
TEST_ZIP_FILE = os.path.join(ROOT_DIR, 'test_files/osw.zip')
99
TEST_WIDTH_ZIP_FILE = os.path.join(ROOT_DIR, 'test_files/width-test.zip')
10+
TEST_DATA_WITH_INCLINE_ZIP_FILE = os.path.join(ROOT_DIR, 'test_files/dataset_with_incline.zip')
1011

1112

1213
class TestOSW2OSM(unittest.IsolatedAsyncioTestCase):
@@ -64,6 +65,46 @@ async def test_convert_error(self):
6465
result = osw2osm.convert()
6566
self.assertFalse(result.status)
6667

68+
def test_generated_file_contains_climb_tag(self):
69+
zip_file = TEST_DATA_WITH_INCLINE_ZIP_FILE
70+
osw2osm = OSW2OSM(zip_file_path=zip_file, workdir=OUTPUT_DIR, prefix='test')
71+
result = osw2osm.convert()
72+
xml_file_path = result.generated_files
73+
74+
tree = ET.parse(xml_file_path)
75+
root = tree.getroot()
76+
self.assertGreater(len(root.findall(".//tag[@k='climb']")), 0)
77+
78+
os.remove(result.generated_files)
79+
80+
def test_generated_file_contains_incline_tag(self):
81+
zip_file = TEST_DATA_WITH_INCLINE_ZIP_FILE
82+
osw2osm = OSW2OSM(zip_file_path=zip_file, workdir=OUTPUT_DIR, prefix='test')
83+
result = osw2osm.convert()
84+
xml_file_path = result.generated_files
85+
86+
tree = ET.parse(xml_file_path)
87+
root = tree.getroot()
88+
self.assertGreater(len(root.findall(".//tag[@k='incline']")), 0)
89+
90+
os.remove(result.generated_files)
91+
92+
def test_incline_tags_have_climb(self):
93+
zip_file = TEST_DATA_WITH_INCLINE_ZIP_FILE
94+
osw2osm = OSW2OSM(zip_file_path=zip_file, workdir=OUTPUT_DIR, prefix='test')
95+
result = osw2osm.convert()
96+
xml_file_path = result.generated_files
97+
98+
tree = ET.parse(xml_file_path)
99+
root = tree.getroot()
100+
101+
for element in root.findall('.//way') + root.findall('.//node') + root.findall('.//relation'):
102+
tags = {tag.get('k'): tag.get('v') for tag in element.findall('tag')}
103+
if 'incline' in tags and float(tags.get('incline', 0) or 0) != 0:
104+
self.assertIn('climb', tags)
105+
106+
os.remove(result.generated_files)
107+
67108

68109
if __name__ == '__main__':
69110
unittest.main()

tests/unit_tests/test_serializer/test_osm_normalizer.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,45 @@ def test_preserves_width_when_value_is_float_with_string(self):
4848
self.assertIsInstance(normalizer, dict)
4949
self.assertIn('highway', normalizer)
5050
self.assertIn('width', normalizer)
51-
self.assertEqual(normalizer['width'], '1.525')
51+
self.assertEqual(normalizer['width'], '1.525')
52+
53+
54+
class TestOSMNormalizeInclineField(unittest.TestCase):
55+
def setUp(self):
56+
self.normalizer = OSMNormalizer()
57+
58+
def test_retains_existing_incline_and_climb(self):
59+
tags = {"highway": "footway", "incline": 0.014, "climb": "up"}
60+
normalizer = self.normalizer.filter_tags(tags)
61+
self.assertEqual(normalizer["incline"], "0.014")
62+
self.assertEqual(normalizer["climb"], "up")
63+
64+
def test_derives_climb_from_positive_incline(self):
65+
tags = {"highway": "footway", "incline": 0.014}
66+
normalizer = self.normalizer.filter_tags(tags)
67+
self.assertEqual(normalizer["climb"], "up")
68+
self.assertEqual(normalizer["incline"], "0.014")
69+
70+
def test_derives_climb_from_negative_incline(self):
71+
tags = {"highway": "footway", "incline": -0.014}
72+
normalizer = self.normalizer.filter_tags(tags)
73+
self.assertEqual(normalizer["climb"], "down")
74+
self.assertEqual(normalizer["incline"], "-0.014")
75+
76+
def test_does_not_derive_climb_from_zero_incline(self):
77+
tags = {"highway": "footway", "incline": 0}
78+
normalizer = self.normalizer.filter_tags(tags)
79+
self.assertEqual(normalizer["incline"], "0.0")
80+
self.assertNotIn("climb", normalizer)
81+
82+
def test_retains_climb_without_incline(self):
83+
tags = {"highway": "footway", "climb": "down"}
84+
normalizer = self.normalizer.filter_tags(tags)
85+
self.assertEqual(normalizer["climb"], "down")
86+
self.assertNotIn("incline", normalizer)
87+
88+
def test_retains_non_numeric_incline_without_climb(self):
89+
tags = {"highway": "footway", "incline": "steep"}
90+
normalizer = self.normalizer.filter_tags(tags)
91+
self.assertEqual(normalizer["incline"], "steep")
92+
self.assertNotIn("climb", normalizer)

0 commit comments

Comments
 (0)