Skip to content

Commit

Permalink
Merge pull request #1972 from tilezen/dees/protect-against-large-park…
Browse files Browse the repository at this point in the history
…ing-lots

Protect against abnormally large parking lots
  • Loading branch information
iandees committed Sep 3, 2021
2 parents e539e86 + 94e0755 commit 15a8fb3
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
12 changes: 9 additions & 3 deletions data/functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1071,14 +1071,20 @@ DECLARE
levels_int INTEGER;
spaces_per_level INTEGER;
BEGIN
-- if the capacity is set, then use that.
IF capacity ~ '^[0-9]+$' THEN
-- if the capacity is set to something between 0 and 99999, then use that.
IF capacity ~ '^[0-9]{1,5}$' THEN
RETURN capacity::integer;
END IF;
-- don't try to do this if way_area is abnormally large.
-- (Epcot's parking lot is 647k m^2)
IF way_area > 2000000 THEN
RETURN NULL;
END IF;
-- otherwise, try to use the information we have to guess the capacity
spaces_per_level := (way_area / 46.0)::integer;
levels_int := CASE
WHEN levels ~ '^[0-9]+$' THEN levels::integer
-- limit levels to an integer between 0 and 99
WHEN levels ~ '^[0-9]{1,2}$' THEN levels::integer
WHEN parking = 'multi-storey' THEN 2
ELSE 1
END;
Expand Down
34 changes: 34 additions & 0 deletions integration-test/1972-big-parking-lots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- encoding: utf-8 -*-
import dsl
from shapely.wkt import loads as wkt_loads
from tilequeue.tile import deg2num
from . import FixtureTest


def _tile_centre(z, x, y):
from tilequeue.tile import num2deg
lat, lon = num2deg(x + 0.5, y + 0.5, z)
return (lon, lat)


class BigParkingLotsTest(FixtureTest):

def test_osm_big_parking_capacity(self):
lon, lat = (8.9140471, 48.8352716)
self.generate_fixtures(
dsl.point(8712714905, (lon, lat), {
u"amenity": u"parking",
u"capacity": u"6472217472217",
u"parking": u"surface",
u"source": u"openstreetmap.org",
})
)

x, y = deg2num(lat, lon, 16)
self.assert_has_feature(
16, x, y, 'pois', {
'id': 8712714905,
'kind': 'parking',
'min_zoom': 18,
'source': u'openstreetmap.org',
})
13 changes: 13 additions & 0 deletions test/test_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,19 @@ def test_feature(self):
out_min_zoom = self.pois.fn(shape, props, None, meta)
self.assertEquals(16, out_min_zoom)

def test_large_parking_capacity(self):
import shapely.geometry
shape = shapely.geometry.Point(0, 0)
props = {
'amenity': 'parking',
'capacity': '6472217472217',
'parking': 'surface',
}
meta = make_test_metadata()
out_min_zoom = self.pois.fn(shape, props, None, meta)
# An unbelievably big capacity should default to a high min_zoom
self.assertEquals(18, out_min_zoom)


class RoadsMinZoomTest(unittest.TestCase):

Expand Down
15 changes: 15 additions & 0 deletions vectordatasource/meta/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,13 +407,24 @@ def tz_estimate_parking_capacity(capacity, parking, levels, way_area):
try:
# if the tags tell us what capacity is, then we should respect that.
capacity = int(capacity)

# don't allow abnormally large capacity values
# (West Edmonton mall has 20k spaces)
if capacity > 99999:
return None

return capacity

except (ValueError, TypeError):
# sometimes people don't put integers in the capacity, which is kind of
# annoying. it means we just have to fall back to estimating.
pass

# don't try to do this if way_area is abnormally large
# (Epcot's parking lot is 647k m^2)
if way_area > 2000000:
return None

# estimate capacity based on way area fitting. looks like roughly 46 square
# mercator meters per space?
spaces_per_level = int(way_area / 46.0)
Expand All @@ -431,6 +442,10 @@ def tz_estimate_parking_capacity(capacity, parking, levels, way_area):
# mainly surface, but also other types such as "underground"
levels = 1

# don't allow abnormally large levels values
if levels > 99:
return None

capacity = spaces_per_level * levels

# if we get a silly answer, don't set that - just return None to indicate
Expand Down

0 comments on commit 15a8fb3

Please sign in to comment.