geometry utils
returns true if a given linear ring is in clockwise order
def is_clockwise(pts): s = 0
for i in range(len(pts) - 1):
if 'x' in pts[i]:
x1 = pts[i].x
y1 = pts[i].y
x2 = pts[i + 1].x
y2 = pts[i + 1].y
else:
x1, y1 = pts[i]
x2, y2 = pts[i + 1]
s += (x2 - x1) * (y2 + y1)
return s >= 0def bbox_to_polygon(bbox):
from shapely.geometry import Polygon
s = bbox
poly = Polygon([(s.left, s.bottom), (s.left, s.top), (s.right, s.top), (s.right, s.bottom)])
return polydef geom_to_bbox(geom, min_area=0):
from kartograph.geometry import BBox
from shapely.geometry import MultiPolygon
if True or min_area == 0 or not isinstance(geom, MultiPolygon):if no minimum area ratio is set or the geometry is not a multipart geometry, we simply use the full bbox
minx, miny, maxx, maxy = geom.bounds
return BBox(width=maxx - minx, height=maxy - miny, left=minx, top=miny)
else:for multipart geometry we use only the bbox of the 'biggest' sub-geometries, depending on min_area
bbox = BBox()
areas = []
bb = []
for polygon in geom.geoms:
areas.append(polygon.area)
max_a = max(areas)
for i in range(len(geom.geoms)):
a = areas[i]
if a < max_a * min_area:ignore this sub polygon since it is too small
continue
bb.append(geom.geoms[i].bounds)
for b in bb:
bbox.update((b[0], b[2]))
bbox.update((b[1], b[2]))
bbox.update((b[0], b[3]))
bbox.update((b[1], b[3]))
return bboxjoins polygonal features
def join_features(features, props): from feature import MultiPolygonFeature
if len(features) == 0:
return features
joined = []
polygons = []
for feat in features:
if isinstance(feat, MultiPolygonFeature):
polygons.append(feat.geom)
else:
joined.append(feat) # cannot join this
polygons = filter(lambda x: x is not None, polygons)
if len(polygons) > 0:
poly = polygons[0]
for poly2 in polygons[1:]:
poly = poly.union(poly2)
joined.append(MultiPolygonFeature(poly, props))
return joined