structure saas with tools
This commit is contained in:
335
.venv/lib/python3.10/site-packages/shapely/coordinates.py
Normal file
335
.venv/lib/python3.10/site-packages/shapely/coordinates.py
Normal file
@@ -0,0 +1,335 @@
|
||||
"""Methods that operate on the coordinates of geometries."""
|
||||
|
||||
import numpy as np
|
||||
|
||||
import shapely
|
||||
from shapely import lib
|
||||
from shapely.decorators import deprecate_positional
|
||||
|
||||
__all__ = ["count_coordinates", "get_coordinates", "set_coordinates", "transform"]
|
||||
|
||||
|
||||
# Note: future plan is to change this signature over a few releases:
|
||||
# shapely 2.0: only supported XY and XYZ geometries
|
||||
# transform(geometry, transformation, include_z=False)
|
||||
# shapely 2.1: shows deprecation warning about positional 'include_z' arg
|
||||
# transform(geometry, transformation, include_z=False, *, interleaved=True)
|
||||
# shapely 2.2(?): enforce keyword-only arguments after 'transformation'
|
||||
# transform(geometry, transformation, *, include_z=False, interleaved=True)
|
||||
|
||||
|
||||
@deprecate_positional(["include_z"], category=DeprecationWarning)
|
||||
def transform(
|
||||
geometry,
|
||||
transformation,
|
||||
include_z: bool | None = False,
|
||||
*,
|
||||
interleaved: bool = True,
|
||||
):
|
||||
"""Apply a function to the coordinates of a geometry.
|
||||
|
||||
With the default of ``include_z=False``, all returned geometries will be
|
||||
two-dimensional; the third dimension will be discarded, if present.
|
||||
When specifying ``include_z=True``, the returned geometries preserve
|
||||
the dimensionality of the respective input geometries.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geometry : Geometry or array_like
|
||||
Geometry or geometries to transform.
|
||||
transformation : function
|
||||
A function that transforms a (N, 2) or (N, 3) ndarray of float64 to
|
||||
another (N, 2) or (N, 3) ndarray of float64.
|
||||
The function may not change N.
|
||||
include_z : bool, optional, default False
|
||||
If False, always return 2D geometries.
|
||||
If True, the data being passed to the
|
||||
transformation function will include the third dimension
|
||||
(if a geometry has no third dimension, the z-coordinates
|
||||
will be NaN). If None, will infer the dimensionality per
|
||||
input geometry using ``has_z``, which may result in 2 calls to
|
||||
the transformation function. Note that this inference
|
||||
can be unreliable with empty geometries or NaN coordinates: for a
|
||||
guaranteed result, it is recommended to specify ``include_z`` explicitly.
|
||||
interleaved : bool, default True
|
||||
If set to False, the transformation function should accept 2 or 3 separate
|
||||
one-dimensional arrays (x, y and optional z) instead of a single
|
||||
two-dimensional array.
|
||||
|
||||
.. versionadded:: 2.1.0
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. deprecated:: 2.1.0
|
||||
A deprecation warning is shown if ``include_z`` is specified as a
|
||||
positional argument. This will need to be specified as a keyword
|
||||
argument in a future release.
|
||||
|
||||
See Also
|
||||
--------
|
||||
has_z
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import shapely
|
||||
>>> from shapely import LineString, Point
|
||||
>>> shapely.transform(Point(0, 0), lambda x: x + 1)
|
||||
<POINT (1 1)>
|
||||
>>> shapely.transform(LineString([(2, 2), (4, 4)]), lambda x: x * [2, 3])
|
||||
<LINESTRING (4 6, 8 12)>
|
||||
>>> shapely.transform(None, lambda x: x) is None
|
||||
True
|
||||
>>> shapely.transform([Point(0, 0), None], lambda x: x).tolist()
|
||||
[<POINT (0 0)>, None]
|
||||
|
||||
The presence of a third dimension can be automatically detected, or
|
||||
controlled explicitly:
|
||||
|
||||
>>> shapely.transform(Point(0, 0, 0), lambda x: x + 1)
|
||||
<POINT (1 1)>
|
||||
>>> shapely.transform(Point(0, 0, 0), lambda x: x + 1, include_z=True)
|
||||
<POINT Z (1 1 1)>
|
||||
>>> shapely.transform(Point(0, 0, 0), lambda x: x + 1, include_z=None)
|
||||
<POINT Z (1 1 1)>
|
||||
|
||||
With interleaved=False, the call signature of the transformation is different:
|
||||
|
||||
>>> shapely.transform(LineString([(1, 2), (3, 4)]), lambda x, y: (x + 1, y), \
|
||||
interleaved=False)
|
||||
<LINESTRING (2 2, 4 4)>
|
||||
|
||||
Or with a z coordinate:
|
||||
|
||||
>>> shapely.transform(Point(0, 0, 0), lambda x, y, z: (x + 1, y, z + 2), \
|
||||
interleaved=False, include_z=True)
|
||||
<POINT Z (1 0 2)>
|
||||
|
||||
Using pyproj >= 2.1, the following example will reproject Shapely geometries
|
||||
from EPSG 4326 to EPSG 32618:
|
||||
|
||||
>>> from pyproj import Transformer
|
||||
>>> transformer = Transformer.from_crs(4326, 32618, always_xy=True)
|
||||
>>> shapely.transform(Point(-75, 50), transformer.transform, interleaved=False)
|
||||
<POINT (500000 5538630.703)>
|
||||
|
||||
"""
|
||||
geometry_arr = np.array(geometry, dtype=np.object_) # makes a copy
|
||||
if include_z is None:
|
||||
has_z = shapely.has_z(geometry_arr)
|
||||
result = np.empty_like(geometry_arr)
|
||||
result[has_z] = transform(
|
||||
geometry_arr[has_z], transformation, include_z=True, interleaved=interleaved
|
||||
)
|
||||
result[~has_z] = transform(
|
||||
geometry_arr[~has_z],
|
||||
transformation,
|
||||
include_z=False,
|
||||
interleaved=interleaved,
|
||||
)
|
||||
else:
|
||||
# TODO: expose include_m
|
||||
include_m = False
|
||||
coordinates = lib.get_coordinates(geometry_arr, include_z, include_m, False)
|
||||
if interleaved:
|
||||
new_coordinates = transformation(coordinates)
|
||||
else:
|
||||
new_coordinates = np.asarray(
|
||||
transformation(*coordinates.T), dtype=np.float64
|
||||
).T
|
||||
# check the array to yield understandable error messages
|
||||
if not isinstance(new_coordinates, np.ndarray) or new_coordinates.ndim != 2:
|
||||
raise ValueError(
|
||||
"The provided transformation did not return a two-dimensional numpy "
|
||||
"array"
|
||||
)
|
||||
if new_coordinates.dtype != np.float64:
|
||||
raise ValueError(
|
||||
"The provided transformation returned an array with an unexpected "
|
||||
f"dtype ({new_coordinates.dtype})"
|
||||
)
|
||||
if new_coordinates.shape != coordinates.shape:
|
||||
# if the shape is too small we will get a segfault
|
||||
raise ValueError(
|
||||
"The provided transformation returned an array with an unexpected "
|
||||
f"shape ({new_coordinates.shape})"
|
||||
)
|
||||
result = lib.set_coordinates(geometry_arr, new_coordinates)
|
||||
if result.ndim == 0 and not isinstance(geometry, np.ndarray):
|
||||
return result.item()
|
||||
return result
|
||||
|
||||
|
||||
def count_coordinates(geometry):
|
||||
"""Count the number of coordinate pairs in a geometry array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geometry : Geometry or array_like
|
||||
Geometry or geometries to count the coordinates of.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import shapely
|
||||
>>> from shapely import LineString, Point
|
||||
>>> shapely.count_coordinates(Point(0, 0))
|
||||
1
|
||||
>>> shapely.count_coordinates(LineString([(2, 2), (4, 2)]))
|
||||
2
|
||||
>>> shapely.count_coordinates(None)
|
||||
0
|
||||
>>> shapely.count_coordinates([Point(0, 0), None])
|
||||
1
|
||||
|
||||
"""
|
||||
return lib.count_coordinates(np.asarray(geometry, dtype=np.object_))
|
||||
|
||||
|
||||
# Note: future plan is to change this signature over a few releases:
|
||||
# shapely 2.0: only supported XY and XYZ geometries
|
||||
# get_coordinates(geometry, include_z=False, return_index=False)
|
||||
# shapely 2.1: shows deprecation warning about positional 'include_z' and 'return_index'
|
||||
# get_coordinates(geometry, include_z=False, return_index=False, *, include_m=False)
|
||||
# shapely 2.2(?): enforce keyword-only arguments after 'geometry'
|
||||
# get_coordinates(geometry, *, include_z=False, include_m=False, return_index=False)
|
||||
|
||||
|
||||
@deprecate_positional(["include_z", "return_index"], category=DeprecationWarning)
|
||||
def get_coordinates(geometry, include_z=False, return_index=False, *, include_m=False):
|
||||
"""Get coordinates from a geometry array as an array of floats.
|
||||
|
||||
The shape of the returned array is (N, 2), with N being the number of
|
||||
coordinate pairs. The shape of the data may also be (N, 3) or (N, 4),
|
||||
depending on ``include_z`` and ``include_m`` options.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geometry : Geometry or array_like
|
||||
Geometry or geometries to get the coordinates of.
|
||||
include_z, include_m : bool, default False
|
||||
If both are False, return XY (2D) geometries.
|
||||
If both are True, return XYZM (4D) geometries.
|
||||
If either are True, return XYZ or XYM (3D) geometries.
|
||||
If a geometry has no Z or M dimension, extra coordinate data will be NaN.
|
||||
|
||||
.. versionadded:: 2.1.0
|
||||
The ``include_m`` parameter was added to support XYM (3D) and
|
||||
XYZM (4D) geometries available with GEOS 3.12.0 or later.
|
||||
With older GEOS versions, M dimension coordinates will be NaN.
|
||||
|
||||
return_index : bool, default False
|
||||
If True, also return the index of each returned geometry as a separate
|
||||
ndarray of integers. For multidimensional arrays, this indexes into the
|
||||
flattened array (in C contiguous order).
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. deprecated:: 2.1.0
|
||||
A deprecation warning is shown if ``include_z`` or ``return_index`` are
|
||||
specified as positional arguments. In a future release, these will
|
||||
need to be specified as keyword arguments.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import shapely
|
||||
>>> from shapely import LineString, Point
|
||||
>>> shapely.get_coordinates(Point(1, 2)).tolist()
|
||||
[[1.0, 2.0]]
|
||||
>>> shapely.get_coordinates(LineString([(2, 2), (4, 4)])).tolist()
|
||||
[[2.0, 2.0], [4.0, 4.0]]
|
||||
>>> shapely.get_coordinates(None)
|
||||
array([], shape=(0, 2), dtype=float64)
|
||||
|
||||
By default the third dimension is ignored:
|
||||
|
||||
>>> shapely.get_coordinates(Point(1, 2, 3)).tolist()
|
||||
[[1.0, 2.0]]
|
||||
>>> shapely.get_coordinates(Point(1, 2, 3), include_z=True).tolist()
|
||||
[[1.0, 2.0, 3.0]]
|
||||
|
||||
If geometries don't have Z or M dimension, these values will be NaN:
|
||||
|
||||
>>> pt = Point(1, 2)
|
||||
>>> shapely.get_coordinates(pt, include_z=True).tolist()
|
||||
[[1.0, 2.0, nan]]
|
||||
>>> shapely.get_coordinates(pt, include_z=True, include_m=True).tolist()
|
||||
[[1.0, 2.0, nan, nan]]
|
||||
|
||||
When ``return_index=True``, indexes are returned also:
|
||||
|
||||
>>> geometries = [LineString([(2, 2), (4, 4)]), Point(0, 0)]
|
||||
>>> coordinates, index = shapely.get_coordinates(geometries, return_index=True)
|
||||
>>> coordinates.tolist(), index.tolist()
|
||||
([[2.0, 2.0], [4.0, 4.0], [0.0, 0.0]], [0, 0, 1])
|
||||
|
||||
"""
|
||||
return lib.get_coordinates(
|
||||
np.asarray(geometry, dtype=np.object_), include_z, include_m, return_index
|
||||
)
|
||||
|
||||
|
||||
def set_coordinates(geometry, coordinates):
|
||||
"""Adapts the coordinates of a geometry array in-place.
|
||||
|
||||
If the coordinates array has shape (N, 2), all returned geometries
|
||||
will be two-dimensional, and the third dimension will be discarded,
|
||||
if present. If the coordinates array has shape (N, 3), the returned
|
||||
geometries preserve the dimensionality of the input geometries.
|
||||
|
||||
.. warning::
|
||||
|
||||
The geometry array is modified in-place! If you do not want to
|
||||
modify the original array, you can do
|
||||
``set_coordinates(arr.copy(), newcoords)``.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geometry : Geometry or array_like
|
||||
Geometry or geometries to set the coordinates of.
|
||||
coordinates: array_like
|
||||
An array of coordinates to set.
|
||||
|
||||
See Also
|
||||
--------
|
||||
transform : Returns a copy of a geometry array with a function applied to its
|
||||
coordinates.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import shapely
|
||||
>>> from shapely import LineString, Point
|
||||
>>> shapely.set_coordinates(Point(0, 0), [[1, 1]])
|
||||
<POINT (1 1)>
|
||||
>>> shapely.set_coordinates(
|
||||
... [Point(0, 0), LineString([(0, 0), (0, 0)])],
|
||||
... [[1, 2], [3, 4], [5, 6]]
|
||||
... ).tolist()
|
||||
[<POINT (1 2)>, <LINESTRING (3 4, 5 6)>]
|
||||
>>> shapely.set_coordinates([None, Point(0, 0)], [[1, 2]]).tolist()
|
||||
[None, <POINT (1 2)>]
|
||||
|
||||
Third dimension of input geometry is discarded if coordinates array does
|
||||
not include one:
|
||||
|
||||
>>> shapely.set_coordinates(Point(0, 0, 0), [[1, 1]])
|
||||
<POINT (1 1)>
|
||||
>>> shapely.set_coordinates(Point(0, 0, 0), [[1, 1, 1]])
|
||||
<POINT Z (1 1 1)>
|
||||
|
||||
"""
|
||||
geometry_arr = np.asarray(geometry, dtype=np.object_)
|
||||
coordinates = np.atleast_2d(np.asarray(coordinates)).astype(np.float64)
|
||||
if coordinates.ndim != 2:
|
||||
raise ValueError(
|
||||
f"The coordinate array should have dimension of 2 (has {coordinates.ndim})"
|
||||
)
|
||||
n_coords = lib.count_coordinates(geometry_arr)
|
||||
if (coordinates.shape[0] != n_coords) or (coordinates.shape[1] not in {2, 3}):
|
||||
raise ValueError(
|
||||
f"The coordinate array has an invalid shape {coordinates.shape}"
|
||||
)
|
||||
lib.set_coordinates(geometry_arr, coordinates)
|
||||
if geometry_arr.ndim == 0 and not isinstance(geometry, np.ndarray):
|
||||
return geometry_arr.item()
|
||||
return geometry_arr
|
||||
Reference in New Issue
Block a user