Skip to content

Commit 7d47872

Browse files
authored
Merge pull request #368 from tilezen/zerebubuth/fix-boundaries-orient-multipolygon
Add utility function to orient MultiPolygons.
2 parents 58f6398 + da716aa commit 7d47872

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

tests/test_query_rawr.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,48 @@ def _tile_triangle(bounds):
820820
# check no area
821821
self.assertIsNone(props.get('area'))
822822

823+
def test_boundaries_from_multipolygons(self):
824+
# check that the boundary extraction code also works for multipolygons
825+
from shapely.geometry import Polygon, MultiPolygon
826+
827+
def _tile_squares(bounds):
828+
# maxy +----+
829+
# | b |
830+
# midy +----+----+
831+
# | a |
832+
# miny +----+
833+
# minx midx maxx
834+
835+
minx, miny, maxx, maxy = bounds
836+
midx = 0.5 * (minx + maxx)
837+
midy = 0.5 * (miny + maxy)
838+
839+
a = Polygon([
840+
[minx, miny],
841+
[minx, midy],
842+
[midx, midy],
843+
[midx, miny],
844+
[minx, miny],
845+
])
846+
847+
b = Polygon([
848+
[midx, midy],
849+
[midx, maxy],
850+
[maxx, maxy],
851+
[maxx, midy],
852+
[midy, midy],
853+
])
854+
855+
return MultiPolygon([a, b])
856+
857+
read_rows = self._fetch_data(_tile_squares, 'planet_osm_polygon')
858+
859+
self.assertEqual(len(read_rows), 1)
860+
props = read_rows[0]['__boundaries_properties__']
861+
self.assertEqual(props.get('boundary'), 'administrative')
862+
# check no area
863+
self.assertIsNone(props.get('area'))
864+
823865

824866
class TestBufferedLand(RawrTestCase):
825867

tilequeue/query/rawr.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from collections import namedtuple, defaultdict
22
from shapely.geometry import box
33
from shapely.geometry import MultiLineString
4+
from shapely.geometry import MultiPolygon
45
from shapely.geometry.polygon import orient
56
from shapely.wkb import loads as wkb_loads
67
from tilequeue.query.common import layer_properties
@@ -612,6 +613,25 @@ def _lines_only(shape):
612613
return MultiLineString(lines)
613614

614615

616+
def _orient(shape):
617+
"""
618+
The Shapely version of the orient function appears to only work on
619+
Polygons, and fails on MultiPolygons. This is a quick wrapper to allow
620+
orienting of either.
621+
"""
622+
623+
assert shape.geom_type in ('Polygon', 'MultiPolygon')
624+
625+
if shape.geom_type == 'Polygon':
626+
return orient(shape)
627+
628+
else:
629+
polys = []
630+
for geom in shape.geoms:
631+
polys.append(orient(geom))
632+
return MultiPolygon(polys)
633+
634+
615635
class RawrTile(object):
616636

617637
def __init__(self, layers, tables, tile_pyramid, label_placement_layers,
@@ -757,7 +777,7 @@ def _parse_row(self, zoom, unpadded_bounds, bbox, source, fid, shape,
757777
# make sure boundary rings are oriented in the correct
758778
# direction; anti-clockwise for outers and clockwise for
759779
# inners, which means the interior should be on the left.
760-
boundaries_shape = orient(shape).boundary
780+
boundaries_shape = _orient(shape).boundary
761781

762782
# make sure it's only lines, post-intersection. a polygon-line
763783
# intersection can return points as well as lines. however,

0 commit comments

Comments
 (0)