[Git][debian-gis-team/python-geopandas][master] 6 commits: New upstream version 1.1.3
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Tue Mar 10 04:49:23 GMT 2026
Bas Couwenberg pushed to branch master at Debian GIS Project / python-geopandas
Commits:
5a5c4284 by Bas Couwenberg at 2026-03-10T05:28:55+01:00
New upstream version 1.1.3
- - - - -
b06069b4 by Bas Couwenberg at 2026-03-10T05:29:18+01:00
Update upstream source from tag 'upstream/1.1.3'
Update to upstream version '1.1.3'
with Debian dir 9e7f6a079d6427865647d36d5f7cf96bcc2e1f20
- - - - -
57577700 by Bas Couwenberg at 2026-03-10T05:34:36+01:00
New upstream release.
- - - - -
e5c2185a by Bas Couwenberg at 2026-03-10T05:38:58+01:00
Add python3-pointpats to build dependencies.
- - - - -
28bb716c by Bas Couwenberg at 2026-03-10T05:40:47+01:00
Refresh patches.
- - - - -
2eeecb63 by Bas Couwenberg at 2026-03-10T05:40:57+01:00
Set distribution to unstable.
- - - - -
22 changed files:
- .github/workflows/release_to_pypi.yml → .github/workflows/release.yml
- .github/workflows/tests.yaml
- CHANGELOG.md
- debian/changelog
- debian/control
- debian/patches/pandas2_compat.patch
- geopandas/_compat.py
- geopandas/_version.py
- geopandas/array.py
- geopandas/base.py
- geopandas/geodataframe.py
- geopandas/geoseries.py
- geopandas/io/sql.py
- geopandas/io/tests/test_sql.py
- geopandas/tests/test_crs.py
- geopandas/tests/test_geodataframe.py
- geopandas/tests/test_geom_methods.py
- geopandas/tests/test_geoseries.py
- geopandas/tests/test_op_output_types.py
- geopandas/tests/test_sindex.py
- geopandas/tools/clip.py
- pyproject.toml
Changes:
=====================================
.github/workflows/release_to_pypi.yml → .github/workflows/release.yml
=====================================
@@ -9,6 +9,11 @@ jobs:
build-n-publish:
name: Build and publish geopandas to PyPI
runs-on: ubuntu-latest
+ environment:
+ name: pypi
+ url: https://pypi.org/p/geopandas
+ permissions:
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Checkout source
@@ -27,9 +32,6 @@ jobs:
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish at release/v1
- with:
- user: __token__
- password: ${{ secrets.PYPI_API_TOKEN }}
- name: Create GitHub Release
id: create_release
=====================================
.github/workflows/tests.yaml
=====================================
@@ -58,7 +58,6 @@ jobs:
- env: ci/envs/312-dev.yaml
os: ubuntu-latest
dev: true
- pandas_future_infer_string: "1"
steps:
- uses: actions/checkout at v4
@@ -76,8 +75,6 @@ jobs:
micromamba list
- name: Test
- env:
- PANDAS_FUTURE_INFER_STRING: ${{ matrix.pandas_future_infer_string || '0' }}
run: |
pytest -v -r a -n auto --color=yes --cov=geopandas --cov-append --cov-report term-missing --cov-report xml geopandas/
=====================================
CHANGELOG.md
=====================================
@@ -1,5 +1,17 @@
# Changelog
+## Version 1.1.3 (March 10, 2026)
+
+Bug fixes:
+- Improved compatibility with pandas 3.0 Copy-on-Write feature, making use of deferred copies where possible (#3298, #3711).
+- Fix `GeoSeries.sample_points` not accepting list-like `size` when generating points using
+ `pointpaterns` (#3710).
+- Fix `from_wkt/wkb` to correctly handle missing values with pandas 3 (where the new `str` dtype is used) (#3714).
+- Fix `to_postgis` to correctly handle missing values with pandas 3 (where the new `str` dtype is used) (#3722).
+- Using `loc` to assign column values to a new row index now correctly preserves the column CRS and geometry dtype
+ on pandas 3.1, due to an upstream bug fix (#3741, Pandas #62523)
+- Random states in ``pointpats`` methods of ``sample_points`` can now be fixed with ``rng`` (#3737).
+
## Version 1.1.2 (December 22, 2025)
Bug fixes:
@@ -1057,7 +1069,7 @@ New features and improvements:
- Addition of a ``GeoDataFrame.rename_geometry`` method to easily rename the active geometry column (#1053).
- Addition of ``geopandas.show_versions()`` function, which can be used to give an overview of the installed libraries in bug reports (#899).
- The ``legend_kwds`` keyword of the ``plot()`` method can now also be used to specify keywords for the color bar (#1102).
-- Performance improvement in the ``sjoin()`` operation by re-using existing spatial index of the input dataframes, if available (#789).
+- Performance improvement in the ``sjoin()`` operation by reusing existing spatial index of the input dataframes, if available (#789).
- Updated documentation to work with latest version of geoplot and contextily (#1044, #1088).
- A new ``geopandas.options`` configuration, with currently a single option to control the display precision of the coordinates (``options.display_precision``). The default is now to show less coordinates (3 for projected and 5 for geographic coordinates), but the default can be overridden with the option.
=====================================
debian/changelog
=====================================
@@ -1,3 +1,12 @@
+python-geopandas (1.1.3-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+ * Add python3-pointpats to build dependencies.
+ * Refresh patches.
+
+ -- Bas Couwenberg <sebastic at debian.org> Tue, 10 Mar 2026 05:40:50 +0100
+
python-geopandas (1.1.2-2) unstable; urgency=medium
[ Bas Couwenberg ]
=====================================
debian/control
=====================================
@@ -20,6 +20,7 @@ Build-Depends: debhelper-compat (= 13),
python3-numpy,
python3-numpydoc,
python3-pandas,
+ python3-pointpats,
python3-psycopg2,
python3-pyogrio,
python3-pyproj,
=====================================
debian/patches/pandas2_compat.patch
=====================================
@@ -7,7 +7,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
--- a/geopandas/tests/test_geom_methods.py
+++ b/geopandas/tests/test_geom_methods.py
-@@ -1675,7 +1675,7 @@ class TestGeomMethods:
+@@ -1683,7 +1683,7 @@ class TestGeomMethods:
names=[index_name, None],
)
expected_df = expected_df.set_index(expected_index)
@@ -16,7 +16,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
@pytest.mark.parametrize("index_name", [None, "test"])
def test_explode_geodataframe_level_1(self, index_name):
-@@ -1694,7 +1694,7 @@ class TestGeomMethods:
+@@ -1702,7 +1702,7 @@ class TestGeomMethods:
names=[index_name, None],
)
expected_df = expected_df.set_index(expected_index)
@@ -25,7 +25,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
@pytest.mark.parametrize("index_name", [None, "test"])
def test_explode_geodataframe_no_multiindex(self, index_name):
-@@ -1800,7 +1800,7 @@ class TestGeomMethods:
+@@ -1808,7 +1808,7 @@ class TestGeomMethods:
names=["first", "second", None],
)
expected_df = expected_df.set_index(expected_index)
@@ -34,7 +34,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
@pytest.mark.parametrize("outer_index", [1, (1, 2), "1"])
def test_explode_pandas_multi_index_false(self, outer_index):
-@@ -1901,7 +1901,7 @@ class TestGeomMethods:
+@@ -1909,7 +1909,7 @@ class TestGeomMethods:
geometry=expected_geometry,
index=expected_index,
)
@@ -43,7 +43,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
def test_explode_order_no_multi(self):
df = GeoDataFrame(
-@@ -1919,7 +1919,7 @@ class TestGeomMethods:
+@@ -1927,7 +1927,7 @@ class TestGeomMethods:
geometry=[Point(0, x) for x in range(3)],
index=expected_index,
)
@@ -52,7 +52,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
def test_explode_order_mixed(self):
df = GeoDataFrame(
-@@ -1947,7 +1947,7 @@ class TestGeomMethods:
+@@ -1955,7 +1955,7 @@ class TestGeomMethods:
geometry=expected_geometry,
index=expected_index,
)
@@ -61,7 +61,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
def test_explode_duplicated_index(self):
df = GeoDataFrame(
-@@ -1975,7 +1975,7 @@ class TestGeomMethods:
+@@ -1983,7 +1983,7 @@ class TestGeomMethods:
geometry=expected_geometry,
index=expected_index,
)
@@ -70,7 +70,7 @@ Applied-Upstream: https://github.com/geopandas/geopandas/commit/45fbc51ea309a9c9
@pytest.mark.parametrize("geom_col", ["geom", "geometry"])
def test_explode_geometry_name(self, geom_col):
-@@ -2070,7 +2070,7 @@ class TestGeomMethods:
+@@ -2078,7 +2078,7 @@ class TestGeomMethods:
]
),
)
=====================================
geopandas/_compat.py
=====================================
@@ -13,7 +13,8 @@ PANDAS_GE_202 = Version(pd.__version__) >= Version("2.0.2")
PANDAS_GE_21 = Version(pd.__version__) >= Version("2.1.0")
PANDAS_GE_22 = Version(pd.__version__) >= Version("2.2.0")
PANDAS_GE_23 = Version(pd.__version__) >= Version("2.3.0")
-PANDAS_GE_30 = Version(pd.__version__) >= Version("3.0.0.dev0")
+PANDAS_GE_30 = Version(pd.__version__) >= Version("3.0.0")
+PANDAS_GE_31 = Version(pd.__version__) >= Version("3.1.0.dev0")
PANDAS_INFER_STR = PANDAS_GE_23 and pd.options.future.infer_string
=====================================
geopandas/_version.py
=====================================
@@ -25,9 +25,9 @@ def get_keywords() -> Dict[str, str]:
# setup.py/versioneer.py will grep for the variable names, so they must
# each be defined on a line of their own. _version.py will just call
# get_keywords().
- git_refnames = " (tag: v1.1.2, 1.1.x)"
- git_full = "81214bf9f3eaba9f5fdcfd141ae8d16fa17fd860"
- git_date = "2025-12-22 22:04:52 +0100"
+ git_refnames = " (tag: v1.1.3, 1.1.x)"
+ git_full = "f5fe3ff5f0e473603cd0e81673d9f1f300f4975d"
+ git_date = "2026-03-10 08:34:35 +1100"
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
return keywords
=====================================
geopandas/array.py
=====================================
@@ -219,6 +219,8 @@ def from_wkb(data, crs=None, on_invalid="raise"):
without a warning. Requires GEOS >= 3.11 and shapely >= 2.1.
"""
+ if isinstance(data, ExtensionArray):
+ data = data.to_numpy(na_value=None)
return GeometryArray(shapely.from_wkb(data, on_invalid=on_invalid), crs=crs)
@@ -251,6 +253,8 @@ def from_wkt(data, crs=None, on_invalid="raise"):
without a warning. Requires GEOS >= 3.11 and shapely >= 2.1.
"""
+ if isinstance(data, ExtensionArray):
+ data = data.to_numpy(na_value=None)
return GeometryArray(shapely.from_wkt(data, on_invalid=on_invalid), crs=crs)
@@ -423,6 +427,18 @@ class GeometryArray(ExtensionArray):
def __getitem__(self, idx):
if isinstance(idx, numbers.Integral):
return self._data[idx]
+ elif (
+ isinstance(idx, slice)
+ and idx.start is None
+ and idx.stop is None
+ and idx.step is None
+ ):
+ # special case of a full slice -> preserve the sindex
+ # (to ensure view() preserves it as well)
+ result = GeometryArray(self._data[idx], crs=self.crs)
+ result._sindex = self._sindex
+ return result
+
# array-like, slice
# validate and convert IntegerArray/BooleanArray
# to numpy array, pass-through non-array-like indexers
=====================================
geopandas/base.py
=====================================
@@ -6446,15 +6446,27 @@ GeometryCollection
f" available random sampling methods."
)
sample_function = getattr(pointpats.random, method)
- result = self.geometry.apply(
- lambda x: (
- points_from_xy(
- *sample_function(x, size=size, **kwargs).T
- ).union_all()
- if not (x.is_empty or x is None or "Polygon" not in x.geom_type)
- else MultiPoint()
- ),
- )
+ if pd.api.types.is_list_like(size):
+ result = [
+ (
+ points_from_xy(
+ *sample_function(x, size=s, rng=rng, **kwargs).T
+ ).union_all()
+ if not (x.is_empty or x is None or "Polygon" not in x.geom_type)
+ else MultiPoint()
+ )
+ for x, s in zip(self.geometry, size)
+ ]
+ else:
+ result = self.geometry.apply(
+ lambda x: (
+ points_from_xy(
+ *sample_function(x, size=size, rng=rng, **kwargs).T
+ ).union_all()
+ if not (x.is_empty or x is None or "Polygon" not in x.geom_type)
+ else MultiPoint()
+ ),
+ )
return GeoSeries(result, name="sampled_points", crs=self.crs, index=self.index)
=====================================
geopandas/geodataframe.py
=====================================
@@ -1264,7 +1264,7 @@ properties': {'col1': 'name1'}, 'geometry': {'type': 'Point', 'coordinates': (1.
DataFrame
geometry columns are encoded to WKB
"""
- df = DataFrame(self.copy())
+ df = DataFrame(self.copy(deep=not PANDAS_GE_30))
# Encode all geometry columns to WKB
for col in df.columns[df.dtypes == "geometry"]:
@@ -1286,7 +1286,7 @@ properties': {'col1': 'name1'}, 'geometry': {'type': 'Point', 'coordinates': (1.
DataFrame
geometry columns are encoded to WKT
"""
- df = DataFrame(self.copy())
+ df = DataFrame(self.copy(deep=not PANDAS_GE_30))
# Encode all geometry columns to WKT
for col in df.columns[df.dtypes == "geometry"]:
@@ -1730,7 +1730,7 @@ default 'snappy'
"""
if not inplace:
- df = self.copy()
+ df = self.copy(deep=not PANDAS_GE_30)
else:
df = self
df.geometry = df.geometry.set_crs(
@@ -1838,7 +1838,7 @@ default 'snappy'
if inplace:
df = self
else:
- df = self.copy()
+ df = self.copy(deep=not PANDAS_GE_30)
geom = df.geometry.to_crs(crs=crs, epsg=epsg)
df.geometry = geom
if not inplace:
=====================================
geopandas/geoseries.py
=====================================
@@ -603,7 +603,7 @@ class GeoSeries(GeoPandasBase, Series):
data = data.reindex(index)
else:
index = data.index
- data = data.values
+ data = data.to_numpy(na_value=None)
return cls(
from_wkb_or_wkt_function(data, crs=crs, on_invalid=on_invalid),
index=index,
@@ -1165,7 +1165,7 @@ class GeoSeries(GeoPandasBase, Series):
"transform the geometries, use 'GeoSeries.to_crs' instead."
)
if not inplace:
- result = self.copy()
+ result = self.copy(deep=not compat.PANDAS_GE_30)
else:
result = self
result.array.crs = crs
=====================================
geopandas/io/sql.py
=====================================
@@ -233,7 +233,7 @@ def _get_geometry_type(gdf):
has_curve = False
for gt in geom_types:
- if gt is None:
+ if pd.isna(gt):
continue
elif "LinearRing" in gt:
has_curve = True
@@ -242,7 +242,7 @@ def _get_geometry_type(gdf):
if has_curve:
target_geom_type = "LINESTRING"
else:
- if geom_types[0] is None:
+ if pd.isna(geom_types[0]):
raise ValueError("No valid geometries in the data.")
else:
target_geom_type = geom_types[0].upper()
=====================================
geopandas/io/tests/test_sql.py
=====================================
@@ -179,6 +179,23 @@ def df_mixed_single_and_multi():
return df
+ at pytest.fixture
+def df_mixed_none_geometry():
+ from shapely.geometry import MultiPolygon
+
+ df = geopandas.GeoDataFrame(
+ {
+ "geometry": [
+ None,
+ MultiPolygon([[[[0, 0], [0, 1], [1, 1], [1, 0]]]]),
+ ],
+ "id": [0, 1],
+ },
+ crs="epsg:4326",
+ )
+ return df
+
+
@pytest.fixture
def df_geom_collection():
from shapely.geometry import GeometryCollection, LineString, Point, Polygon
@@ -550,6 +567,28 @@ class TestIO:
assert geom_type.upper() == "GEOMETRYCOLLECTION"
assert df.geom_type.unique()[0] == "GeometryCollection"
+ @pytest.mark.parametrize("engine_postgis", POSTGIS_DRIVERS, indirect=True)
+ def test_write_postgis_none_geometry_types(
+ self, engine_postgis, df_mixed_none_geometry
+ ):
+ """
+ Tests that writing a mix of None and MulitPolygons is possible.
+ """
+ engine = engine_postgis
+
+ table = "geomtype_tests"
+
+ write_postgis(
+ df_mixed_none_geometry, con=engine, name=table, if_exists="replace"
+ )
+
+ # Validate geometry type
+ sql = text(f"SELECT DISTINCT GeometryType(geometry) FROM {table} ORDER BY 1;")
+ with engine.connect() as conn:
+ res = conn.execute(sql).fetchall()
+ assert res[0][0].upper() == "MULTIPOLYGON"
+ assert pd.isna(res[1][0])
+
@pytest.mark.parametrize("engine_postgis", POSTGIS_DRIVERS, indirect=True)
def test_write_postgis_mixed_geometry_types(
self, engine_postgis, df_mixed_single_and_multi
=====================================
geopandas/tests/test_crs.py
=====================================
@@ -717,7 +717,7 @@ class TestSetCRS:
naive = constructor([Point(0, 0), Point(1, 1)], crs=None)
assert naive.crs is None
- # by default returns a copy
+ # by default returns a (shallow) copy
result = naive.set_crs(crs="EPSG:4326")
assert result.crs == "EPSG:4326"
assert naive.crs is None
=====================================
geopandas/tests/test_geodataframe.py
=====================================
@@ -152,17 +152,19 @@ class TestDataFrame:
df = GeoDataFrame(data)
s = GeoSeries([Point(x, y + 1) for x, y in zip(range(5), range(5))])
+ expected = s.copy()
+
# setting geometry column
for vals in [s, s.values]:
df["geometry"] = vals
- assert_geoseries_equal(df["geometry"], s)
- assert_geoseries_equal(df.geometry, s)
+ assert_geoseries_equal(df["geometry"], expected)
+ assert_geoseries_equal(df.geometry, expected)
# non-aligned values
s2 = GeoSeries([Point(x, y + 1) for x, y in zip(range(6), range(6))])
df["geometry"] = s2
- assert_geoseries_equal(df["geometry"], s)
- assert_geoseries_equal(df.geometry, s)
+ assert_geoseries_equal(df["geometry"], expected)
+ assert_geoseries_equal(df.geometry, expected)
# setting other column with geometry values -> preserve geometry type
for vals in [s, s.values]:
@@ -254,10 +256,12 @@ class TestDataFrame:
def test_set_geometry(self):
geom = GeoSeries([Point(x, y) for x, y in zip(range(5), range(5))])
original_geom = self.df.geometry
+ expected = geom.copy()
+ expected.crs = self.df.crs
df2 = self.df.set_geometry(geom)
- assert self.df is not df2
- assert_geoseries_equal(df2.geometry, geom, check_crs=False)
+ assert df2 is not self.df
+ assert_geoseries_equal(df2.geometry, expected)
assert_geoseries_equal(self.df.geometry, original_geom)
assert_geoseries_equal(self.df["geometry"], self.df.geometry)
# unknown column
@@ -290,7 +294,7 @@ class TestDataFrame:
def test_set_geometry_col(self):
g = self.df.geometry
g_simplified = g.simplify(100)
- self.df["simplified_geometry"] = g_simplified
+ self.df["simplified_geometry"] = g_simplified.copy()
df2 = self.df.set_geometry("simplified_geometry")
# Drop is false by default
=====================================
geopandas/tests/test_geom_methods.py
=====================================
@@ -1,5 +1,6 @@
import string
import warnings
+from packaging.version import Version
import numpy as np
from pandas import DataFrame, Index, MultiIndex, Series, concat
@@ -29,6 +30,13 @@ from geopandas.tests.util import assert_geoseries_equal, geom_almost_equals, geo
from numpy.testing import assert_array_equal
from pandas.testing import assert_frame_equal, assert_index_equal, assert_series_equal
+try:
+ import pointpats
+
+ POINTPATS_GE_253 = Version(pointpats.__version__) >= Version("2.5.3")
+except ImportError:
+ POINTPATS_GE_253 = False
+
def assert_array_dtype_equal(a, b, *args, **kwargs):
a = np.asanyarray(a)
@@ -2135,23 +2143,49 @@ class TestGeomMethods:
)
assert_series_equal(shapely.get_num_geometries(output), expected)
+ @pytest.mark.parametrize("rng", [None, 1, np.random.default_rng(seed=2)])
@pytest.mark.parametrize("size", [10, 20, 50])
- def test_sample_points_pointpats(self, size):
- pytest.importorskip("pointpats")
+ @pytest.mark.parametrize("method", ["cluster_poisson", "cluster_normal"])
+ @pytest.mark.skipif(
+ not POINTPATS_GE_253, reason="Requires pointpats>=2.5.3 for rng kwarg"
+ )
+ def test_sample_points_pointpats(self, method, size, rng):
for gs in (
self.g1,
self.na,
self.a1,
):
- output = gs.sample_points(size, method="cluster_poisson")
- assert_index_equal(gs.index, output.index)
+ output1 = gs.sample_points(size, method=method, rng=rng)
+ assert_index_equal(gs.index, output1.index)
assert (
- len(output.explode(ignore_index=True)) == len(gs[~gs.is_empty]) * size
+ len(output1.explode(ignore_index=True)) == len(gs[~gs.is_empty]) * size
)
+ if rng is not None:
+ output2 = gs.sample_points(size, method=method, rng=rng)
+ if rng == 1:
+ assert_geoseries_equal(output1, output2)
+ else:
+ with pytest.raises(AssertionError, match="2 out of"):
+ assert_geoseries_equal(output1, output2)
+
with pytest.raises(AttributeError, match="pointpats.random module has no"):
gs.sample_points(10, method="nonexistent")
+ @pytest.mark.parametrize("rng", [None, 1, np.random.default_rng(seed=2)])
+ @pytest.mark.parametrize("method", ["cluster_poisson", "cluster_normal"])
+ @pytest.mark.skipif(
+ not POINTPATS_GE_253, reason="Requires pointpats>=2.5.3 for rng kwarg"
+ )
+ def test_sample_points_pointpats_array(self, method, rng):
+ output = concat([self.g1, self.g1]).sample_points(
+ [10, 15, 20, 25], method=method, rng=rng
+ )
+ expected = Series(
+ [10, 15, 20, 25], index=[0, 1, 0, 1], name="sampled_points", dtype="int32"
+ )
+ assert_series_equal(shapely.get_num_geometries(output), expected)
+
def test_offset_curve(self):
oc = GeoSeries([self.l1]).offset_curve(1, join_style="mitre")
expected = GeoSeries([LineString([[-1, 0], [-1, 2], [1, 2]])])
=====================================
geopandas/tests/test_geoseries.py
=====================================
@@ -372,6 +372,12 @@ class TestSeries:
expected = self.g1.reindex(index)
assert_geoseries_equal(expected, GeoSeries.from_wkb(s, index=index))
+ def test_from_wkb_with_missing(self):
+ s = pd.Series([self.t1.wkb, None, self.sq.wkb])
+ result = GeoSeries.from_wkb(s)
+ expected = GeoSeries([self.t1, None, self.sq])
+ assert_geoseries_equal(result, expected)
+
def test_from_wkt(self):
assert_geoseries_equal(self.g1, GeoSeries.from_wkt([self.t1.wkt, self.sq.wkt]))
@@ -404,6 +410,19 @@ class TestSeries:
expected = self.g1.reindex(index)
assert_geoseries_equal(expected, GeoSeries.from_wkt(s, index=index))
+ def test_from_wkt_with_missing(self):
+ s = pd.Series([self.t1.wkt, None, self.sq.wkt])
+ result = GeoSeries.from_wkt(s)
+ expected = GeoSeries([self.t1, None, self.sq])
+ assert_geoseries_equal(result, expected)
+
+ @pytest.mark.parametrize("missing_value", [None, np.nan, pd.NA])
+ def test_from_wkt_with_missing_object(self, missing_value):
+ s = pd.Series([self.t1.wkt, missing_value, self.sq.wkt], dtype="object")
+ result = GeoSeries.from_wkt(s)
+ expected = GeoSeries([self.t1, None, self.sq])
+ assert_geoseries_equal(result, expected)
+
def test_to_wkb(self):
assert_series_equal(pd.Series([self.t1.wkb, self.sq.wkb]), self.g1.to_wkb())
assert_series_equal(
=====================================
geopandas/tests/test_op_output_types.py
=====================================
@@ -1,3 +1,5 @@
+import contextlib
+
import numpy as np
import pandas as pd
@@ -5,6 +7,7 @@ from shapely.geometry import Point
import geopandas
from geopandas import GeoDataFrame, GeoSeries
+from geopandas._compat import PANDAS_GE_31
import pytest
from geopandas.testing import assert_geodataframe_equal
@@ -147,30 +150,27 @@ def test_loc(df):
assert_object(df.loc[:, "value1"], pd.Series)
- at pytest.mark.parametrize(
- "geom_name",
- [
- "geometry",
- pytest.param(
- "geom",
- marks=pytest.mark.xfail(
- reason="pre-regression behaviour only works for geometry col geometry"
- ),
- ),
- ],
-)
+ at pytest.mark.parametrize("geom_name", ["geometry", "geom"])
def test_loc_add_row(geom_name, nybb_filename):
# https://github.com/geopandas/geopandas/issues/3119
nybb = geopandas.read_file(nybb_filename)[["BoroCode", "geometry"]]
if geom_name != "geometry":
nybb = nybb.rename_geometry(geom_name)
- # crs_orig = nybb.crs
-
# add a new row
- nybb.loc[5] = [6, nybb.geometry.iloc[0]]
- assert nybb.geometry.dtype == "geometry"
- assert nybb.crs is None # TODO this should be crs_orig, regressed in #2373
+ if PANDAS_GE_31:
+ ctx = pytest.warns(UserWarning, match="CRS not set for some.*")
+ expected_crs = nybb.crs
+ else:
+ ctx = contextlib.nullcontext()
+ expected_crs = None # this should be nybb.crs, regressed in #2373
+ with ctx:
+ nybb.loc[5] = [6, nybb.geometry.iloc[0]]
+ if PANDAS_GE_31 or geom_name == "geometry":
+ assert nybb.geometry.dtype == "geometry"
+ assert nybb.crs is expected_crs
+ else:
+ assert nybb.geometry.dtype == "object"
def test_iloc(df):
=====================================
geopandas/tests/test_sindex.py
=====================================
@@ -99,6 +99,7 @@ class TestSeriesSindex:
assert sliced.sindex is not original_index
# Select all rows
sliced = s.iloc[:]
+ assert sliced.has_sindex
assert sliced.sindex is original_index
# Select all rows and flip
sliced = s.iloc[::-1]
=====================================
geopandas/tools/clip.py
=====================================
@@ -8,6 +8,7 @@ import pandas.api.types
from shapely.geometry import MultiPolygon, Polygon, box
from geopandas import GeoDataFrame, GeoSeries
+from geopandas._compat import PANDAS_GE_30
from geopandas.array import (
LINE_GEOM_TYPES,
POINT_GEOM_TYPES,
@@ -82,7 +83,7 @@ def _clip_gdf_with_mask(gdf, mask, sort=False):
# Clip the data with the polygon
if isinstance(gdf_sub, GeoDataFrame):
- clipped = gdf_sub.copy()
+ clipped = gdf_sub.copy(deep=not PANDAS_GE_30)
if clipping_by_rectangle:
clipped.loc[non_point_mask, clipped._geometry_column_name] = (
gdf_sub.geometry.values[non_point_mask].clip_by_rect(*mask)
@@ -93,7 +94,7 @@ def _clip_gdf_with_mask(gdf, mask, sort=False):
)
else:
# GeoSeries
- clipped = gdf_sub.copy()
+ clipped = gdf_sub.copy(deep=not PANDAS_GE_30)
if clipping_by_rectangle:
clipped[non_point_mask] = gdf_sub.values[non_point_mask].clip_by_rect(*mask)
else:
=====================================
pyproject.toml
=====================================
@@ -7,13 +7,12 @@ name = "geopandas"
dynamic = ["version"]
authors = [{ name = "Kelsey Jordahl", email = "kjordahl at alum.mit.edu" }]
maintainers = [{ name = "GeoPandas contributors" }]
-license = { text = "BSD 3-Clause" }
+license = "BSD-3-Clause"
description = "Geographic pandas extensions"
keywords = ["GIS", "cartography", "pandas", "shapely"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
- "License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
@@ -41,6 +40,7 @@ all = [
"GeoAlchemy2",
"pyarrow>=10.0.0",
"scipy",
+ "pointpats>=2.5.3",
]
# Minimum supported additional deps, not installed as part of `all` extra
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-geopandas/-/compare/58c8bb2391b8f6dbd1dcd12c9fc7ab67fe380de2...2eeecb636d9429d054ac4a9fb256bbf2623d1070
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-geopandas/-/compare/58c8bb2391b8f6dbd1dcd12c9fc7ab67fe380de2...2eeecb636d9429d054ac4a9fb256bbf2623d1070
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260310/6eaf6ee4/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list