예제 #1
0
def triangulate_polygon(polygon,
                        triangle_args=None,
                        engine=None,
                        **kwargs):
    """
    Given a shapely polygon create a triangulation using a
    python interface to `triangle.c` or mapbox-earcut.
    > pip install triangle
    > pip install mapbox_earcut

    Parameters
    ---------
    polygon : Shapely.geometry.Polygon
        Polygon object to be triangulated
    triangle_args : str or None
        Passed to triangle.triangulate i.e: 'p', 'pq30'
    engine : None or str
      Any value other than 'earcut' will use `triangle`

    Returns
    --------------
    vertices : (n, 2) float
       Points in space
    faces : (n, 3) int
       Index of vertices that make up triangles
    """
    if engine == 'earcut':
        from mapbox_earcut import triangulate_float64

        # get vertices as sequence where exterior is the first value
        vertices = [np.array(polygon.exterior)]
        vertices.extend(np.array(i) for i in polygon.interiors)
        # record the index from the length of each vertex array
        rings = np.cumsum([len(v) for v in vertices])
        # stack vertices into (n, 2) float array
        vertices = np.vstack(vertices)
        # run triangulation
        faces = triangulate_float64(vertices, rings).reshape(
            (-1, 3)).astype(np.int64).reshape((-1, 3))

        return vertices, faces

    # do the import here for soft requirement
    from triangle import triangulate
    # set default triangulation arguments if not specified
    if triangle_args is None:
        triangle_args = 'p'
    # turn the polygon in to vertices, segments, and hole points
    arg = _polygon_to_kwargs(polygon)
    # run the triangulation
    result = triangulate(arg, triangle_args)

    return result['vertices'], result['triangles']
예제 #2
0
def triangulatePolygon_mapbox(polygon):
    import mapbox_earcut
    vertices, rings = [], []
    ring = polygon.exterior.coords[:
                                   -1]  # despite 'ring' name, actually need a chain
    vertices.extend(ring)
    rings.append(len(vertices))
    for interior in polygon.interiors:
        ring = interior.coords[:-1]
        vertices.extend(ring)
        rings.append(len(vertices))
    vertices = np.array(vertices, dtype=np.float64)
    rings = np.array(rings)
    result = mapbox_earcut.triangulate_float64(vertices, rings)

    triangles = []
    points = vertices[result]
    its = [iter(points)] * 3
    for triple in zip(*its):
        triangles.append(shapely.geometry.Polygon(triple))
    return triangles