def test_from_wkt(): expected = shapely.points(1, 1) actual = shapely.from_wkt("POINT (1 1)") assert_geometries_equal(actual, expected) # also accept bytes actual = shapely.from_wkt(b"POINT (1 1)") assert_geometries_equal(actual, expected)
def __new__(self, coordinates=None): if coordinates is None: # empty geometry # TODO better constructor return shapely.from_wkt("LINESTRING EMPTY") elif isinstance(coordinates, LineString): if type(coordinates) == LineString: # return original objects since geometries are immutable return coordinates else: # LinearRing # TODO convert LinearRing to LineString more directly coordinates = coordinates.coords else: # check coordinates on points def _coords(o): if isinstance(o, Point): return o.coords[0] else: return o coordinates = [_coords(o) for o in coordinates] if len(coordinates) == 0: # empty geometry # TODO better constructor + should shapely.linestrings handle this? return shapely.from_wkt("LINESTRING EMPTY") geom = shapely.linestrings(coordinates) if not isinstance(geom, LineString): raise ValueError("Invalid values passed to LineString constructor") return geom
def test_from_wkb_ignore_on_invalid(): with warnings.catch_warnings(): warnings.simplefilter("error") shapely.from_wkt("", on_invalid="ignore") with warnings.catch_warnings(): warnings.simplefilter("error") shapely.from_wkt("NOT A WKT STRING", on_invalid="ignore")
def __new__(self, coordinates=None): """ Parameters ---------- coordinates : sequence A sequence of (x, y [,z]) numeric coordinate pairs or triples. Also can be a sequence of Point objects. Rings are implicitly closed. There is no need to specific a final coordinate pair identical to the first. Example ------- Construct a square ring. >>> ring = LinearRing( ((0, 0), (0, 1), (1 ,1 ), (1 , 0)) ) >>> ring.is_closed True >>> ring.length 4.0 """ if coordinates is None: # empty geometry # TODO better way? return shapely.from_wkt("LINEARRING EMPTY") elif isinstance(coordinates, LineString): if type(coordinates) == LinearRing: # return original objects since geometries are immutable return coordinates elif not coordinates.is_valid: raise TopologicalError("An input LineString must be valid.") else: # LineString # TODO convert LineString to LinearRing more directly? coordinates = coordinates.coords else: # check coordinates on points def _coords(o): if isinstance(o, Point): return o.coords[0] else: return o coordinates = [_coords(o) for o in coordinates] if len(coordinates) == 0: # empty geometry # TODO better constructor + should shapely.linearrings handle this? return shapely.from_wkt("LINEARRING EMPTY") geom = shapely.linearrings(coordinates) if not isinstance(geom, LinearRing): raise ValueError("Invalid values passed to LinearRing constructor") return geom
def __new__(self, coordinates=None): """ Parameters ---------- coordinates : sequence A sequence of (x, y [,z]) numeric coordinate pairs or triples or an object that provides the numpy array interface, including another instance of LineString. Example ------- Create a line with two segments >>> a = LineString([[0, 0], [1, 0], [1, 1]]) >>> a.length 2.0 """ if coordinates is None: # empty geometry # TODO better constructor return shapely.from_wkt("LINESTRING EMPTY") elif isinstance(coordinates, LineString): if type(coordinates) == LineString: # return original objects since geometries are immutable return coordinates else: # LinearRing # TODO convert LinearRing to LineString more directly coordinates = coordinates.coords else: # check coordinates on points def _coords(o): if isinstance(o, Point): return o.coords[0] else: return o coordinates = [_coords(o) for o in coordinates] if len(coordinates) == 0: # empty geometry # TODO better constructor + should shapely.linestrings handle this? return shapely.from_wkt("LINESTRING EMPTY") geom = shapely.linestrings(coordinates) if not isinstance(geom, LineString): raise ValueError("Invalid values passed to LineString constructor") return geom
def __new__(self, geoms=None): """ Parameters ---------- geoms : list A list of shapely geometry instances, which may be heterogeneous. Example ------- Create a GeometryCollection with a Point and a LineString >>> from shapely.geometry import LineString, Point >>> p = Point(51, -1) >>> l = LineString([(52, -1), (49, 2)]) >>> gc = GeometryCollection([p, l]) """ if not geoms: # TODO better empty constructor return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY") if isinstance(geoms, BaseGeometry): # TODO(shapely-2.0) do we actually want to split Multi-part geometries? # this is needed for the split() tests if hasattr(geoms, "geoms"): geoms = geoms.geoms else: geoms = [geoms] return shapely.geometrycollections(geoms)
def __new__(self, *args): if len(args) == 0: # empty geometry # TODO better constructor return shapely.from_wkt("POINT EMPTY") elif len(args) > 3: raise TypeError( "Point() takes at most 3 arguments ({} given)".format( len(args))) elif len(args) == 1: coords = args[0] if isinstance(coords, Point): return coords # Accept either (x, y) or [(x, y)] if not hasattr(coords, "__getitem__"): # generators coords = list(coords) if isinstance(coords[0], tuple): coords = coords[0] geom = shapely.points(coords) else: # 2 or 3 args geom = shapely.points(*args) if not isinstance(geom, Point): raise ValueError("Invalid values passed to Point constructor") return geom
def __new__(self): warn( "Directly calling the base class 'BaseGeometry()' is deprecated, and " "will raise an error in the future. To create an empty geometry, " "use one of the subclasses instead, for example 'GeometryCollection()'.", ShapelyDeprecationWarning, stacklevel=2, ) return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY")
def __new__(self): """Create an empty geometry.""" warn( "The 'EmptyGeometry()' constructor to create an empty geometry is " "deprecated, and will raise an error in the future. Use one of the " "geometry subclasses instead, for example 'GeometryCollection()'.", ShapelyDeprecationWarning, stacklevel=2, ) return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY")
def __new__(self, shell=None, holes=None): if shell is None: # empty geometry # TODO better way? return shapely.from_wkt("POLYGON EMPTY") elif isinstance(shell, Polygon): # return original objects since geometries are immutable return shell # else: # geom_shell = LinearRing(shell) # if holes is not None: # geom_holes = [LinearRing(h) for h in holes] if holes is not None: if len(holes) == 0: # shapely constructor cannot handle holes=[] holes = None else: holes = [LinearRing(ring) for ring in holes] if not isinstance(shell, BaseGeometry): if not isinstance(shell, (list, np.ndarray)): # eg emtpy generator not handled well by np.asarray shell = list(shell) shell = np.asarray(shell) if len(shell) == 0: # empty geometry # TODO better constructor + should shapely.polygons handle this? return shapely.from_wkt("POLYGON EMPTY") if not np.issubdtype(shell.dtype, np.number): # conversion of coords to 2D array failed, this might be due # to inconsistent coordinate dimensionality raise ValueError("Inconsistent coordinate dimensionality") elif not isinstance(shell, LinearRing): shell = LinearRing(shell) geom = shapely.polygons(shell, holes=holes) if not isinstance(geom, Polygon): raise ValueError("Invalid values passed to Polygon constructor") return geom
def __new__(self, points=None): if points is None: # allow creation of empty multipoints, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTIPOINT EMPTY") elif isinstance(points, MultiPoint): return points m = len(points) subs = [] for i in range(m): p = point.Point(points[i]) if p.is_empty: raise EmptyPartError( "Can't create MultiPoint with empty component") subs.append(p) if len(points) == 0: return shapely.from_wkt("MULTIPOINT EMPTY") return shapely.multipoints(subs)
def __new__(self, points=None): """ Parameters ---------- points : sequence A sequence of (x, y [,z]) numeric coordinate pairs or triples or a sequence of objects that implement the numpy array interface, including instances of Point. Example ------- Construct a 2 point collection >>> from shapely.geometry import Point >>> ob = MultiPoint([[0.0, 0.0], [1.0, 2.0]]) >>> len(ob.geoms) 2 >>> type(ob.geoms[0]) == Point True """ if points is None: # allow creation of empty multipoints, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTIPOINT EMPTY") elif isinstance(points, MultiPoint): return points m = len(points) subs = [] for i in range(m): p = point.Point(points[i]) if p.is_empty: raise EmptyPartError( "Can't create MultiPoint with empty component") subs.append(p) if len(points) == 0: return shapely.from_wkt("MULTIPOINT EMPTY") return shapely.multipoints(subs)
def __new__(self, geoms=None): if not geoms: # TODO better empty constructor return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY") if isinstance(geoms, BaseGeometry): # TODO(shapely-2.0) do we actually want to split Multi-part geometries? # this is needed for the split() tests if hasattr(geoms, "geoms"): geoms = geoms.geoms else: geoms = [geoms] return shapely.geometrycollections(geoms)
def __new__(self, lines=None): if not lines: # allow creation of empty multilinestrings, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTILINESTRING EMPTY") elif isinstance(lines, MultiLineString): return lines lines = getattr(lines, "geoms", lines) m = len(lines) subs = [] for i in range(m): line = linestring.LineString(lines[i]) if line.is_empty: raise EmptyPartError( "Can't create MultiLineString with empty component") subs.append(line) if len(lines) == 0: return shapely.from_wkt("MULTILINESTRING EMPTY") return shapely.multilinestrings(subs)
def __new__(self, polygons=None): if not polygons: # allow creation of empty multipolygons, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTIPOLYGON EMPTY") elif isinstance(polygons, MultiPolygon): return polygons polygons = getattr(polygons, "geoms", polygons) polygons = [ p for p in polygons if p and not (isinstance(p, polygon.Polygon) and p.is_empty) ] L = len(polygons) # Bail immediately if we have no input points. if L == 0: return shapely.from_wkt("MULTIPOLYGON EMPTY") # This function does not accept sequences of MultiPolygons: there is # no implicit flattening. if isinstance(polygons[0], MultiPolygon): raise ValueError( "Sequences of multi-polygons are not valid arguments") subs = [] for i in range(L): ob = polygons[i] if not isinstance(ob, polygon.Polygon): shell = ob[0] holes = ob[1] p = polygon.Polygon(shell, holes) else: p = polygon.Polygon(ob) subs.append(p) return shapely.multipolygons(subs)
def loads(data): """ Load a geometry from a WKT string. Parameters ---------- data : str A WKT string Returns ------- Shapely geometry object """ return shapely.from_wkt(data)
def __new__(self, lines=None): """ Parameters ---------- lines : sequence A sequence of line-like coordinate sequences or objects that provide the numpy array interface, including instances of LineString. Example ------- Construct a collection containing one line string. >>> lines = MultiLineString( [[[0.0, 0.0], [1.0, 2.0]]] ) """ if not lines: # allow creation of empty multilinestrings, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTILINESTRING EMPTY") elif isinstance(lines, MultiLineString): return lines lines = getattr(lines, "geoms", lines) m = len(lines) subs = [] for i in range(m): line = linestring.LineString(lines[i]) if line.is_empty: raise EmptyPartError( "Can't create MultiLineString with empty component") subs.append(line) if len(lines) == 0: return shapely.from_wkt("MULTILINESTRING EMPTY") return shapely.multilinestrings(subs)
def test_from_wkt_exceptions(): with pytest.raises(TypeError, match="Expected bytes or string, got int"): shapely.from_wkt(1) with pytest.raises(shapely.GEOSException, match="Expected word but encountered end of stream"): shapely.from_wkt("") with pytest.raises(shapely.GEOSException, match="Unknown type: 'NOT'"): shapely.from_wkt("NOT A WKT STRING")
def __new__(self, *args): """ Parameters ---------- There are 2 cases: 1) 1 parameter: this must satisfy the numpy array protocol. 2) 2 or more parameters: x, y, z : float Easting, northing, and elevation. """ if len(args) == 0: # empty geometry # TODO better constructor return shapely.from_wkt("POINT EMPTY") elif len(args) > 3: raise TypeError( "Point() takes at most 3 arguments ({} given)".format(len(args)) ) elif len(args) == 1: coords = args[0] if isinstance(coords, Point): return coords # Accept either (x, y) or [(x, y)] if not hasattr(coords, "__getitem__"): # generators coords = list(coords) if isinstance(coords[0], tuple): coords = coords[0] geom = shapely.points(coords) else: # 2 or 3 args geom = shapely.points(*args) if not isinstance(geom, Point): raise ValueError("Invalid values passed to Point constructor") return geom
def test_from_wkt_empty(wkt): geom = shapely.from_wkt(wkt) assert shapely.is_geometry(geom).all() assert shapely.is_empty(geom).all() assert shapely.to_wkt(geom) == wkt
def test_from_wkt_all_types(geom): wkt = shapely.to_wkt(geom) actual = shapely.from_wkt(wkt) assert_geometries_equal(actual, geom)
def test_from_wkt_on_invalid_unsupported_option(): with pytest.raises(ValueError, match="not a valid option"): shapely.from_wkt(b"\x01\x01\x00\x00\x00\x00", on_invalid="unsupported_option")
def __new__(self): """Create an empty geometry.""" # TODO(shapely-2.0) create empty geometry - should we deprecate this class? return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY")
def test_from_wkt_warn_on_invalid(): with pytest.warns(Warning, match="Invalid WKT"): shapely.from_wkt("", on_invalid="warn") with pytest.warns(Warning, match="Invalid WKT"): shapely.from_wkt("NOT A WKT STRING", on_invalid="warn")
def test_from_wkt_none(): # None propagates assert shapely.from_wkt(None) is None
def __new__(self): # TODO create empty geometry - should we deprecate this constructor? return shapely.from_wkt("GEOMETRYCOLLECTION EMPTY")
def __new__(self, polygons=None): """ Parameters ---------- polygons : sequence A sequence of (shell, holes) tuples where shell is the sequence representation of a linear ring (see linearring.py) and holes is a sequence of such linear rings Example ------- Construct a collection from a sequence of coordinate tuples >>> from shapely.geometry import Polygon >>> ob = MultiPolygon( [ ... ( ... ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), ... [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))] ... ) ... ] ) >>> len(ob.geoms) 1 >>> type(ob.geoms[0]) == Polygon True """ if not polygons: # allow creation of empty multipolygons, to support unpickling # TODO better empty constructor return shapely.from_wkt("MULTIPOLYGON EMPTY") elif isinstance(polygons, MultiPolygon): return polygons polygons = getattr(polygons, "geoms", polygons) polygons = [ p for p in polygons if p and not (isinstance(p, polygon.Polygon) and p.is_empty) ] L = len(polygons) # Bail immediately if we have no input points. if L == 0: return shapely.from_wkt("MULTIPOLYGON EMPTY") # This function does not accept sequences of MultiPolygons: there is # no implicit flattening. if isinstance(polygons[0], MultiPolygon): raise ValueError( "Sequences of multi-polygons are not valid arguments") subs = [] for i in range(L): ob = polygons[i] if not isinstance(ob, polygon.Polygon): shell = ob[0] holes = ob[1] p = polygon.Polygon(shell, holes) else: p = polygon.Polygon(ob) subs.append(p) return shapely.multipolygons(subs)
def __new__(self, shell=None, holes=None): """ Parameters ---------- shell : sequence A sequence of (x, y [,z]) numeric coordinate pairs or triples. Also can be a sequence of Point objects. holes : sequence A sequence of objects which satisfy the same requirements as the shell parameters above Example ------- Create a square polygon with no holes >>> coords = ((0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.)) >>> polygon = Polygon(coords) >>> polygon.area 1.0 """ if shell is None: # empty geometry # TODO better way? return shapely.from_wkt("POLYGON EMPTY") elif isinstance(shell, Polygon): # return original objects since geometries are immutable return shell # else: # geom_shell = LinearRing(shell) # if holes is not None: # geom_holes = [LinearRing(h) for h in holes] if holes is not None: if len(holes) == 0: # shapely constructor cannot handle holes=[] holes = None else: holes = [LinearRing(ring) for ring in holes] if not isinstance(shell, BaseGeometry): if not isinstance(shell, (list, np.ndarray)): # eg emtpy generator not handled well by np.asarray shell = list(shell) shell = np.asarray(shell) if len(shell) == 0: # empty geometry # TODO better constructor + should shapely.polygons handle this? return shapely.from_wkt("POLYGON EMPTY") if not np.issubdtype(shell.dtype, np.number): # conversion of coords to 2D array failed, this might be due # to inconsistent coordinate dimensionality raise ValueError("Inconsistent coordinate dimensionality") elif not isinstance(shell, LinearRing): shell = LinearRing(shell) geom = shapely.polygons(shell, holes=holes) if not isinstance(geom, Polygon): raise ValueError("Invalid values passed to Polygon constructor") return geom
def time_read_from_wkt(self): shapely.from_wkt(self.to_read_wkt)
def test_from_wkb_ignore_on_invalid(): with pytest.warns(None): shapely.from_wkt("", on_invalid="ignore") with pytest.warns(None): shapely.from_wkt("NOT A WKT STRING", on_invalid="ignore")