Skip to content

Commit

Permalink
Check that building height is in a sensible range.
Browse files Browse the repository at this point in the history
Sometimes, data that doesn't make sense gets into OSM. For example, version 4 of [this building](https://www.openstreetmap.org/way/290535940) has `height=5e+70`, which is many orders of magnitude larger than the observable universe. Clearly this is a typo and causes problems for us when we try to write it out in tiles.

This patch drops values outside a sensible range, which is approximately that of the tallest current structure, the Burj Khalifa.
  • Loading branch information
zerebubuth committed Mar 1, 2019
1 parent 4ffd95a commit f0a4eba
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
19 changes: 19 additions & 0 deletions test/test_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -1039,3 +1039,22 @@ def test_hole(self):

def test_filled_hole(self):
self._check(set([1, 2, 3, 4]), 5)


class BuildingHeightCalculation(unittest.TestCase):

def test_nonsense_height(self):
# test that a nonsensically large value for a height input
# doesn't get returned in the output.
from vectordatasource.transform import _building_calc_height
from vectordatasource.transform import _building_calc_levels
height = _building_calc_height('1e6', None, _building_calc_levels)
self.assertIsNone(height)

def test_nonsense_levels(self):
# test that a nonsensically large value for the number of levels in
# a building doesn't get into the output.
from vectordatasource.transform import _building_calc_height
from vectordatasource.transform import _building_calc_levels
height = _building_calc_height(None, '1000', _building_calc_levels)
self.assertIsNone(height)
13 changes: 11 additions & 2 deletions vectordatasource/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,24 @@ def _building_calc_min_levels(min_levels):
return min_levels


# slightly bigger than the tallest structure in the world. at the time
# of writing, the Burj Khalifa at 829.8m. this is used as a check to make
# sure that nonsense values (e.g: buildings a million meters tall) don't
# make it into the data.
TALLEST_STRUCTURE_METERS = 1000.0


def _building_calc_height(height_val, levels_val, levels_calc_fn):
height = _to_float_meters(height_val)
if height is not None:
if height is not None and 0 <= height <= TALLEST_STRUCTURE_METERS:
return height
levels = _to_float_meters(levels_val)
if levels is None:
return None
levels = levels_calc_fn(levels)
return levels
if 0 <= levels <= TALLEST_STRUCTURE_METERS:
return levels
return None


def add_id_to_properties(shape, properties, fid, zoom):
Expand Down

0 comments on commit f0a4eba

Please sign in to comment.