[GH-3189] GeoPandas: Preserve CRS metadata without geometry SRIDs - #3190
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Preserves CRS metadata for distributed GeoSeries/GeoDataFrame outputs that have no usable geometry SRID (empty, all-null, or SRID 0), ensuring CRS can still round-trip through common operations and conversions.
Changes:
- Added explicit CRS fallback metadata on
GeoSeriesand updated CRS resolution precedence (SRID > explicit metadata > lineage metadata). - Updated
GeoDataFrameconstruction, geometry switching, copying, and GeoPandas conversion to retain/clear CRS fallback appropriately (including duplicate-index construction behavior). - Expanded Python test coverage for empty/all-null geometries, duplicate-index construction, geometry switching, copies, and GeoPandas round-trips.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/sedona/spark/geopandas/geoseries.py | Adds explicit CRS fallback metadata and updates CRS lookup / copy behavior. |
| python/sedona/spark/geopandas/geodataframe.py | Preserves/clears CRS fallback across construction, geometry access/switching, copying, and GeoPandas conversion; avoids duplicate-index row multiplication on construction. |
| python/tests/geopandas/test_geoseries.py | Adds tests for CRS preservation/removal for all-null and empty explode results. |
| python/tests/geopandas/test_geodataframe.py | Adds tests for duplicate-index construction and CRS preservation across set_geometry/copy/reconstruction and GeoPandas conversion. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+343
to
+348
| self._col_label: Label | ||
| self._sindex: SpatialIndex = None | ||
| self._empty_crs_source: typing.Optional["GeoSeries"] = None | ||
| # Explicit CRS metadata wins over the lineage fallback below when | ||
| # geometry rows are empty or carry SRID 0. | ||
| self._empty_crs_value = None |
Comment on lines
+440
to
+444
| geometry = self[self._geometry_column_name] | ||
| empty_crs_source = getattr(self, "_empty_crs_source", None) | ||
| if empty_crs_source is not None: | ||
| geometry._empty_crs_source = empty_crs_source | ||
| return geometry |
Comment on lines
+492
to
+501
| if srid != 0: | ||
| return CRS.from_user_input(srid) | ||
| # These fallbacks are metadata rather than a fresh read from geometry | ||
| # coordinates. Explicit metadata takes precedence over inherited | ||
| # lineage metadata, including for non-empty geometries with SRID 0. | ||
| if self._empty_crs_value is not None: | ||
| return self._empty_crs_value | ||
| if self._empty_crs_source is not None: | ||
| return self._empty_crs_source.crs | ||
| return None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Did you read the Contributor Guide?
Is this PR related to a ticket?
[GH-XXX] my subject. Closes GeoPandas: Preserve CRS metadata for empty geometry results #3189What changes were proposed in this PR?
This PR preserves CRS metadata when a distributed
GeoSeriesorGeoDataFramehas no geometry row from which Sedona can recover an SRID.CRS WKT is stored in each geometry column's pandas-on-Spark
InternalFieldmetadata. This makes the metadata survive column extraction, projection,
filtering to zero rows, copies, geometry expressions, active-geometry
switches, renames, assignments, and pandas-on-Spark round trips without
collecting geometry rows.
set_crsand constructors now retain the full CRS even when it has no EPSGcode, while the physical Sedona SRID remains
0in that case. Constructionwith duplicate indexes updates SRID directly in the Spark column instead of
performing index alignment.
The patch also fixes
GeoSeries.copy(deep=True), which previously raised anassertion for every input, and keeps copied metadata independent from later
changes to the source object.
This is the shared CRS foundation needed by the distributed
clip,dissolve, and collection APIs merged from #3183 and #3185.How was this patch tested?
TestGeoSeries::test_set_crsTestGeoSeries::test_crs_metadata_propagationTestGeoDataFrame::test_construct_from_geopandasTestGeoDataFrame::test_set_crsTestGeoDataFrame::test_crs_metadata_survives_frame_selectionTestGeoDataFrame::test_set_geometry_crsclipanddissolveThe tests cover empty and all-null geometries, zero-row filters, explicit CRS
replacement and removal, non-EPSG CRS values, deep-copy independence,
GeoPandas conversion, duplicate-index construction, Spark-pandas round trips,
and both in-place and copied active-geometry switches.
Did this PR include necessary documentation updates?