def geos_multilinestring_from_py(ob): # ob must be either a MultiLineString, a sequence, or # array of sequences or arrays if isinstance(ob, MultiLineString): return geos_geom_from_py(ob) obs = getattr(ob, 'geoms', ob) L = len(obs) assert L >= 1 exemplar = obs[0] try: N = len(exemplar[0]) except TypeError: N = exemplar._ndim if N not in (2, 3): raise ValueError("Invalid coordinate dimensionality") # Array of pointers to point geometries subs = (c_void_p * L)() # add to coordinate sequence for l in range(L): geom, ndims = linestring.geos_linestring_from_py(obs[l]) subs[l] = cast(geom, c_void_p) return lgeos.GEOSGeom_createCollection(5, subs, L), N
def geos_multipolygon_from_polygons(arg): """Creates a GEOS multipolygon from a sequence of polygon-like objects. Parameters ---------- arg : sequence or MultiPolygon Returns ------- int Pointer to a GEOS multipolygon. """ if isinstance(arg, MultiPolygon): return geos_geom_from_py(arg) obs = getattr(arg, 'geoms', arg) obs = [ ob for ob in obs if ob and not (isinstance(ob, polygon.Polygon) and ob.is_empty) ] L = len(obs) # Bail immediately if we have no input points. if L <= 0: return (lgeos.GEOSGeom_createEmptyCollection(6), 3) # This function does not accept sequences of MultiPolygons: there is # no implicit flattening. if isinstance(obs[0], MultiPolygon): raise ValueError("Sequences of multi-polygons are not valid arguments") exemplar = obs[0] try: N = len(exemplar[0][0]) except TypeError: N = exemplar._ndim assert N == 2 or N == 3 subs = (c_void_p * L)() for i, ob in enumerate(obs): if isinstance(ob, polygon.Polygon): shell = ob.exterior holes = ob.interiors else: shell = ob[0] holes = ob[1] geom, ndims = polygon.geos_polygon_from_py(shell, holes) subs[i] = cast(geom, c_void_p) return (lgeos.GEOSGeom_createCollection(6, subs, L), N)
def geos_geometrycollection_from_py(ob): """Creates a GEOS GeometryCollection from a list of geometries""" L = len(ob) N = 2 subs = (c_void_p * L)() for l in range(L): assert (isinstance(ob[l], BaseGeometry)) if ob[l].has_z: N = 3 geom, n = geos_geom_from_py(ob[l]) subs[l] = geom return lgeos.GEOSGeom_createCollection(7, subs, L), N
def geos_point_from_py(ob, update_geom=None, update_ndim=0): """Create a GEOS geom from an object that is a Point, a coordinate sequence or that provides the array interface. Returns the GEOS geometry and the number of its dimensions. """ if isinstance(ob, Point): return geos_geom_from_py(ob) # Accept either (x, y) or [(x, y)] if not hasattr(ob, '__getitem__'): # Iterators, e.g. Python 3 zip ob = list(ob) if isinstance(ob[0], tuple): coords = ob[0] else: coords = ob n = len(coords) dx = c_double(coords[0]) dy = c_double(coords[1]) dz = None if n == 3: dz = c_double(coords[2]) if update_geom: cs = lgeos.GEOSGeom_getCoordSeq(update_geom) if n != update_ndim: raise ValueError( "Wrong coordinate dimensions; this geometry has dimensions: " "%d" % update_ndim) else: cs = lgeos.GEOSCoordSeq_create(1, n) # Because of a bug in the GEOS C API, always set X before Y lgeos.GEOSCoordSeq_setX(cs, 0, dx) lgeos.GEOSCoordSeq_setY(cs, 0, dy) if n == 3: lgeos.GEOSCoordSeq_setZ(cs, 0, dz) if update_geom: return None else: return lgeos.GEOSGeom_createPoint(cs), n
def geos_multipoint_from_py(ob): if isinstance(ob, MultiPoint): return geos_geom_from_py(ob) m = len(ob) try: n = len(ob[0]) except TypeError: n = ob[0]._ndim assert n == 2 or n == 3 # Array of pointers to point geometries subs = (c_void_p * m)() # add to coordinate sequence for i in range(m): coords = ob[i] geom, ndims = point.geos_point_from_py(coords) subs[i] = cast(geom, c_void_p) return lgeos.GEOSGeom_createCollection(4, subs, m), n