Failing WCS sub-setting when native CRS != declared CRS

Hello,

we have a problem using WCS with layers that have a native CRS different than the declared CRS.

We do e.g. have data defined on very particular meteorological CRS (which we have defined in the user_projections file). Now as we don’t want this to be the declared CRS, we have configured the layer as such:

  • native CRS: EPSG:100002 (defined by the data)
  • declared: EPSG:4326
  • projection handling: reproject native to declared

Now the problem is that for WCS requests on that data, the requests usually fail because of the spatial subsetting.

A typical request that should fail would be such:

http://localhost:8080/geoserver/ows?service=WCS&version=2.0.1&request=GetCoverage&coverageId=dwd.modeldata__ICON-D2.Temperature.height_level_above_ground&format=application/x-netcdf&subsettingCRS=http://www.opengis.net/def/crs/EPSG/0/4326&subset=Long(7,13)&subset=Lat(45,55)&outputCRS=http://www.opengis.net/def/crs/EPSG/0/4326&subset=elevation(2)&subset=time(%222025-04-07T06:00:00.000Z%22)&subset=REFERENCE_TIME(%222025-04-07T00:00:00.000Z%22)

The important part is this:

  • subsettingCRS=http://www.opengis.net/def/crs/EPSG/0/4326&
  • subset=Long(7,13)&subset=Lat(45,55)&
  • outputCRS=http://www.opengis.net/def/crs/EPSG/0/4326

We would like to be able to specify lon/lat coordinates for the request, and the output should also be in EPSG:4326.

Such a request fails with the error Splitting requests returned nothing.

The problem seems to be that the coverage reader that builds the granule source only knows the native CRS and therefore builds all granules using that CRS.

Now WCS dimension sub-setting helper, when it builds the granule query would have to reproject the request envelope (in our case EPSG:4236) to the native CRS for the spatial query. For strange reasons that doesn’t seem to be happen. It seems to build the query from the declared CRS and since both match (in our case EPSG:4326) nothing is reprojected.

Later when the filter is executed and the granule geometries are intersected with the request envelope, this will of course fail badly, because it intersects polygons built from different CRSs. This will fail in most cases, but could even be worse, because it could even sometimes succeed falsly.

The code that seems wrong is in org.geoserver.wcs2_0.response.WCSDimensionsSubsetHelper#extractSubsettingEnvelope

It seems as if it should be using the native CRS (coverageInfo#getNativeCRS()) there instead of the declared CRS (coverageInfo#getCRS()). Then, the query should have it’s request envelope reprojected to the native CRS of the data.

Has anybody noticed something like that before? Could this be a bug, or are we misinterpreting the CRS handling of WCS?

Thanks!
Sören

Is there any known transformation from the very particular “Cosmo-D2” into EPSG:4326?

-Jukka Rahkonen-

Hi @jratike80 ,

good question. It’s actually not so unusual after all, just the parameters are:

data/user_projections/epsg.properties:

# COSMO-D2 projection
1000002=PROJCS["COSMO-D2 projection",  \
  GEOGCS["COSMO-DE Coordinate System",  \
    DATUM["COSMO Sphere",  \
      SPHEROID["COSMO Sphere", 6371229.0, 0.0]],  \
    PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],  \
    UNIT["degree", 0.017453292519943295],  \
    AXIS["Longitude", EAST],  \
    AXIS["Latitude", NORTH]],  \
  PROJECTION["Rotated_Pole"],  \
  PARAMETER["central_meridian", 10.0],  \
  PARAMETER["latitude_of_origin", 50.0],  \
  PARAMETER["scale_factor", 1.0],  \
  PARAMETER["false_easting", 0.0],  \
  PARAMETER["false_northing", 0.0],  \
  UNIT["m", 1.0],  \
  AXIS["x", EAST],  \
  AXIS["y", NORTH],  \
  AUTHORITY["EPSG","1000002"]]

This is the projection (Rotated_Pole) we use for the our local numerical weather models. And we defined some transformations at:

data/user_projections/epsg_operations.properties:

# COSMO-D2 -> EPSG:4326
4326,1000002=PARAM_MT["Rotated_Pole",  \
    PARAMETER["semi_major", 6371229.0],  \
    PARAMETER["semi_minor", 6371229.0],  \
    PARAMETER["central_meridian", 10.0],  \
    PARAMETER["latitude_of_origin", 50.0],  \
    PARAMETER["scale_factor", 1.0],  \
    PARAMETER["false_easting", 0.0],  \
    PARAMETER["false_northing", 0.0]]
...

This has been working nicely for WMS for years now. But now our users would like to access the data using WCS. They would typically runs their requests in EPSG:4326, because they are more familiar with the that CRS. But I guess the problem would be in any other sub-setting CRS.

Now it turns out that the granules are all in EPSG:1000002 (the native CRS) while WCS builds its spatial query based on EPSG:4326 (the declared CRS).

So basically the intersection filter applied to the features of the GranuleSource is comparing apples and oranges.

So it seems.

Hi all,
while I don’t have time to look into this, I’d like to share an hypothesis.
The notion of “reproject to native” is something that GeoServer introduced, and sits above the stores/readers levels.

For vectors, there is code transforming Query objects going to the stores based on the projection policy configuration, making it jump from the service level, which works with the “declared crs”, to the native store level, which needs “native crs”. For example, spatial filters get reprojected.

My guess is that this code is simply missing from WCS (and yes, that would be a bug).

Cheers
Andrea