shapely 2.1.0rc1__tar.gz → 2.1.2__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.1.0rc1 → shapely-2.1.2}/CHANGES.txt +19 -70
- {shapely-2.1.0rc1 → shapely-2.1.2}/CITATION.cff +2 -2
- {shapely-2.1.0rc1 → shapely-2.1.2}/PKG-INFO +4 -2
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/coverage.rst +2 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/geometry.rst +28 -14
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/manual.rst +1 -28
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/migration.rst +27 -26
- {shapely-2.1.0rc1 → shapely-2.1.2}/pyproject.toml +2 -1
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_geometry_helpers.pyx +46 -11
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_version.py +3 -3
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/decorators.py +84 -34
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/io.py +2 -1
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/set_operations.py +3 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_polylabel.py +4 -1
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_constructive.py +6 -4
- shapely-2.1.2/shapely/tests/test_decorators.py +138 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_measurement.py +1 -1
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_ragged_array.py +77 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_set_operations.py +5 -1
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely.egg-info/PKG-INFO +4 -2
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely.egg-info/SOURCES.txt +1 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/CREDITS.txt +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/LICENSE.txt +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/README.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/constructive.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/coordinates.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/creation.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/design.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/index.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/installation.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/io.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/linear.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/measurement.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/migration_pygeos.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/plotting.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/predicates.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/properties.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/release.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/set_operations.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/strtree.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/docs/testing.rst +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/setup.cfg +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/setup.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_coverage.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_enum.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_geometry.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_geos.pxd +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_geos.pyx +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_pygeos_api.pxd +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/_ragged_array.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/affinity.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/algorithms/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/algorithms/_oriented_envelope.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/algorithms/cga.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/algorithms/polylabel.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/conftest.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/constructive.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/coordinates.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/coords.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/creation.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/errors.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/base.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/collection.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/geo.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/linestring.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/multilinestring.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/multipoint.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/multipolygon.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/point.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geometry/polygon.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/geos.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/linear.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/measurement.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/ops.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/plotting.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/predicates.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/prepared.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/speedups.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/strtree.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/testing.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/common.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_collection.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_coords.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_decimal.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_emptiness.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_equality.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_format.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_geometry_base.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_hash.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_linestring.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_multi.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_multilinestring.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_multipoint.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_multipolygon.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_point.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/geometry/test_polygon.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/conftest.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_affinity.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_box.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_buffer.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_cga.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_clip_by_rect.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_create_inconsistent_dimensionality.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_delaunay.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_empty_polygons.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_equality.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_geointerface.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_invalid_geometries.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_linear_referencing.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_linemerge.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_locale.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_make_valid.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_mapping.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_minimum_clearance.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_ndarrays.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_nearest.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_operations.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_operators.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_orient.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_parallel_offset.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_persist.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_pickle.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_polygonize.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_predicates.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_prepared.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_products_z.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_shape.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_shared_paths.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_singularity.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_snap.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_split.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_substring.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_svg.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_transform.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_union.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_validation.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_vectorized.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_voronoi_diagram.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_wkb.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/test_wkt.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/legacy/threading_test.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_coordinates.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_coverage.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_creation.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_creation_indices.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_geometry.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_io.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_linear.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_misc.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_plotting.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_predicates.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_strtree.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/tests/test_testing.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/validation.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/vectorized/__init__.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/wkb.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely/wkt.py +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely.egg-info/dependency_links.txt +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely.egg-info/requires.txt +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/shapely.egg-info/top_level.txt +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/c_api.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/c_api.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/coords.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/coords.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/fast_loop_macros.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/geos.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/geos.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/kvec.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/lib.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/pygeom.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/pygeom.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/pygeos.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/pygeos.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/strtree.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/strtree.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/ufuncs.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/ufuncs.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/vector.c +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/src/vector.h +0 -0
- {shapely-2.1.0rc1 → shapely-2.1.2}/versioneer.py +0 -0
|
@@ -1,88 +1,37 @@
|
|
|
1
1
|
Changes
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
-
2.1.
|
|
4
|
+
2.1.2 (2025-09-24)
|
|
5
5
|
------------------
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Wheels are available for Python 3.14 (and still include GEOS 3.13.1).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
now use the ``handle_nan`` parameter in construction functions.
|
|
9
|
+
|
|
10
|
+
2.1.1 (2025-05-19)
|
|
11
|
+
------------------
|
|
13
12
|
|
|
14
13
|
Bug fixes:
|
|
15
14
|
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- Fixes ``GeometryCollection()`` constructor accepting an array of geometries (#2017).
|
|
15
|
+
- Fix performance degradation calling shapely functions (caused by deprecation
|
|
16
|
+
of certain positional arguments) (#2283).
|
|
17
|
+
- Fix crash caused by `from_ragged_array()` (#2291).
|
|
18
|
+
- Fix compilation error building with recent LLVM toolchain (#2293).
|
|
21
19
|
|
|
22
|
-
Improvements:
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
error on nonfinite (NaN / Inf) coordinates. The default behaviour (allow) is
|
|
27
|
-
backwards compatible (#1594, #1811).
|
|
28
|
-
- Add an ``interleaved`` parameter to ``shapely.transform()`` allowing a transposed call
|
|
29
|
-
signature in the ``transformation`` function.
|
|
30
|
-
- The ``include_z`` in ``shapely.transform()`` now also allows ``None``, which
|
|
31
|
-
lets it automatically detect the dimensionality of each input geometry.
|
|
32
|
-
- Add an ``include_m`` keyword in ``to_ragged_array`` and ``get_coordinates`` (#2234, #2235)
|
|
33
|
-
- Add parameters ``method`` and ``keep_collapsed`` to ``shapely.make_valid()`` (#1941)
|
|
34
|
-
- The ``voronoi_polygons`` now accepts the ``ordered`` keyword, optionally forcing the
|
|
35
|
-
order of polygons within the GeometryCollection to follow the order of input
|
|
36
|
-
coordinates. Requires at least GEOS 3.12. (#1968)
|
|
37
|
-
- Add option on ``invalid="fix"`` to ``from_wkb`` and ``from_wkt`` (#2094)
|
|
38
|
-
- Add a ``normalize`` keyword to ``equals_exact`` (#1231)
|
|
39
|
-
- Handle ``Feature`` type in ``shapely.geometry.shape`` (#1815)
|
|
40
|
-
- Add support to split polygons by multilinestrings (#2206)
|
|
41
|
-
- Add an ``m`` attribute on the Point class and an ``has_m`` attribute on the base Geometry class.
|
|
42
|
-
|
|
43
|
-
New functions:
|
|
44
|
-
|
|
45
|
-
- Add ``disjoint_subset_union`` and ``disjoint_subset_union_all`` as an optimized
|
|
46
|
-
version of union and union_all, assuming inputs can be divided into subsets that do
|
|
47
|
-
not intersect. Requires at least GEOS 3.12.
|
|
48
|
-
- Add function ``minimum_clearance_line`` (#2106)
|
|
49
|
-
- Add function ``maximum_inscribed_circle`` (#1307)
|
|
50
|
-
- Add function ``orient_polygons`` (#2147)
|
|
51
|
-
- Add function ``constrained_delaunay_triangles`` (#1685)
|
|
52
|
-
- Add function ``coverage_simplify`` to allow topological simplification of polygonal
|
|
53
|
-
coverages (#1969)
|
|
54
|
-
- Add function ``coverage_is_valid`` and ``coverage_invalid_edges`` to validate
|
|
55
|
-
an array of geometries as valid topological coverage (#2156)
|
|
56
|
-
- Add function ``equals_identical`` (#1760)
|
|
57
|
-
- Add function ``has_m`` (#2008)
|
|
58
|
-
- Add function ``get_m`` (#2019)
|
|
59
|
-
|
|
60
|
-
Breaking changes in GEOS 3.12:
|
|
61
|
-
|
|
62
|
-
- ``oriented_envelope`` / ``minimum_rotated_rectangle`` changed its implementation
|
|
63
|
-
in GEOS 3.12. Be aware that results will change when updating GEOS. Coincidentally
|
|
64
|
-
the implementation is similar to the shapely 1.x approach. (#1885)
|
|
65
|
-
- ``get_coordinate_dimension`` / ``has_z`` now considers geometries three dimensional if
|
|
66
|
-
they have a NaN z coordinate. (#1885)
|
|
67
|
-
- ``voronoi_polygons`` changed its output from a LINESTRING to a MULTILINESTRING in case
|
|
68
|
-
``only_edges=True``. (#1885)
|
|
69
|
-
- The WKT representation of a MULTIPOINT changed from for example "MULTIPOINT (0 0, 1 1)"
|
|
70
|
-
to "MULTIPOINT ((0 0), (1 1))". (#1885)
|
|
21
|
+
2.1.0 (2025-04-03)
|
|
22
|
+
------------------
|
|
71
23
|
|
|
72
|
-
|
|
24
|
+
Shapely 2.1.0 is a feature release with various new functions,
|
|
25
|
+
improvements and bug fixes. Highlights include initial support for geometries
|
|
26
|
+
with M or ZM values, functionality for coverage validation and
|
|
27
|
+
simplification, and a set of new top-level functions.
|
|
73
28
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
shapely 2.0) (#2145).
|
|
77
|
-
- The ``shapely.vectorized`` module is deprecated. The two functions (``contains and
|
|
78
|
-
``touches``) can be replaced by the top-level vectorized functions ``contains_xy``
|
|
79
|
-
and ``intersects_xy`` (#1630).
|
|
29
|
+
Shapely supports Python >= 3.10, and binary wheels on PyPI include GEOS 3.13.1
|
|
30
|
+
and are now also provided for musllinux (Alpine) x86_64 platforms.
|
|
80
31
|
|
|
81
|
-
|
|
32
|
+
For a full changelog, see
|
|
33
|
+
https://shapely.readthedocs.io/en/latest/release/2.x.html#version-2-1-0
|
|
82
34
|
|
|
83
|
-
- Require GEOS >= 3.9, NumPy >= 1.21, and Python >= 3.10 (#1802, #1885, #2124)
|
|
84
|
-
- Binary wheels are now built for musllinux (Alpine) x86_64 platforms (#1996).
|
|
85
|
-
- Upgraded the GEOS version in the binary wheel distributions to 3.13.1.
|
|
86
35
|
|
|
87
36
|
2.0.7 (2025-01-30)
|
|
88
37
|
------------------
|
|
@@ -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.
|
|
6
|
-
date-released: "2025-
|
|
5
|
+
version: "2.1.2"
|
|
6
|
+
date-released: "2025-09-24"
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: shapely
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Manipulation and analysis of geometric objects
|
|
5
5
|
Author: Sean Gillies
|
|
6
6
|
Maintainer: Shapely contributors
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
24
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
24
25
|
Requires-Python: >=3.10
|
|
25
26
|
Description-Content-Type: text/x-rst
|
|
@@ -35,6 +36,7 @@ Requires-Dist: matplotlib; extra == "docs"
|
|
|
35
36
|
Requires-Dist: sphinx; extra == "docs"
|
|
36
37
|
Requires-Dist: sphinx-book-theme; extra == "docs"
|
|
37
38
|
Requires-Dist: sphinx-remove-toctrees; extra == "docs"
|
|
39
|
+
Dynamic: license-file
|
|
38
40
|
|
|
39
41
|
=======
|
|
40
42
|
Shapely
|
|
@@ -84,7 +84,7 @@ Therefore, geometries are equal if and only if their WKB representations are equ
|
|
|
84
84
|
>>> point_1 = Point(5.2, 52.1)
|
|
85
85
|
>>> point_2 = Point(1, 1)
|
|
86
86
|
>>> point_3 = Point(5.2, 52.1)
|
|
87
|
-
>>> {point_1, point_2, point_3}
|
|
87
|
+
>>> {point_1, point_2, point_3} # doctest: +SKIP
|
|
88
88
|
{<POINT (1 1)>, <POINT (5.2 52.1)>}
|
|
89
89
|
|
|
90
90
|
.. warning:: Due to limitations of WKB, linearrings will equal linestrings if they contain the exact same points.
|
|
@@ -113,9 +113,9 @@ The most convenient is to use ``.wkb_hex`` and ``.wkt`` properties.
|
|
|
113
113
|
>>> from shapely import Point, to_wkb, to_wkt, to_geojson
|
|
114
114
|
>>> pt = Point(-169.910918, -18.997564)
|
|
115
115
|
>>> pt.wkb_hex
|
|
116
|
-
0101000000CF6A813D263D65C0BDAAB35A60FF32C0
|
|
116
|
+
'0101000000CF6A813D263D65C0BDAAB35A60FF32C0'
|
|
117
117
|
>>> pt.wkt
|
|
118
|
-
POINT (-169.910918 -18.997564)
|
|
118
|
+
'POINT (-169.910918 -18.997564)'
|
|
119
119
|
|
|
120
120
|
More output options can be found using using :func:`~shapely.to_wkb`,
|
|
121
121
|
:func:`~shapely.to_wkt`, and :func:`~shapely.to_geojson` functions.
|
|
@@ -123,9 +123,9 @@ More output options can be found using using :func:`~shapely.to_wkb`,
|
|
|
123
123
|
.. code:: python
|
|
124
124
|
|
|
125
125
|
>>> to_wkb(pt, hex=True, byte_order=0)
|
|
126
|
-
0000000001C0653D263D816ACFC032FF605AB3AABD
|
|
126
|
+
'0000000001C0653D263D816ACFC032FF605AB3AABD'
|
|
127
127
|
>>> to_wkt(pt, rounding_precision=3)
|
|
128
|
-
POINT (-169.911 -18.998)
|
|
128
|
+
'POINT (-169.911 -18.998)'
|
|
129
129
|
>>> print(to_geojson(pt, indent=2))
|
|
130
130
|
{
|
|
131
131
|
"type": "Point",
|
|
@@ -158,21 +158,35 @@ Semantic for format specification
|
|
|
158
158
|
|
|
159
159
|
Format types ``'f'`` and ``'F'`` are to use a fixed-point notation, which is
|
|
160
160
|
activated by setting GEOS' trim option off.
|
|
161
|
-
The upper case variant converts ``nan`` to ``NAN`` and ``inf`` to ``INF``.
|
|
162
161
|
|
|
163
|
-
Format types ``'g'`` and ``'G'`` are to use a "general format",
|
|
162
|
+
Format types ``'g'`` (default) and ``'G'`` are to use a "general format",
|
|
164
163
|
where unnecessary digits are trimmed. This notation is activated by setting
|
|
165
|
-
GEOS' trim option on.
|
|
166
|
-
|
|
167
|
-
is required. Note that this representation may be different for GEOS 3.10.0
|
|
168
|
-
and later, which does not use scientific notation.
|
|
164
|
+
GEOS' trim option on. This option sometimes enables
|
|
165
|
+
:ref:`scientific-formatting`.
|
|
169
166
|
|
|
170
|
-
For numeric outputs ``
|
|
167
|
+
For numeric outputs ``[fFgG]``, the precision is optional, and if not
|
|
171
168
|
specified, rounding precision will be disabled showing full precision.
|
|
172
169
|
|
|
173
170
|
Format types ``'x'`` and ``'X'`` show a hex-encoded string representation of
|
|
174
|
-
WKB or Well-Known Binary
|
|
175
|
-
|
|
171
|
+
WKB or Well-Known Binary.
|
|
172
|
+
|
|
173
|
+
The upper case letter variant converts all non-numeric values to uppercase,
|
|
174
|
+
e.g. ``nan`` to ``NAN``, or ``e`` to ``E``.
|
|
175
|
+
|
|
176
|
+
.. _scientific-formatting:
|
|
177
|
+
|
|
178
|
+
Scientific formatting
|
|
179
|
+
---------------------
|
|
180
|
+
|
|
181
|
+
WKT outputs may sometimes use scientific formatting, depending on the GEOS
|
|
182
|
+
version, coordinate value and WKT writer options. GEOS versions 3.10 to 3.12
|
|
183
|
+
never use scientific formatting (only showing positional), while older and
|
|
184
|
+
newer versions may use scientific formatting for large and small coordinate
|
|
185
|
+
values (e.g. ``POINT (1.234e+18 1.234e-11)``).
|
|
186
|
+
|
|
187
|
+
Scientific formatting can always be disabled by setting ``trim=False`` for
|
|
188
|
+
:func:`~shapely.to_wkt` or other WKT writer methods,
|
|
189
|
+
which sets the WKT writer to use fixed-precision number formatting.
|
|
176
190
|
|
|
177
191
|
.. _canonical-form:
|
|
178
192
|
|
|
@@ -1285,34 +1285,7 @@ and that copies of these are collected into a list
|
|
|
1285
1285
|
>>> features = [c, a, d, b, c]
|
|
1286
1286
|
|
|
1287
1287
|
that we'd prefer to have ordered as ``[d, c, c, b, a]`` in reverse containment
|
|
1288
|
-
order.
|
|
1289
|
-
function that operates on each list element and returns a value for comparison.
|
|
1290
|
-
Our key function will be a wrapper class that implements ``__lt__()`` using
|
|
1291
|
-
Shapely's binary :meth:`~object.within` predicate.
|
|
1292
|
-
|
|
1293
|
-
.. code-block:: python
|
|
1294
|
-
|
|
1295
|
-
>>> class Within:
|
|
1296
|
-
... def __init__(self, o):
|
|
1297
|
-
... self.o = o
|
|
1298
|
-
... def __lt__(self, other):
|
|
1299
|
-
... return self.o.within(other.o)
|
|
1300
|
-
|
|
1301
|
-
As the howto says, the `less than` comparison is guaranteed to be used in
|
|
1302
|
-
sorting. That's what we'll rely on to spatially sort. Trying it out on features
|
|
1303
|
-
`d` and `c`, we see that it works.
|
|
1304
|
-
|
|
1305
|
-
.. code-block:: pycon
|
|
1306
|
-
|
|
1307
|
-
>>> Within(d) < Within(c)
|
|
1308
|
-
False
|
|
1309
|
-
|
|
1310
|
-
It also works on the list of features, producing the order we want.
|
|
1311
|
-
|
|
1312
|
-
.. code-block:: pycon
|
|
1313
|
-
|
|
1314
|
-
>>> [d, c, c, b, a] == sorted(features, key=Within, reverse=True)
|
|
1315
|
-
True
|
|
1288
|
+
order.
|
|
1316
1289
|
|
|
1317
1290
|
DE-9IM Relationships
|
|
1318
1291
|
--------------------
|
|
@@ -5,9 +5,9 @@ Migrating to Shapely 1.8 / 2.0
|
|
|
5
5
|
==============================
|
|
6
6
|
|
|
7
7
|
Shapely 1.8.0 is a transitional version introducing several warnings in
|
|
8
|
-
|
|
8
|
+
transition to 2.0.0.
|
|
9
9
|
|
|
10
|
-
Shapely 2.0.0
|
|
10
|
+
Shapely 2.0.0 was a major release with a refactor of the internals with
|
|
11
11
|
considerable performance improvements (based on the developments in the
|
|
12
12
|
`PyGEOS <https://github.com/pygeos/pygeos>`__ package), along with several
|
|
13
13
|
breaking changes.
|
|
@@ -33,13 +33,13 @@ can change their coordinates in-place. Illustrative code::
|
|
|
33
33
|
>>> print(line)
|
|
34
34
|
LINESTRING (0 0, 2 2)
|
|
35
35
|
|
|
36
|
-
>>> line.coords = [(0, 0), (10, 0), (10, 10)]
|
|
37
|
-
>>> print(line)
|
|
36
|
+
>>> line.coords = [(0, 0), (10, 0), (10, 10)] # doctest: +SKIP
|
|
37
|
+
>>> print(line) # doctest: +SKIP
|
|
38
38
|
LINESTRING (0 0, 10 0, 10 10)
|
|
39
39
|
|
|
40
40
|
In Shapely 1.8, this will start raising a warning::
|
|
41
41
|
|
|
42
|
-
>>> line.coords = [(0, 0), (10, 0), (10, 10)]
|
|
42
|
+
>>> line.coords = [(0, 0), (10, 0), (10, 10)] # doctest: +SKIP
|
|
43
43
|
ShapelyDeprecationWarning: Setting the 'coords' to mutate a Geometry
|
|
44
44
|
in place is deprecated, and will not be possible any more in Shapely 2.0
|
|
45
45
|
|
|
@@ -56,15 +56,16 @@ Setting custom attributes
|
|
|
56
56
|
-------------------------
|
|
57
57
|
|
|
58
58
|
Another consequence of the geometry objects becoming immutable is that
|
|
59
|
-
assigning custom attributes, which
|
|
59
|
+
assigning custom attributes, which previously worked, will no longer be
|
|
60
|
+
possible.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
Previously, custom attributes could have ben added::
|
|
62
63
|
|
|
63
|
-
>>> line.name = "my_geometry"
|
|
64
|
-
>>> line.name
|
|
64
|
+
>>> line.name = "my_geometry" # doctest: +SKIP
|
|
65
|
+
>>> line.name # doctest: +SKIP
|
|
65
66
|
'my_geometry'
|
|
66
67
|
|
|
67
|
-
In Shapely 1.8, this will
|
|
68
|
+
In Shapely 1.8, this will raise a warning, and will raise an
|
|
68
69
|
AttributeError in Shapely 2.0.
|
|
69
70
|
|
|
70
71
|
**How do I update my code?** There is no direct alternative for adding custom
|
|
@@ -85,18 +86,18 @@ Some examples of this with Shapely 1.x:
|
|
|
85
86
|
|
|
86
87
|
>>> from shapely.geometry import Point, MultiPoint
|
|
87
88
|
>>> mp = MultiPoint([(1, 1), (2, 2), (3, 3)])
|
|
88
|
-
>>> print(mp)
|
|
89
|
+
>>> print(mp) # doctest: +SKIP
|
|
89
90
|
MULTIPOINT (1 1, 2 2, 3 3)
|
|
90
|
-
>>> for part in mp:
|
|
91
|
-
... print(part)
|
|
91
|
+
>>> for part in mp: # doctest: +SKIP
|
|
92
|
+
... print(part) # doctest: +SKIP
|
|
92
93
|
POINT (1 1)
|
|
93
94
|
POINT (2 2)
|
|
94
95
|
POINT (3 3)
|
|
95
|
-
>>> print(mp[1])
|
|
96
|
+
>>> print(mp[1]) # doctest: +SKIP
|
|
96
97
|
POINT (2 2)
|
|
97
|
-
>>> len(mp)
|
|
98
|
+
>>> len(mp) # doctest: +SKIP
|
|
98
99
|
3
|
|
99
|
-
>>> list(mp)
|
|
100
|
+
>>> list(mp) # doctest: +SKIP
|
|
100
101
|
[<shapely.geometry.point.Point at 0x7f2e0912bf10>,
|
|
101
102
|
<shapely.geometry.point.Point at 0x7f2e09fed820>,
|
|
102
103
|
<shapely.geometry.point.Point at 0x7f2e09fed4c0>]
|
|
@@ -104,8 +105,8 @@ Some examples of this with Shapely 1.x:
|
|
|
104
105
|
Starting with Shapely 1.8, all the examples above will start raising a
|
|
105
106
|
deprecation warning. For example:
|
|
106
107
|
|
|
107
|
-
>>> for part in mp:
|
|
108
|
-
... print(part)
|
|
108
|
+
>>> for part in mp: # doctest: +SKIP
|
|
109
|
+
... print(part) # doctest: +SKIP
|
|
109
110
|
ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated
|
|
110
111
|
and will be removed in Shapely 2.0. Use the `geoms` property to access the
|
|
111
112
|
constituent parts of a multi-part geometry.
|
|
@@ -129,7 +130,7 @@ The examples above can be updated to::
|
|
|
129
130
|
POINT (2 2)
|
|
130
131
|
>>> len(mp.geoms)
|
|
131
132
|
3
|
|
132
|
-
>>> list(mp.geoms)
|
|
133
|
+
>>> list(mp.geoms) # doctest: +SKIP
|
|
133
134
|
[<shapely.geometry.point.Point at 0x7f2e0912bf10>,
|
|
134
135
|
<shapely.geometry.point.Point at 0x7f2e09fed820>,
|
|
135
136
|
<shapely.geometry.point.Point at 0x7f2e09fed4c0>]
|
|
@@ -152,7 +153,7 @@ A small example::
|
|
|
152
153
|
|
|
153
154
|
>>> line = LineString([(0, 0), (1, 1), (2, 2)])
|
|
154
155
|
>>> import numpy as np
|
|
155
|
-
>>> np.asarray(line)
|
|
156
|
+
>>> np.asarray(line) # doctest: +SKIP
|
|
156
157
|
array([[0., 0.],
|
|
157
158
|
[1., 1.],
|
|
158
159
|
[2., 2.]])
|
|
@@ -160,9 +161,9 @@ A small example::
|
|
|
160
161
|
In addition, there are also the explicit ``array_interface()`` method and
|
|
161
162
|
``ctypes`` attribute to get access to the coordinates as array data:
|
|
162
163
|
|
|
163
|
-
>>> line.ctypes
|
|
164
|
+
>>> line.ctypes # doctest: +SKIP
|
|
164
165
|
<shapely.geometry.linestring.c_double_Array_6 at 0x7f75261eb740>
|
|
165
|
-
>>> line.array_interface()
|
|
166
|
+
>>> line.array_interface() # doctest: +SKIP
|
|
166
167
|
{'version': 3,
|
|
167
168
|
'typestr': '<f8',
|
|
168
169
|
'data': <shapely.geometry.linestring.c_double_Array_6 at 0x7f752664ae40>,
|
|
@@ -177,7 +178,7 @@ removed from those geometry classes, and limited to the ``coords``.
|
|
|
177
178
|
Starting with Shapely 1.8, converting a geometry object to a NumPy array
|
|
178
179
|
directly will start raising a warning::
|
|
179
180
|
|
|
180
|
-
>>> np.asarray(line)
|
|
181
|
+
>>> np.asarray(line) # doctest: +SKIP
|
|
181
182
|
ShapelyDeprecationWarning: The array interface is deprecated and will no longer
|
|
182
183
|
work in Shapely 2.0. Convert the '.coords' to a NumPy array instead.
|
|
183
184
|
array([[0., 0.],
|
|
@@ -209,7 +210,7 @@ as follows::
|
|
|
209
210
|
|
|
210
211
|
>>> from shapely.geometry import Point
|
|
211
212
|
>>> arr = np.array([Point(0, 0), Point(1, 1), Point(2, 2)])
|
|
212
|
-
>>> arr
|
|
213
|
+
>>> arr # doctest: +SKIP
|
|
213
214
|
array([<shapely.geometry.point.Point object at 0x7fb798407cd0>,
|
|
214
215
|
<shapely.geometry.point.Point object at 0x7fb7982831c0>,
|
|
215
216
|
<shapely.geometry.point.Point object at 0x7fb798283b80>],
|
|
@@ -300,7 +301,7 @@ creation methods. A small example for an empty Polygon geometry:
|
|
|
300
301
|
>>> g1 = Polygon()
|
|
301
302
|
>>> type(g1)
|
|
302
303
|
<class 'shapely.geometry.polygon.Polygon'>
|
|
303
|
-
>>> g1.wkt
|
|
304
|
+
>>> g1.wkt # doctest: +SKIP
|
|
304
305
|
GEOMETRYCOLLECTION EMPTY
|
|
305
306
|
|
|
306
307
|
# Converting from WKT gives a correct empty polygon
|
|
@@ -309,7 +310,7 @@ creation methods. A small example for an empty Polygon geometry:
|
|
|
309
310
|
>>> type(g2)
|
|
310
311
|
<class 'shapely.geometry.polygon.Polygon'>
|
|
311
312
|
>>> g2.wkt
|
|
312
|
-
POLYGON EMPTY
|
|
313
|
+
'POLYGON EMPTY'
|
|
313
314
|
|
|
314
315
|
Shapely 1.8 does not yet change this inconsistent behaviour, but starting
|
|
315
316
|
with Shapely 2.0, the different methods will always consistently give an
|
|
@@ -35,6 +35,7 @@ classifiers = [
|
|
|
35
35
|
"Programming Language :: Python :: 3.11",
|
|
36
36
|
"Programming Language :: Python :: 3.12",
|
|
37
37
|
"Programming Language :: Python :: 3.13",
|
|
38
|
+
"Programming Language :: Python :: 3.14",
|
|
38
39
|
"Topic :: Scientific/Engineering :: GIS",
|
|
39
40
|
]
|
|
40
41
|
requires-python = ">=3.10"
|
|
@@ -74,7 +75,7 @@ skip = ["pp*", "*_i686", "*_ppc64le", "*_s390x"]
|
|
|
74
75
|
build-verbosity = 1
|
|
75
76
|
test-requires = "pytest"
|
|
76
77
|
test-command = "pytest --pyargs shapely.tests"
|
|
77
|
-
|
|
78
|
+
enable = ["cpython-freethreading"]
|
|
78
79
|
|
|
79
80
|
[tool.coverage.run]
|
|
80
81
|
source = ["shapely"]
|
|
@@ -284,7 +284,7 @@ def get_parts(object[:] array, bint extract_rings=0):
|
|
|
284
284
|
|
|
285
285
|
@cython.boundscheck(False)
|
|
286
286
|
@cython.wraparound(False)
|
|
287
|
-
cdef void _deallocate_arr(
|
|
287
|
+
cdef void _deallocate_arr(GEOSContextHandle_t handle, np.intp_t[:] arr, Py_ssize_t last_geom_i) noexcept nogil:
|
|
288
288
|
"""Deallocate a temporary geometry array to prevent memory leaks"""
|
|
289
289
|
cdef Py_ssize_t i = 0
|
|
290
290
|
cdef GEOSGeometry *g
|
|
@@ -421,7 +421,7 @@ def collections_1d(object geometries, object indices, int geometry_type = 7, obj
|
|
|
421
421
|
coll = GEOSGeom_createPolygon_r(
|
|
422
422
|
geos_handle,
|
|
423
423
|
<GEOSGeometry*> temp_geoms_view[0],
|
|
424
|
-
NULL if coll_size <= 1 else <GEOSGeometry**> &temp_geoms_view[1],
|
|
424
|
+
<GEOSGeometry**> NULL if coll_size <= 1 else <GEOSGeometry**> &temp_geoms_view[1],
|
|
425
425
|
coll_size - 1
|
|
426
426
|
)
|
|
427
427
|
else: # Polygon, empty
|
|
@@ -454,7 +454,7 @@ def _from_ragged_array_multi_linear(
|
|
|
454
454
|
MultiLineString (geometry_type 5): linear_type is a LineString (1)
|
|
455
455
|
"""
|
|
456
456
|
cdef:
|
|
457
|
-
Py_ssize_t n_geoms
|
|
457
|
+
Py_ssize_t n_total_coords, n_rings, n_geoms
|
|
458
458
|
Py_ssize_t i, k
|
|
459
459
|
Py_ssize_t i1, i2, k1, k2
|
|
460
460
|
Py_ssize_t n_coords, linear_idx
|
|
@@ -463,12 +463,26 @@ def _from_ragged_array_multi_linear(
|
|
|
463
463
|
GEOSGeometry *linear = NULL
|
|
464
464
|
GEOSGeometry *geom = NULL
|
|
465
465
|
|
|
466
|
+
n_total_coords = coordinates.shape[0]
|
|
467
|
+
n_rings = offsets1.shape[0] - 1
|
|
466
468
|
n_geoms = offsets2.shape[0] - 1
|
|
467
469
|
|
|
470
|
+
if offsets2[n_geoms] > n_rings:
|
|
471
|
+
raise ValueError(
|
|
472
|
+
f"Number of rings indicated by the geometry offsets ({offsets2[n_geoms]}) "
|
|
473
|
+
f"larger than indicated by the shape of the linear offsets array ({n_rings})"
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
if offsets1[n_rings] > n_total_coords:
|
|
477
|
+
raise ValueError(
|
|
478
|
+
f"Number of coordinates indicated by the linear offsets ({offsets1[n_rings]}) "
|
|
479
|
+
f"larger than the shape of the coordinates array ({n_total_coords})"
|
|
480
|
+
)
|
|
481
|
+
|
|
468
482
|
# A temporary array for the geometries that will be given to CreatePolygon/Collection.
|
|
469
|
-
# For simplicity, we use
|
|
470
|
-
#
|
|
471
|
-
temp_linear = np.empty(shape=(
|
|
483
|
+
# For simplicity, we use n_rings instead of calculating the max needed size
|
|
484
|
+
# as max(diff(offsets2)) (trading performance for a bit more memory usage)
|
|
485
|
+
temp_linear = np.empty(shape=(n_rings, ), dtype=np.intp)
|
|
472
486
|
cdef np.intp_t[:] temp_linear_view = temp_linear
|
|
473
487
|
# A temporary array for resulting geometries
|
|
474
488
|
temp_geoms = np.empty(shape=(n_geoms, ), dtype=np.intp)
|
|
@@ -570,7 +584,7 @@ def _from_ragged_array_multipolygon(
|
|
|
570
584
|
Create MultiPolygons from coordinate and offset arrays.
|
|
571
585
|
"""
|
|
572
586
|
cdef:
|
|
573
|
-
Py_ssize_t n_geoms
|
|
587
|
+
Py_ssize_t n_total_coords, n_rings, n_parts, n_geoms
|
|
574
588
|
Py_ssize_t i, j, k
|
|
575
589
|
Py_ssize_t i1, i2, j1, j2, k1, k2
|
|
576
590
|
Py_ssize_t n_coords, rings_idx, parts_idx
|
|
@@ -580,14 +594,35 @@ def _from_ragged_array_multipolygon(
|
|
|
580
594
|
GEOSGeometry *part = NULL
|
|
581
595
|
GEOSGeometry *geom = NULL
|
|
582
596
|
|
|
597
|
+
n_total_coords = coordinates.shape[0]
|
|
598
|
+
n_rings = offsets1.shape[0] - 1
|
|
599
|
+
n_parts = offsets2.shape[0] - 1
|
|
583
600
|
n_geoms = offsets3.shape[0] - 1
|
|
584
601
|
|
|
602
|
+
if offsets3[n_geoms] > n_parts:
|
|
603
|
+
raise ValueError(
|
|
604
|
+
f"Number of geometry parts indicated by the geometry offsets ({offsets3[n_geoms]}) "
|
|
605
|
+
f"larger than indicated by the shape of the part offsets array ({n_parts})"
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
if offsets2[n_parts] > n_rings:
|
|
609
|
+
raise ValueError(
|
|
610
|
+
f"Number of rings indicated by the part offsets ({offsets2[n_parts]}) "
|
|
611
|
+
f"larger than indicated by the shape of the linear offsets array ({n_rings})"
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
if offsets1[n_rings] > n_total_coords:
|
|
615
|
+
raise ValueError(
|
|
616
|
+
f"Number of coordinates indicated by the linear offsets ({offsets1[n_rings]}) "
|
|
617
|
+
f"larger than the shape of the coordinates array ({n_total_coords})"
|
|
618
|
+
)
|
|
619
|
+
|
|
585
620
|
# A temporary array for the geometries that will be given to CreatePolygon
|
|
586
|
-
# and CreateCollection. For simplicity, we use
|
|
587
|
-
# the max needed size (trading performance for a bit more memory usage)
|
|
588
|
-
temp_rings = np.empty(shape=(
|
|
621
|
+
# and CreateCollection. For simplicity, we use n_rings/n_parts instead of
|
|
622
|
+
# calculating the max needed size (trading performance for a bit more memory usage)
|
|
623
|
+
temp_rings = np.empty(shape=(n_rings, ), dtype=np.intp)
|
|
589
624
|
cdef np.intp_t[:] temp_rings_view = temp_rings
|
|
590
|
-
temp_parts = np.empty(shape=(
|
|
625
|
+
temp_parts = np.empty(shape=(n_parts, ), dtype=np.intp)
|
|
591
626
|
cdef np.intp_t[:] temp_parts_view = temp_parts
|
|
592
627
|
# A temporary array for resulting geometries
|
|
593
628
|
temp_geoms = np.empty(shape=(n_geoms, ), dtype=np.intp)
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-09-24T15:22:48+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.1.
|
|
14
|
+
"full-revisionid": "5fb639d1056888d135fe56bfaf750c9648addeec",
|
|
15
|
+
"version": "2.1.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|