Skip to content

[GH-3260] Preserve M and ZM in Python GeometryUDT serialization - #3265

Open
jiayuasu wants to merge 2 commits into
apache:masterfrom
jiayuasu:feature/python-geometryudt-m-dimensions
Open

[GH-3260] Preserve M and ZM in Python GeometryUDT serialization#3265
jiayuasu wants to merge 2 commits into
apache:masterfrom
jiayuasu:feature/python-geometryudt-m-dimensions

Conversation

@jiayuasu

@jiayuasu jiayuasu commented Aug 15, 2026

Copy link
Copy Markdown
Member

Did you read the Contributor Guide?

Is this PR related to a ticket?

  • Yes, and the PR name follows the format [GH-XXX] my subject.

Part of #3260.

Context and background

Sedona's Python GeometryUDT serializer is the boundary used to move Shapely
geometries into Spark/JVM geometry values. The native serializer previously
derived the coordinate layout only from the coordinate dimension and treated
every layout with at least three ordinates as XYZ. Its measure flag was always
false.

That behavior is sufficient for XY and ordinary XYZ geometries, but it cannot
distinguish the layouts introduced by modern Shapely and GEOS:

Input layout Previous serialized layout Result of this PR
XY XY XY
XYZ XYZ XYZ
XYM XYZ XYM
XYZM XYZ, with M discarded XYZM

This is observable data loss, not only a type-label difference. For example,
two geometries that differ only in their M ordinates can become indistinguishable
after Python-to-JVM serialization. That makes it impossible for the distributed
geom_equals_identical work in #3260 to honor GeoPandas' requirement to compare
every stored coordinate dimension. It can also affect any other workflow that
constructs a Sedona geometry column from Shapely M or ZM objects.

GEOS added GEOSHasM_r in version 3.12. Sedona still supports Shapely builds
linked against older GEOS versions, so requiring that symbol would prevent the
native extension from loading in supported environments. This PR therefore
loads GEOSHasM_r as an optional symbol: newer GEOS versions preserve M/ZM,
while older versions continue to support their existing XY/XYZ inputs. The Z
fallback also preserves XYZ when older GEOS versions report no Z because the
first Z ordinate is NaN.

The pure-Python serializer does not have a representation that can safely
preserve M. It now raises a clear error for M/ZM serialization and
deserialization instead of silently reinterpreting M as Z or dropping it.

What changes were proposed in this PR?

  • Preserve M and ZM coordinate layouts in Sedona's native Python GeometryUDT serializer.
  • Detect measures through the optional GEOS 3.12 GEOSHasM_r API while retaining compatibility with older supported GEOS versions.
  • Preserve Z layouts when the first Z ordinate is NaN.
  • Make the pure-Python fallback reject M and ZM serialization and deserialization instead of silently discarding measure coordinates.
  • Add round-trip coverage for M and ZM points, lines, polygons, and geometry collections.

This is the first PR in the #3260 stack and is based on master:

  1. [GH-3260] Preserve M and ZM in Python GeometryUDT serialization #3265 — Python GeometryUDT M/ZM serialization
  2. [GH-3260] Add ST_EqualsIdentical across Sedona SQL engines #3266 — native ST_EqualsIdentical across Sedona SQL engines
  3. [GH-3260] GeoPandas: Implement distributed geom_equals_identical #3262 — distributed GeoPandas geom_equals_identical

How was this patch tested?

  • Native serializer tests passed with Shapely 2.1 and GEOS 3.13: 21 passed.
  • Legacy compatibility tests passed with Shapely 2.0 and GEOS 3.11: 13 passed and 8 skipped as version-gated.
  • Regression coverage includes XY, XYZ, XYM, and XYZM layouts, including first-ordinate NaN cases.
  • The repository commit-hook suite, including C formatting, Black, and git diff --check, passed.

Did this PR include necessary documentation updates?

  • No, this PR does not add or change a public API.

@jiayuasu jiayuasu linked an issue Aug 16, 2026 that may be closed by this pull request
@jiayuasu jiayuasu added this to the sedona-2.0.0 milestone Aug 16, 2026
@jiayuasu
jiayuasu marked this pull request as ready for review August 16, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GeoPandas: implement distributed geom_equals_identical

1 participant