Skip to content

GeoDataFrame CRS mismatch is resolved silently (last-one-wins) - a frame mislabel can never fail loudly #646

Description

@dshean

Summary

Since c815b55 ("fixed bug in crs mismatch"), GeoDataFrame::receiveThread's CRS_REC handler resolves a CRS mismatch by silently overwriting with the last-received CRS (last-one-wins), rather than raising. The commit comment explains the intent — the constructor default is later replaced by the subsetting thread's mission+datum CRS — and that flow is fine today because all senders are mission code.

Why it's worth hardening

The consequence is that a genuine frame mislabel (e.g. a future sender attaching ITRF2014 metadata to ITRF2020 data, or a user-supplied CRS colliding with mission logic) can never fail loudly: the dataframe simply reports whichever CRS arrived last, and any downstream raster sampling (which trusts robj->getCRS() as the transform source, GdalRaster.cpp createTransform) silently uses it. Datum-level errors this could mask are dm-to-m scale (ITRF↔NAD83 ~1.5–2.3 m horizontal in the western US).

Suggestion

Keep the expected-replacement path (default → mission CRS) silent, but log a warning (or raise, behind a strict flag) when a non-default CRS is replaced by a different non-default CRS. That preserves current behavior for the legitimate flow while making a real mislabel observable.

Happy to provide more context — this came out of a broader verification of the ICESat-2 → 3DEP sampling datum chain (which we found to be exact; see also the coordinate-epoch issue filed separately).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions