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']
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