shapely 2.0.4__tar.gz → 2.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shapely-2.0.4 → shapely-2.0.6}/CHANGES.txt +22 -0
- {shapely-2.0.4 → shapely-2.0.6}/CITATION.cff +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/PKG-INFO +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/docs/geometry.rst +35 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/installation.rst +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/docs/migration_pygeos.rst +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/pyproject.toml +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/setup.py +11 -13
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_geometry.py +32 -23
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_geometry_helpers.pyx +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_version.py +3 -3
- {shapely-2.0.4 → shapely-2.0.6}/shapely/affinity.py +23 -7
- {shapely-2.0.4 → shapely-2.0.6}/shapely/constructive.py +13 -12
- {shapely-2.0.4 → shapely-2.0.6}/shapely/coords.py +7 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/creation.py +5 -5
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/point.py +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/io.py +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/plotting.py +5 -5
- {shapely-2.0.4 → shapely-2.0.6}/shapely/predicates.py +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/set_operations.py +6 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_coords.py +16 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_format.py +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_point.py +3 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_operations.py +6 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_predicates.py +10 -2
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_geometry.py +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_linear.py +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_predicates.py +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_set_operations.py +4 -4
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_strtree.py +20 -8
- {shapely-2.0.4 → shapely-2.0.6}/shapely.egg-info/PKG-INFO +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/src/coords.c +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/src/geos.c +1 -1
- {shapely-2.0.4 → shapely-2.0.6}/src/strtree.c +2 -2
- {shapely-2.0.4 → shapely-2.0.6}/src/ufuncs.c +3 -3
- {shapely-2.0.4 → shapely-2.0.6}/CREDITS.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/LICENSE.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/README.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/constructive.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/coordinates.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/creation.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/design.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/index.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/io.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/linear.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/manual.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/measurement.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/migration.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/predicates.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/properties.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/release.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/set_operations.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/strtree.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/docs/testing.rst +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/setup.cfg +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_enum.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_geos.pxd +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_geos.pyx +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_pygeos_api.pxd +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/_ragged_array.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/algorithms/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/algorithms/_oriented_envelope.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/algorithms/cga.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/algorithms/polylabel.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/coordinates.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/decorators.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/errors.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/base.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/collection.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/conftest.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/geo.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/linestring.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/multilinestring.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/multipoint.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/multipolygon.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geometry/polygon.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/geos.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/linear.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/measurement.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/ops.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/prepared.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/speedups.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/strtree.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/testing.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/common.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_collection.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_decimal.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_emptiness.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_equality.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_geometry_base.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_hash.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_linestring.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_multi.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_multilinestring.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_multipoint.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_multipolygon.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/geometry/test_polygon.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/conftest.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_affinity.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_box.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_buffer.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_cga.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_clip_by_rect.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_create_inconsistent_dimensionality.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_delaunay.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_empty_polygons.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_equality.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_geointerface.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_invalid_geometries.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_linear_referencing.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_linemerge.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_locale.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_make_valid.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_mapping.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_minimum_clearance.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_ndarrays.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_nearest.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_operators.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_orient.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_parallel_offset.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_persist.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_pickle.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_polygonize.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_polylabel.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_prepared.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_products_z.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_shape.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_shared_paths.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_singularity.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_snap.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_split.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_substring.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_svg.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_transform.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_union.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_validation.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_vectorized.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_voronoi_diagram.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_wkb.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/test_wkt.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/legacy/threading_test.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_constructive.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_coordinates.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_creation.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_creation_indices.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_io.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_measurement.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_misc.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_plotting.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_ragged_array.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/tests/test_testing.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/validation.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/vectorized/__init__.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/wkb.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely/wkt.py +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely.egg-info/SOURCES.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely.egg-info/dependency_links.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely.egg-info/requires.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/shapely.egg-info/top_level.txt +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/c_api.c +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/c_api.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/coords.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/fast_loop_macros.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/geos.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/kvec.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/lib.c +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/pygeom.c +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/pygeom.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/strtree.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/ufuncs.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/vector.c +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/src/vector.h +0 -0
- {shapely-2.0.4 → shapely-2.0.6}/versioneer.py +0 -0
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
Changes
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
2.0.6 (2024-08-19)
|
|
5
|
+
------------------
|
|
6
|
+
|
|
7
|
+
Bug fixes:
|
|
8
|
+
|
|
9
|
+
- Fix compatibility with NumPy 2.1.0 (#2099).
|
|
10
|
+
|
|
11
|
+
Wheels are available for Python 3.13 (and still include GEOS 3.11.4).
|
|
12
|
+
|
|
13
|
+
2.0.5 (2024-07-13)
|
|
14
|
+
------------------
|
|
15
|
+
|
|
16
|
+
Binary wheels on PyPI include GEOS 3.11.4 from 2024-06-05. Furthermore,
|
|
17
|
+
universal2 wheels are removed for macOS since both x86_64 and arm64 wheels are
|
|
18
|
+
provided.
|
|
19
|
+
|
|
20
|
+
Bug fixes:
|
|
21
|
+
|
|
22
|
+
- Fix Point x/y/z attributes to return Python floats (#2074).
|
|
23
|
+
- Fix affinity for Apple silicon with NumPy 2.0 by reverting matmul, and
|
|
24
|
+
use direct matrix multiplication instead (#2085).
|
|
25
|
+
|
|
4
26
|
2.0.4 (2024-04-16)
|
|
5
27
|
------------------
|
|
6
28
|
|
|
@@ -2,8 +2,8 @@ cff-version: 1.2.0
|
|
|
2
2
|
message: "Please cite this software using these metadata."
|
|
3
3
|
type: software
|
|
4
4
|
title: Shapely
|
|
5
|
-
version: "2.0.
|
|
6
|
-
date-released: "2024-
|
|
5
|
+
version: "2.0.6"
|
|
6
|
+
date-released: "2024-08-19"
|
|
7
7
|
doi: 10.5281/zenodo.5597138
|
|
8
8
|
abstract: "Manipulation and analysis of geometric objects in the Cartesian plane."
|
|
9
9
|
repository-artifact: https://pypi.org/project/Shapely
|
|
@@ -173,3 +173,38 @@ specified, rounding precision will be disabled showing full precision.
|
|
|
173
173
|
Format types ``'x'`` and ``'X'`` show a hex-encoded string representation of
|
|
174
174
|
WKB or Well-Known Binary, with the case of the output matched the
|
|
175
175
|
case of the format type character.
|
|
176
|
+
|
|
177
|
+
.. _canonical-form:
|
|
178
|
+
|
|
179
|
+
Canonical form
|
|
180
|
+
--------------
|
|
181
|
+
When operations are applied on geometries the result is returned according to
|
|
182
|
+
some conventions.
|
|
183
|
+
|
|
184
|
+
In most cases, geometries will be returned in "mild" canonical form. There is no
|
|
185
|
+
goal to keep this form stable, so it is expected to change in future versions of
|
|
186
|
+
GEOS:
|
|
187
|
+
|
|
188
|
+
- the coordinates of exterior rings follow a clockwise orientation and interior
|
|
189
|
+
rings have a counter-clockwise orientation. This is the opposite of the OGC
|
|
190
|
+
specifications because the choice was made before this was included in the
|
|
191
|
+
standard.
|
|
192
|
+
- the starting point of rings can be changed in the output, but the exact order
|
|
193
|
+
is undefined and should not be relied upon
|
|
194
|
+
- the order of geometry types in a collection can be changed, but the order is
|
|
195
|
+
undefined
|
|
196
|
+
|
|
197
|
+
When :func:`~shapely.normalize` is used, the "strict" canonical form is applied.
|
|
198
|
+
This type of normalization is meant to be stable, so changes to it will be
|
|
199
|
+
avoided if possible:
|
|
200
|
+
|
|
201
|
+
- the coordinates of exterior rings follow a clockwise orientation and interior
|
|
202
|
+
rings have a counter-clockwise orientation
|
|
203
|
+
- the starting point of rings is lower left
|
|
204
|
+
- elements in collections are ordered by geometry type: by descending dimension
|
|
205
|
+
and multi-types first (MultiPolygon, Polygon, MultiLineString, LineString,
|
|
206
|
+
MultiPoint, Point). Multiple elements from the same type are ordered from
|
|
207
|
+
right to left and from top to bottom.
|
|
208
|
+
|
|
209
|
+
It is important to note that input geometries do not have to follow these
|
|
210
|
+
conventions.
|
|
@@ -26,8 +26,8 @@ Shapely is available on the conda-forge channel. Install as follows::
|
|
|
26
26
|
$ conda install shapely --channel conda-forge
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
Installation from source with custom GEOS
|
|
30
|
-
|
|
29
|
+
Installation from source with custom GEOS library
|
|
30
|
+
-------------------------------------------------
|
|
31
31
|
|
|
32
32
|
You may want to use a specific GEOS version or a GEOS distribution that is
|
|
33
33
|
already present on your system (for compatibility with other modules that
|
|
@@ -14,7 +14,7 @@ Therefore, everybody using PyGEOS is highly recommended to migrate to Shapely
|
|
|
14
14
|
|
|
15
15
|
Generally speaking, this should be a smooth experience because all
|
|
16
16
|
functionality of PyGEOS was added to Shapely. All vectorized functions
|
|
17
|
-
|
|
17
|
+
available in ``pygeos`` have been added to the top-level ``shapely`` module,
|
|
18
18
|
with only minor differences (see below). Migrating from PyGEOS to Shapely 2.0
|
|
19
19
|
can thus be done by replacing the ``pygeos`` import and module calls::
|
|
20
20
|
|
|
@@ -87,4 +87,4 @@ Other differences
|
|
|
87
87
|
- The behaviour of ``union_all()`` / ``intersection_all()`` / ``symmetric_difference_all``
|
|
88
88
|
was changed to return an empty GeometryCollection for an empty or all-None
|
|
89
89
|
sequence as input (instead of returning None).
|
|
90
|
-
- The ``radius`` keyword of the ``buffer()``
|
|
90
|
+
- The ``radius`` keyword of the ``buffer()`` function was renamed to ``distance``.
|
|
@@ -3,7 +3,7 @@ requires = [
|
|
|
3
3
|
"Cython",
|
|
4
4
|
# Starting with NumPy 1.25, NumPy is (by default) as far back compatible
|
|
5
5
|
# as oldest-support-numpy was (customizable with a NPY_TARGET_VERSION
|
|
6
|
-
# define). For older Python versions (where NumPy 1.25 is not yet
|
|
6
|
+
# define). For older Python versions (where NumPy 1.25 is not yet available)
|
|
7
7
|
# continue using oldest-support-numpy.
|
|
8
8
|
"oldest-supported-numpy; python_version<'3.9'",
|
|
9
9
|
"numpy>=1.25; python_version>='3.9'",
|
|
@@ -5,8 +5,7 @@ import subprocess
|
|
|
5
5
|
import sys
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from setuptools import Extension, find_packages, setup
|
|
8
|
+
from setuptools import Extension, setup
|
|
10
9
|
from setuptools.command.build_ext import build_ext as _build_ext
|
|
11
10
|
|
|
12
11
|
# ensure the current directory is on sys.path so versioneer can be imported
|
|
@@ -42,15 +41,13 @@ def get_geos_config(option):
|
|
|
42
41
|
"""
|
|
43
42
|
cmd = os.environ.get("GEOS_CONFIG", "geos-config")
|
|
44
43
|
try:
|
|
45
|
-
|
|
46
|
-
[cmd, option], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
47
|
-
).communicate()
|
|
44
|
+
proc = subprocess.run([cmd, option], capture_output=True, text=True)
|
|
48
45
|
except OSError:
|
|
49
46
|
return
|
|
50
|
-
if stderr and not stdout:
|
|
51
|
-
log.warning("geos-config %s returned '%s'", option, stderr.
|
|
47
|
+
if proc.stderr and not proc.stdout:
|
|
48
|
+
log.warning("geos-config %s returned '%s'", option, proc.stderr.strip())
|
|
52
49
|
return
|
|
53
|
-
result = stdout.
|
|
50
|
+
result = proc.stdout.strip()
|
|
54
51
|
log.debug("geos-config %s returned '%s'", option, result)
|
|
55
52
|
return result
|
|
56
53
|
|
|
@@ -86,11 +83,12 @@ def get_geos_paths():
|
|
|
86
83
|
)
|
|
87
84
|
return {}
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
def version_tuple(ver):
|
|
87
|
+
return tuple(int(itm) if itm.isnumeric() else itm for itm in ver.split("."))
|
|
88
|
+
|
|
89
|
+
if version_tuple(geos_version) < version_tuple(MIN_GEOS_VERSION):
|
|
90
90
|
raise ImportError(
|
|
91
|
-
"GEOS version should be >={}, found {}"
|
|
92
|
-
MIN_GEOS_VERSION, geos_version
|
|
93
|
-
)
|
|
91
|
+
f"GEOS version should be >={MIN_GEOS_VERSION}, found {geos_version}"
|
|
94
92
|
)
|
|
95
93
|
|
|
96
94
|
libraries = []
|
|
@@ -133,7 +131,7 @@ class build_ext(_build_ext):
|
|
|
133
131
|
|
|
134
132
|
import numpy
|
|
135
133
|
|
|
136
|
-
self.include_dirs.
|
|
134
|
+
self.include_dirs.insert(0, numpy.get_include())
|
|
137
135
|
|
|
138
136
|
|
|
139
137
|
ext_modules = []
|
|
@@ -728,20 +728,26 @@ def set_precision(geometry, grid_size, mode="valid_output", **kwargs):
|
|
|
728
728
|
|
|
729
729
|
By default, geometries use double precision coordinates (grid_size = 0).
|
|
730
730
|
|
|
731
|
-
Coordinates will be rounded if
|
|
732
|
-
input geometry. Duplicated vertices will be dropped from lines and
|
|
731
|
+
Coordinates will be rounded if the precision grid specified is less precise
|
|
732
|
+
than the input geometry. Duplicated vertices will be dropped from lines and
|
|
733
733
|
polygons for grid sizes greater than 0. Line and polygon geometries may
|
|
734
734
|
collapse to empty geometries if all vertices are closer together than
|
|
735
|
-
grid_size
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
735
|
+
``grid_size`` or if a polygon becomes significantly narrower than
|
|
736
|
+
``grid_size``. Spikes or sections in polygons narrower than ``grid_size``
|
|
737
|
+
after rounding the vertices will be removed, which can lead to multipolygons
|
|
738
|
+
or empty geometries. Z values, if present, will not be modified.
|
|
739
|
+
|
|
740
|
+
Notes:
|
|
741
|
+
|
|
742
|
+
* subsequent operations will always be performed in the precision of the
|
|
743
|
+
geometry with higher precision (smaller "grid_size"). That same precision
|
|
744
|
+
will be attached to the operation outputs.
|
|
745
|
+
* input geometries should be geometrically valid; unexpected results may
|
|
746
|
+
occur if input geometries are not.
|
|
747
|
+
* the geometry returned will be in
|
|
748
|
+
:ref:`mild canonical form <canonical-form>`, and the order of vertices can
|
|
749
|
+
change and should not be relied upon.
|
|
750
|
+
* returns None if geometry is None.
|
|
745
751
|
|
|
746
752
|
Parameters
|
|
747
753
|
----------
|
|
@@ -752,21 +758,24 @@ def set_precision(geometry, grid_size, mode="valid_output", **kwargs):
|
|
|
752
758
|
value is more precise than input geometry, the input geometry will
|
|
753
759
|
not be modified.
|
|
754
760
|
mode : {'valid_output', 'pointwise', 'keep_collapsed'}, default 'valid_output'
|
|
755
|
-
This parameter determines
|
|
761
|
+
This parameter determines the way a precision reduction is applied on
|
|
762
|
+
the geometry. There are three modes:
|
|
756
763
|
|
|
757
|
-
1. `'valid_output'` (default): The output is always valid. Collapsed
|
|
758
|
-
(including both polygons and lines) are removed.
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
764
|
+
1. `'valid_output'` (default): The output is always valid. Collapsed
|
|
765
|
+
geometry elements (including both polygons and lines) are removed.
|
|
766
|
+
Duplicate vertices are removed.
|
|
767
|
+
2. `'pointwise'`: Precision reduction is performed pointwise. Output
|
|
768
|
+
geometry may be invalid due to collapse or self-intersection.
|
|
769
|
+
Duplicate vertices are not removed. In GEOS this option is called
|
|
770
|
+
NO_TOPO.
|
|
762
771
|
|
|
763
772
|
.. note::
|
|
764
773
|
|
|
765
|
-
'pointwise' mode requires at least GEOS 3.10. It is accepted in
|
|
766
|
-
but the results may be unexpected.
|
|
767
|
-
3. `'keep_collapsed'`: Like the default mode, except that collapsed
|
|
768
|
-
elements are preserved. Collapsed polygonal input
|
|
769
|
-
vertices are removed.
|
|
774
|
+
'pointwise' mode requires at least GEOS 3.10. It is accepted in
|
|
775
|
+
earlier versions, but the results may be unexpected.
|
|
776
|
+
3. `'keep_collapsed'`: Like the default mode, except that collapsed
|
|
777
|
+
linear geometry elements are preserved. Collapsed polygonal input
|
|
778
|
+
elements are removed. Duplicate vertices are removed.
|
|
770
779
|
**kwargs
|
|
771
780
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
772
781
|
|
|
@@ -302,7 +302,7 @@ def collections_1d(object geometries, object indices, int geometry_type = 7, obj
|
|
|
302
302
|
cdef int[:] collection_size = np.bincount(indices).astype(np.int32)
|
|
303
303
|
|
|
304
304
|
# A temporary array for the geometries that will be given to CreateCollection.
|
|
305
|
-
# Its size equals max(collection_size) to
|
|
305
|
+
# Its size equals max(collection_size) to accommodate the largest collection.
|
|
306
306
|
temp_geoms = np.empty(shape=(np.max(collection_size), ), dtype=np.intp)
|
|
307
307
|
cdef np.intp_t[:] temp_geoms_view = temp_geoms
|
|
308
308
|
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-
|
|
11
|
+
"date": "2024-08-19T23:29:00+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.0.
|
|
14
|
+
"full-revisionid": "5a4207d2fb74b25d7bb2fb5d04813f68a3a612f4",
|
|
15
|
+
"version": "2.0.6"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -61,15 +61,31 @@ def affine_transform(geom, matrix):
|
|
|
61
61
|
ndim = 2
|
|
62
62
|
else:
|
|
63
63
|
raise ValueError("'matrix' expects either 6 or 12 coefficients")
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
|
|
65
|
+
# if ndim == 2:
|
|
66
|
+
# A = np.array([[a, b], [d, e]], dtype=float)
|
|
67
|
+
# off = np.array([xoff, yoff], dtype=float)
|
|
68
|
+
# else:
|
|
69
|
+
# A = np.array([[a, b, c], [d, e, f], [g, h, i]], dtype=float)
|
|
70
|
+
# off = np.array([xoff, yoff, zoff], dtype=float)
|
|
70
71
|
|
|
71
72
|
def _affine_coords(coords):
|
|
72
|
-
|
|
73
|
+
# These are equivalent, but unfortunately not robust
|
|
74
|
+
# result = np.matmul(coords, A.T) + off
|
|
75
|
+
# result = np.matmul(A, coords.T).T + off
|
|
76
|
+
# Therefore, manual matrix multiplication is needed
|
|
77
|
+
if ndim == 2:
|
|
78
|
+
x, y = coords.T
|
|
79
|
+
xp = a * x + b * y + xoff
|
|
80
|
+
yp = d * x + e * y + yoff
|
|
81
|
+
result = np.stack([xp, yp]).T
|
|
82
|
+
elif ndim == 3:
|
|
83
|
+
x, y, z = coords.T
|
|
84
|
+
xp = a * x + b * y + c * z + xoff
|
|
85
|
+
yp = d * x + e * y + f * z + yoff
|
|
86
|
+
zp = g * x + h * y + i * z + zoff
|
|
87
|
+
result = np.stack([xp, yp, zp]).T
|
|
88
|
+
return result
|
|
73
89
|
|
|
74
90
|
return shapely.transform(geom, _affine_coords, include_z=ndim == 3)
|
|
75
91
|
|
|
@@ -412,17 +412,18 @@ def delaunay_triangles(geometry, tolerance=0.0, only_edges=False, **kwargs):
|
|
|
412
412
|
--------
|
|
413
413
|
>>> from shapely import GeometryCollection, LineString, MultiPoint, Polygon
|
|
414
414
|
>>> points = MultiPoint([(50, 30), (60, 30), (100, 100)])
|
|
415
|
-
>>> delaunay_triangles(points)
|
|
416
|
-
<GEOMETRYCOLLECTION (POLYGON ((50 30,
|
|
415
|
+
>>> delaunay_triangles(points).normalize()
|
|
416
|
+
<GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))>
|
|
417
417
|
>>> delaunay_triangles(points, only_edges=True)
|
|
418
418
|
<MULTILINESTRING ((50 30, 100 100), (50 30, 60 30), ...>
|
|
419
419
|
>>> delaunay_triangles(MultiPoint([(50, 30), (51, 30), (60, 30), (100, 100)]), \
|
|
420
|
-
tolerance=2)
|
|
421
|
-
<GEOMETRYCOLLECTION (POLYGON ((50 30,
|
|
422
|
-
>>> delaunay_triangles(Polygon([(50, 30), (60, 30), (100, 100), (50, 30)]))
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
420
|
+
tolerance=2).normalize()
|
|
421
|
+
<GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))>
|
|
422
|
+
>>> delaunay_triangles(Polygon([(50, 30), (60, 30), (100, 100), (50, 30)]))\
|
|
423
|
+
.normalize()
|
|
424
|
+
<GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))>
|
|
425
|
+
>>> delaunay_triangles(LineString([(50, 30), (60, 30), (100, 100)])).normalize()
|
|
426
|
+
<GEOMETRYCOLLECTION (POLYGON ((50 30, 100 100, 60 30, 50 30)))>
|
|
426
427
|
>>> delaunay_triangles(GeometryCollection([]))
|
|
427
428
|
<GEOMETRYCOLLECTION EMPTY>
|
|
428
429
|
"""
|
|
@@ -533,11 +534,11 @@ def make_valid(geometry, **kwargs):
|
|
|
533
534
|
|
|
534
535
|
@multithreading_enabled
|
|
535
536
|
def normalize(geometry, **kwargs):
|
|
536
|
-
"""Converts Geometry to normal form (or canonical form).
|
|
537
|
+
"""Converts Geometry to strict normal form (or canonical form).
|
|
537
538
|
|
|
538
|
-
|
|
539
|
-
multi geometries consistently. Typically useful for testing
|
|
540
|
-
(for example in combination with ``equals_exact``).
|
|
539
|
+
In :ref:`strict canonical form <canonical-form>`, the coordinates, rings of a polygon and
|
|
540
|
+
parts of multi geometries are ordered consistently. Typically useful for testing
|
|
541
|
+
purposes (for example in combination with ``equals_exact``).
|
|
541
542
|
|
|
542
543
|
Parameters
|
|
543
544
|
----------
|
|
@@ -46,8 +46,13 @@ class CoordinateSequence:
|
|
|
46
46
|
else:
|
|
47
47
|
raise TypeError("key must be an index or slice")
|
|
48
48
|
|
|
49
|
-
def __array__(self, dtype=None):
|
|
50
|
-
|
|
49
|
+
def __array__(self, dtype=None, copy=None):
|
|
50
|
+
if copy is False:
|
|
51
|
+
raise ValueError("`copy=False` isn't supported. A copy is always created.")
|
|
52
|
+
elif copy is True:
|
|
53
|
+
return self._coords.copy()
|
|
54
|
+
else:
|
|
55
|
+
return self._coords
|
|
51
56
|
|
|
52
57
|
@property
|
|
53
58
|
def xy(self):
|
|
@@ -353,7 +353,7 @@ def multipoints(geometries, indices=None, out=None, **kwargs):
|
|
|
353
353
|
):
|
|
354
354
|
geometries = points(geometries)
|
|
355
355
|
if indices is None:
|
|
356
|
-
return lib.create_collection(geometries, typ, out=out, **kwargs)
|
|
356
|
+
return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
|
|
357
357
|
else:
|
|
358
358
|
return collections_1d(geometries, indices, typ, out=out)
|
|
359
359
|
|
|
@@ -390,7 +390,7 @@ def multilinestrings(geometries, indices=None, out=None, **kwargs):
|
|
|
390
390
|
geometries = linestrings(geometries)
|
|
391
391
|
|
|
392
392
|
if indices is None:
|
|
393
|
-
return lib.create_collection(geometries, typ, out=out, **kwargs)
|
|
393
|
+
return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
|
|
394
394
|
else:
|
|
395
395
|
return collections_1d(geometries, indices, typ, out=out)
|
|
396
396
|
|
|
@@ -426,7 +426,7 @@ def multipolygons(geometries, indices=None, out=None, **kwargs):
|
|
|
426
426
|
):
|
|
427
427
|
geometries = polygons(geometries)
|
|
428
428
|
if indices is None:
|
|
429
|
-
return lib.create_collection(geometries, typ, out=out, **kwargs)
|
|
429
|
+
return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
|
|
430
430
|
else:
|
|
431
431
|
return collections_1d(geometries, indices, typ, out=out)
|
|
432
432
|
|
|
@@ -457,7 +457,7 @@ def geometrycollections(geometries, indices=None, out=None, **kwargs):
|
|
|
457
457
|
"""
|
|
458
458
|
typ = GeometryType.GEOMETRYCOLLECTION
|
|
459
459
|
if indices is None:
|
|
460
|
-
return lib.create_collection(geometries, typ, out=out, **kwargs)
|
|
460
|
+
return lib.create_collection(geometries, np.intc(typ), out=out, **kwargs)
|
|
461
461
|
else:
|
|
462
462
|
return collections_1d(geometries, indices, typ, out=out)
|
|
463
463
|
|
|
@@ -511,7 +511,7 @@ def destroy_prepared(geometry, **kwargs):
|
|
|
511
511
|
Parameters
|
|
512
512
|
----------
|
|
513
513
|
geometry : Geometry or array_like
|
|
514
|
-
Geometries are changed
|
|
514
|
+
Geometries are changed in-place
|
|
515
515
|
**kwargs
|
|
516
516
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
517
517
|
|
|
@@ -85,12 +85,12 @@ class Point(BaseGeometry):
|
|
|
85
85
|
@property
|
|
86
86
|
def x(self):
|
|
87
87
|
"""Return x coordinate."""
|
|
88
|
-
return shapely.get_x(self)
|
|
88
|
+
return float(shapely.get_x(self))
|
|
89
89
|
|
|
90
90
|
@property
|
|
91
91
|
def y(self):
|
|
92
92
|
"""Return y coordinate."""
|
|
93
|
-
return shapely.get_y(self)
|
|
93
|
+
return float(shapely.get_y(self))
|
|
94
94
|
|
|
95
95
|
@property
|
|
96
96
|
def z(self):
|
|
@@ -139,12 +139,12 @@ def to_wkb(
|
|
|
139
139
|
----------
|
|
140
140
|
geometry : Geometry or array_like
|
|
141
141
|
hex : bool, default False
|
|
142
|
-
If true, export the WKB as a
|
|
142
|
+
If true, export the WKB as a hexadecimal string. The default is to
|
|
143
143
|
return a binary bytes object.
|
|
144
144
|
output_dimension : int, default 3
|
|
145
145
|
The output dimension for the WKB. Supported values are 2 and 3.
|
|
146
146
|
Specifying 3 means that up to 3 dimensions will be written but 2D
|
|
147
|
-
geometries will still be represented as 2D in the WKB
|
|
147
|
+
geometries will still be represented as 2D in the WKB representation.
|
|
148
148
|
byte_order : int, default -1
|
|
149
149
|
Defaults to native machine byte order (-1). Use 0 to force big endian
|
|
150
150
|
and 1 for little endian.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Plot single geometries using Matplotlib.
|
|
3
3
|
|
|
4
|
-
Note: this module is experimental, and mainly
|
|
4
|
+
Note: this module is experimental, and mainly targeting (interactive)
|
|
5
5
|
exploration, debugging and illustration purposes.
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -38,7 +38,7 @@ def patch_from_polygon(polygon, **kwargs):
|
|
|
38
38
|
"""
|
|
39
39
|
Gets a Matplotlib patch from a (Multi)Polygon.
|
|
40
40
|
|
|
41
|
-
Note: this function is experimental, and mainly
|
|
41
|
+
Note: this function is experimental, and mainly targeting (interactive)
|
|
42
42
|
exploration, debugging and illustration purposes.
|
|
43
43
|
|
|
44
44
|
Parameters
|
|
@@ -69,7 +69,7 @@ def plot_polygon(
|
|
|
69
69
|
"""
|
|
70
70
|
Plot a (Multi)Polygon.
|
|
71
71
|
|
|
72
|
-
Note: this function is experimental, and mainly
|
|
72
|
+
Note: this function is experimental, and mainly targeting (interactive)
|
|
73
73
|
exploration, debugging and illustration purposes.
|
|
74
74
|
|
|
75
75
|
Parameters
|
|
@@ -132,7 +132,7 @@ def plot_line(line, ax=None, add_points=True, color=None, linewidth=2, **kwargs)
|
|
|
132
132
|
"""
|
|
133
133
|
Plot a (Multi)LineString/LinearRing.
|
|
134
134
|
|
|
135
|
-
Note: this function is experimental, and mainly
|
|
135
|
+
Note: this function is experimental, and mainly targeting (interactive)
|
|
136
136
|
exploration, debugging and illustration purposes.
|
|
137
137
|
|
|
138
138
|
Parameters
|
|
@@ -144,7 +144,7 @@ def plot_line(line, ax=None, add_points=True, color=None, linewidth=2, **kwargs)
|
|
|
144
144
|
add_points : bool, default True
|
|
145
145
|
If True, also plot the coordinates (vertices) as points.
|
|
146
146
|
color : matplotlib color specification
|
|
147
|
-
Color for the line (edgecolor under the hood) and
|
|
147
|
+
Color for the line (edgecolor under the hood) and points.
|
|
148
148
|
linewidth : float, default 2
|
|
149
149
|
The line width for the polygon boundary.
|
|
150
150
|
**kwargs
|
|
@@ -81,7 +81,7 @@ def is_ccw(geometry, **kwargs):
|
|
|
81
81
|
Parameters
|
|
82
82
|
----------
|
|
83
83
|
geometry : Geometry or array_like
|
|
84
|
-
This function will return False for non-linear
|
|
84
|
+
This function will return False for non-linear geometries and for
|
|
85
85
|
lines with fewer than 4 points (including the closing point).
|
|
86
86
|
**kwargs
|
|
87
87
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
@@ -748,7 +748,7 @@ def equals(a, b, **kwargs):
|
|
|
748
748
|
def intersects(a, b, **kwargs):
|
|
749
749
|
"""Returns True if A and B share any portion of space.
|
|
750
750
|
|
|
751
|
-
Intersects implies that overlaps, touches
|
|
751
|
+
Intersects implies that overlaps, touches, covers, or within are True.
|
|
752
752
|
|
|
753
753
|
Parameters
|
|
754
754
|
----------
|
|
@@ -403,7 +403,9 @@ def union_all(geometries, grid_size=None, axis=None, **kwargs):
|
|
|
403
403
|
geometries = np.rollaxis(geometries, axis=axis, start=geometries.ndim)
|
|
404
404
|
|
|
405
405
|
# create_collection acts on the inner axis
|
|
406
|
-
collections = lib.create_collection(
|
|
406
|
+
collections = lib.create_collection(
|
|
407
|
+
geometries, np.intc(GeometryType.GEOMETRYCOLLECTION)
|
|
408
|
+
)
|
|
407
409
|
|
|
408
410
|
if grid_size is not None:
|
|
409
411
|
if lib.geos_version < (3, 9, 0):
|
|
@@ -501,5 +503,7 @@ def coverage_union_all(geometries, axis=None, **kwargs):
|
|
|
501
503
|
np.asarray(geometries), axis=axis, start=geometries.ndim
|
|
502
504
|
)
|
|
503
505
|
# create_collection acts on the inner axis
|
|
504
|
-
collections = lib.create_collection(
|
|
506
|
+
collections = lib.create_collection(
|
|
507
|
+
geometries, np.intc(GeometryType.GEOMETRYCOLLECTION)
|
|
508
|
+
)
|
|
505
509
|
return lib.coverage_union(collections, **kwargs)
|
|
@@ -2,6 +2,7 @@ import numpy as np
|
|
|
2
2
|
import pytest
|
|
3
3
|
|
|
4
4
|
from shapely import LineString
|
|
5
|
+
from shapely.tests.common import line_string, line_string_z, point, point_z
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class TestCoords:
|
|
@@ -84,3 +85,18 @@ class TestXY:
|
|
|
84
85
|
assert list(x) == [0.0, 1.0]
|
|
85
86
|
assert len(y) == 2
|
|
86
87
|
assert list(y) == [0.0, 1.0]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@pytest.mark.parametrize("geom", [point, point_z, line_string, line_string_z])
|
|
91
|
+
def test_coords_array_copy(geom):
|
|
92
|
+
"""Test CoordinateSequence.__array__ method."""
|
|
93
|
+
coord_seq = geom.coords
|
|
94
|
+
assert np.array(coord_seq) is not np.array(coord_seq)
|
|
95
|
+
assert np.array(coord_seq, copy=True) is not np.array(coord_seq, copy=True)
|
|
96
|
+
|
|
97
|
+
# Behaviour of copy=False is different between NumPy 1.x and 2.x
|
|
98
|
+
if int(np.version.short_version.split(".", 1)[0]) >= 2:
|
|
99
|
+
with pytest.raises(ValueError, match="A copy is always created"):
|
|
100
|
+
np.array(coord_seq, copy=False)
|
|
101
|
+
else:
|
|
102
|
+
assert np.array(coord_seq, copy=False) is np.array(coord_seq, copy=False)
|
|
@@ -47,7 +47,7 @@ def test_format_point():
|
|
|
47
47
|
("g", xy2, "POINT (-169.910918 -18.997564)", False),
|
|
48
48
|
("0.2g", xy2, "POINT (-169.91 -19)", False),
|
|
49
49
|
]
|
|
50
|
-
# without
|
|
50
|
+
# without precisions test GEOS rounding_precision=-1; different than Python
|
|
51
51
|
test_list += [
|
|
52
52
|
("f", (1, 2), f"POINT ({1:.16f} {2:.16f})", False),
|
|
53
53
|
("F", xyz3, "POINT Z ({:.16f} {:.16f} {:.16f})".format(*xyz3), False),
|
|
@@ -101,7 +101,9 @@ class TestPoint:
|
|
|
101
101
|
# Test 2D points
|
|
102
102
|
p = Point(1.0, 2.0)
|
|
103
103
|
assert p.x == 1.0
|
|
104
|
+
assert type(p.x) is float
|
|
104
105
|
assert p.y == 2.0
|
|
106
|
+
assert type(p.y) is float
|
|
105
107
|
assert p.coords[:] == [(1.0, 2.0)]
|
|
106
108
|
assert str(p) == p.wkt
|
|
107
109
|
assert p.has_z is False
|
|
@@ -114,6 +116,7 @@ class TestPoint:
|
|
|
114
116
|
assert str(p) == p.wkt
|
|
115
117
|
assert p.has_z is True
|
|
116
118
|
assert p.z == 3.0
|
|
119
|
+
assert type(p.z) is float
|
|
117
120
|
|
|
118
121
|
# Coordinate access
|
|
119
122
|
p = Point((3.0, 4.0))
|
|
@@ -3,6 +3,7 @@ import unittest
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
5
|
import shapely
|
|
6
|
+
from shapely import geos_version
|
|
6
7
|
from shapely.errors import TopologicalError
|
|
7
8
|
from shapely.geometry import GeometryCollection, LineString, MultiPoint, Point, Polygon
|
|
8
9
|
from shapely.wkt import loads
|
|
@@ -79,8 +80,11 @@ class OperationsTestCase(unittest.TestCase):
|
|
|
79
80
|
"POLYGON ((40 100, 80 100, 80 60, 40 60, 40 100), (60 60, 80 60, 80 40, 60 40, 60 60))"
|
|
80
81
|
)
|
|
81
82
|
assert not invalid_polygon.is_valid
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
if geos_version < (3, 13, 0):
|
|
84
|
+
with pytest.raises((TopologicalError, shapely.GEOSException)):
|
|
85
|
+
invalid_polygon.relate(invalid_polygon)
|
|
86
|
+
else: # resolved with RelateNG
|
|
87
|
+
assert invalid_polygon.relate(invalid_polygon) == "2FFF1FFF2"
|
|
84
88
|
|
|
85
89
|
def test_hausdorff_distance(self):
|
|
86
90
|
point = Point(1, 1)
|