CRS Mismatch Overlay Pair¶
Two layers holding the same ground footprint, one honest and one lying about its CRS. The reference layer is WGS84 degrees and declares CRS84. The sidecar carries UTM zone 33N eastings and northings while its GeoJSON crs member declares EPSG:4326. Each file parses cleanly on its own; the defect exists only in the relationship between them.
| Property | Value |
|---|---|
| Case ID | crs_mismatch_overlay_pair |
| Category | vector |
| Format | GeoJSON |
| Geometry type | Polygon |
| CRS | EPSG:4326 |
| Location | Southeastern Norway (synthetic, UTM zone 33N) — 11.60°E, 59.90°N → 11.80°E, 60.05°N |
| Test tier | unit |
| Size class | tiny |
| Storage class | bundled |
| Redistributable | yes |
| Loader | geopandas |
| Status | validated |
Use this case¶
import pytest
@pytest.mark.geocase_case("crs_mismatch_overlay_pair")
def test_crs_mismatch_overlay_pair(geocase_case) -> None:
data = geocase_case.load()
assert data is not None
Use GeoCase in your tests¶
Install the complete set of vector, raster, and NetCDF dependencies:
What this case checks¶
Confirm that overlay, join and clip operations validate the CRS of every input against the others rather than trusting each file's declaration. A consumer that trusts the sidecar's declared EPSG:4326 places the footprint roughly 3359 km from where it belongs, without raising anything.
Risk types covered¶
crs/mismatchcrs/reprojection_error
Expected behavior¶
| Assertion | Expected |
|---|---|
expect_loadable |
yes |
expect_valid_geometry |
yes |
expect_crs |
yes |
expected_epsg |
4326 |
expected_geometry_types |
Polygon |
Notes¶
The construction¶
One ground footprint -- 11.6E-11.8E, 59.9N-60.05N, in southeastern Norway, comfortably inside UTM zone 33N -- written twice, into two files:
| file | declared CRS | actual ordinates | honest |
|---|---|---|---|
reference_wgs84.geojson (primary) |
urn:ogc:def:crs:OGC:1.3:CRS84 |
degrees | yes |
mismatched_utm33.geojson (sidecar) |
urn:ogc:def:crs:EPSG::4326 |
UTM 33N metres | no |
The sidecar's SW corner is 309839.329, 6645158.002. Those are eastings and
northings, and the file claims they are longitude and latitude.
Both files are individually well-formed. Each is valid GeoJSON, each parses without a warning, and neither is internally inconsistent in any way a single-file validator can see. That is the point: a CRS mismatch is a relationship between two inputs, and no amount of checking one file finds it.
Why two files rather than two features¶
utm_zone_33n_to_32n_pair stores its pair as two features in one collection,
because a GeoJSON FeatureCollection has exactly one CRS and that case needed
both halves directly comparable. Here that constraint is inverted: the
disagreeing declarations are the subject, so the two halves cannot share a
collection. Hence one case with a sidecar.
They stay one case rather than two because a relationship split across two independently-selectable ids can be selected apart, and a selector that returns half a relationship is a footgun.
What to assert¶
Reproject the sidecar from its true CRS (params.sidecar_true_epsg, 32633)
to WGS84 and the corners land on the reference within
params.agreement_tolerance_m (1 m; measured at 0.0004 m). That agreement is
what makes the two files the same footprint rather than two unrelated shapes.
Then do what a naive consumer does -- read the sidecar's ordinates as the
degrees it declares. The SW corner lands 3359 km away, past the north pole
after normalisation. Nothing raises. The catalog's contract is
params.naive_overlay_error_min_km (3000 km), a floor rather than the exact
figure so the assertion is not brittle against a re-projection.
An overlay, spatial join or clip that trusts each input's declaration produces an empty result here -- which reads as "no features intersect" rather than as an error, and is the failure mode worth testing for.
Related¶
utm_zone_33n_to_32n_pair covers zone selection between two adjacent, both
correctly declared zones. rasterize_match_wgs84_polygon and
web_mercator_baseline are the single-layer CRS cases; neither can express a
mismatch, which is why this case exists.
Required capabilities¶
loadcrs-validationreprojectionbounds-check
Files¶
- Primary:
reference_wgs84.geojson - Sidecar:
mismatched_utm33.geojson - Notes:
notes.md
Source and license¶
- Source: geocase-curated
- License: MIT
Tags¶
crs multi_layer overlay polygon utm vector
Related cases¶
- Dateline crossing polygon --
dateline_crossing_polygon - Rasterize Match WGS84 Polygon --
rasterize_match_wgs84_polygon - Rasterize Match UTM33 Polygon --
rasterize_match_utm33_polygon - Svalbard Special Zone Polygon --
svalbard_special_zone_polygon - UTM Zone 1N Polygon --
utm_zone_1n_small