utils.py

#

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 >= 0
#
def 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 poly
#
def 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 bbox
#

joins 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