Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Change log

### 0.2.10
- Removed `climb` tag generation from OSM normalizer

### 0.2.9
- Retain existing `incline` and `climb` tags when converting OSW to OSM
- Add `climb` tag when missing and `incline` is provided
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ networkx~=3.2
shapely~=2.0.2
pyproj~=3.6.1
coverage~=7.5.1
ogr2osm==1.2.0
ogr2osm==1.2.0
python-osw-validation==0.2.13
11 changes: 5 additions & 6 deletions src/osm_osw_reformatter/serializer/osm/osm_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,17 @@ def filter_tags(self, tags):
tags.pop('foot', '')

# OSW fields with similar OSM field names
if 'climb' in tags:
if tags.get('highway') != 'steps' or tags['climb'] not in ('up', 'down'):
tags.pop('climb', '')

if 'incline' in tags:
try:
incline_val = float(str(tags['incline']).rstrip('%'))
except (ValueError, TypeError):
incline_val = None
pass
else:
tags['incline'] = str(incline_val)
if 'climb' not in tags:
if incline_val > 0:
tags['climb'] = 'up'
elif incline_val < 0:
tags['climb'] = 'down'

self._check_datatypes(tags)

Expand Down
2 changes: 1 addition & 1 deletion src/osm_osw_reformatter/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.2.9'
__version__ = '0.2.10'
Empty file.
38 changes: 38 additions & 0 deletions tests/unit_tests/test_osm_compliance/test_osm_compliance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import os
import json
import zipfile
import unittest
from python_osw_validation import OSWValidation

from src.osm_osw_reformatter.osw2osm.osw2osm import OSW2OSM
from src.osm_osw_reformatter import Formatter

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OUTPUT_DIR = os.path.join(os.path.dirname(os.path.dirname(ROOT_DIR)), 'output')
TEST_DATA_WITH_INCLINE_ZIP_FILE = os.path.join(ROOT_DIR, 'test_files/dataset_with_incline.zip')


class TestOSMCompliance(unittest.IsolatedAsyncioTestCase):
async def test_output_is_osm_compliant(self):
osw2osm = OSW2OSM(zip_file_path=TEST_DATA_WITH_INCLINE_ZIP_FILE, workdir=OUTPUT_DIR, prefix='compliance')
result = osw2osm.convert()
osm_file = result.generated_files

formatter = Formatter(workdir=OUTPUT_DIR, file_path=osm_file, prefix='compliance')
res = await formatter.osm2osw()
osw_files = res.generated_files

zip_path = os.path.join(OUTPUT_DIR, 'compliance_osw.zip')
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for f in osw_files:
zipf.write(f, os.path.basename(f))

validator = OSWValidation(zipfile_path=zip_path)
result = validator.validate()
self.assertEqual(len(result.issues), 0, f'OSW Validation issues: {json.dumps(result.issues)}')

os.remove(osm_file)
for f in osw_files:
os.remove(f)
os.remove(zip_path)
formatter.cleanup()
8 changes: 4 additions & 4 deletions tests/unit_tests/test_osw2osm/test_osw2osm.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ async def test_convert_error(self):
result = osw2osm.convert()
self.assertFalse(result.status)

def test_generated_file_contains_climb_tag(self):
def test_generated_file_does_not_contain_climb_tag(self):
zip_file = TEST_DATA_WITH_INCLINE_ZIP_FILE
osw2osm = OSW2OSM(zip_file_path=zip_file, workdir=OUTPUT_DIR, prefix='test')
result = osw2osm.convert()
xml_file_path = result.generated_files

tree = ET.parse(xml_file_path)
root = tree.getroot()
self.assertGreater(len(root.findall(".//tag[@k='climb']")), 0)
self.assertEqual(len(root.findall(".//tag[@k='climb']")), 0)

os.remove(result.generated_files)

Expand All @@ -89,7 +89,7 @@ def test_generated_file_contains_incline_tag(self):

os.remove(result.generated_files)

def test_incline_tags_have_climb(self):
def test_incline_tags_do_not_have_climb(self):
zip_file = TEST_DATA_WITH_INCLINE_ZIP_FILE
osw2osm = OSW2OSM(zip_file_path=zip_file, workdir=OUTPUT_DIR, prefix='test')
result = osw2osm.convert()
Expand All @@ -101,7 +101,7 @@ def test_incline_tags_have_climb(self):
for element in root.findall('.//way') + root.findall('.//node') + root.findall('.//relation'):
tags = {tag.get('k'): tag.get('v') for tag in element.findall('tag')}
if 'incline' in tags and float(tags.get('incline', 0) or 0) != 0:
self.assertIn('climb', tags)
self.assertNotIn('climb', tags)

os.remove(result.generated_files)

Expand Down
36 changes: 27 additions & 9 deletions tests/unit_tests/test_serializer/test_osm_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,38 +55,56 @@ class TestOSMNormalizeInclineField(unittest.TestCase):
def setUp(self):
self.normalizer = OSMNormalizer()

def test_retains_existing_incline_and_climb(self):
def test_removes_existing_climb_and_retains_incline(self):
tags = {"highway": "footway", "incline": 0.014, "climb": "up"}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["incline"], "0.014")
self.assertEqual(normalizer["climb"], "up")
self.assertNotIn("climb", normalizer)

def test_derives_climb_from_positive_incline(self):
def test_does_not_add_climb_from_positive_incline(self):
tags = {"highway": "footway", "incline": 0.014}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["climb"], "up")
self.assertNotIn("climb", normalizer)
self.assertEqual(normalizer["incline"], "0.014")

def test_derives_climb_from_negative_incline(self):
def test_does_not_add_climb_from_negative_incline(self):
tags = {"highway": "footway", "incline": -0.014}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["climb"], "down")
self.assertNotIn("climb", normalizer)
self.assertEqual(normalizer["incline"], "-0.014")

def test_does_not_derive_climb_from_zero_incline(self):
def test_does_not_add_climb_from_zero_incline(self):
tags = {"highway": "footway", "incline": 0}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["incline"], "0.0")
self.assertNotIn("climb", normalizer)

def test_retains_climb_without_incline(self):
def test_removes_climb_without_incline(self):
tags = {"highway": "footway", "climb": "down"}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["climb"], "down")
self.assertNotIn("climb", normalizer)
self.assertNotIn("incline", normalizer)

def test_retains_non_numeric_incline_without_climb(self):
tags = {"highway": "footway", "incline": "steep"}
normalizer = self.normalizer.filter_tags(tags)
self.assertEqual(normalizer["incline"], "steep")
self.assertNotIn("climb", normalizer)

def test_retains_climb_when_highway_is_steps(self):
tags = {"highway": "steps", "climb": "up"}
normalizer = self.normalizer.filter_tags(tags)
self.assertIn("climb", normalizer)
self.assertEqual(normalizer["climb"], "up")
self.assertNotIn("incline", normalizer)

def test_retains_climb_down_when_highway_is_steps(self):
tags = {"highway": "steps", "climb": "down"}
normalizer = self.normalizer.filter_tags(tags)
self.assertIn("climb", normalizer)
self.assertEqual(normalizer["climb"], "down")

def test_discards_invalid_climb_when_highway_is_steps(self):
tags = {"highway": "steps", "climb": "sideways"}
normalizer = self.normalizer.filter_tags(tags)
self.assertNotIn("climb", normalizer)
Loading