1

I have two layers, where one only has a datetime "time" dimension, and the other layer has a custom integer "forecast" dimension next to time. I'm able to request both layers with WMS with their dimensions (&time=...&dim_forecast=...).

I want to be able to request the coverages through WCS GetCoverage as well. I'm able to subset the first layer that only has a time dimension through a GET like so:

https://localhost:8543/geoserver/ows?service=WCS&version=2.0.1&request=GetCoverage&coverageId=radar:radar_demo&format=geotiff&subset=time("2022-12-12T09:35:00.000Z")

But trying to subset the second layer with both the time dimension and the custom forecast dimension results in an exception.

Second layer's request:

https://localhost:8543/geoserver/ows?service=WCS&version=2.0.1&request=GetCoverage&coverageId=radar:radar_demo2&format=geotiff&subset=forecast(30)&subset=time(%222023-06-01T05:25:00.000Z%22)

XML Exception:

<ows:ExceptionReport version="2.0.0" xsi:schemaLocation="http://www.opengis.net/ows/2.0 http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd">
    <ows:Exception exceptionCode="NoApplicableCode">
        <ows:ExceptionText>
            Failed to read the coverage radar:radar_demo2 Null domain values provided
        </ows:ExceptionText>
    </ows:Exception>
</ows:ExceptionReport>

The name of the dimensions do get recognised, as replacing the "forecast" or "time" with anything else results in an exception Invalid axis label provided: forecat. It seems like the issue is truly with the value of the domain/dimension, more specifically with the forecast's dimension. I've tried entering various things for the forecast (quoted, unquoted, strings, time intervals, integers) but none of it works.

Here are the dimensions from the DescribeCoverage requests for the two layers:

        <gmlcov:metadata>
            <gmlcov:Extension>
                <wcsgs:TimeDomain default="2022-12-12T09:35:00.000Z">
                    <gml:TimePeriod gml:id="radar__radar_demo_tp_0">
                        <gml:beginPosition>2022-12-12T09:30:00.000Z</gml:beginPosition>
                        <gml:endPosition>2022-12-12T09:35:00.000Z</gml:endPosition>
                        <gml:timeInterval unit="minute">5</gml:timeInterval>
                    </gml:TimePeriod>
                </wcsgs:TimeDomain>
            </gmlcov:Extension>
        </gmlcov:metadata>
...

Second layer:

        <gmlcov:metadata>
            <gmlcov:Extension>
                <wcsgs:TimeDomain default="2023-06-01T00:10:00.000Z">
                    <gml:TimePeriod gml:id="radar__radar_demo2_tp_0">
                        <gml:beginPosition>2023-06-01T00:00:00.000Z</gml:beginPosition>
                        <gml:endPosition>2023-06-01T00:10:00.000Z</gml:endPosition>
                        <gml:timeInterval unit="minute">5</gml:timeInterval>
                    </gml:TimePeriod>
                </wcsgs:TimeDomain>
                <wcsgs:DimensionDomain name="FORECAST" uom="minutes" default="0">
                    <wcsgs:SingleValue>0</wcsgs:SingleValue>
                    <wcsgs:SingleValue>5</wcsgs:SingleValue>
                    <wcsgs:SingleValue>10</wcsgs:SingleValue>
                    <wcsgs:SingleValue>15</wcsgs:SingleValue>
                    <wcsgs:SingleValue>20</wcsgs:SingleValue>
                    <wcsgs:SingleValue>25</wcsgs:SingleValue>
                    <wcsgs:SingleValue>30</wcsgs:SingleValue>
                    <wcsgs:SingleValue>35</wcsgs:SingleValue>
                    <wcsgs:SingleValue>40</wcsgs:SingleValue>
                    <wcsgs:SingleValue>45</wcsgs:SingleValue>
                    <wcsgs:SingleValue>50</wcsgs:SingleValue>
                    <wcsgs:SingleValue>55</wcsgs:SingleValue>
                    <wcsgs:SingleValue>60</wcsgs:SingleValue>
                </wcsgs:DimensionDomain>
            </gmlcov:Extension>
        </gmlcov:metadata>

I know the timestamps of the two layers differ a bit, but these are the data that I have. The second layer has all the combinations of time-forecast as described by the DescribeCoverage.

I've also tried recreating this as a POST request, but I get the same error.

curl -v -w "%{http_code} %{time_total}" -u "admin:admin" -XPOST -H "Content-type: xml" [email protected] http://localhost:8180/geoserver/wcs
...
* upload completely sent off: 702 out of 702 bytes
< HTTP/1.1 200
< X-Frame-Options: SAMEORIGIN
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Mon, 05 Jun 2023 10:27:33 GMT
<
<?xml version="1.0" encoding="UTF-8"?><ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.0" xsi:schemaLocation="http://www.opengis.net/ows/2.0 http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd">
<ows:Exception exceptionCode="NoApplicableCode">
<ows:ExceptionText>Failed to read the coverage radar:radar_demo2
Null domain values provided</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>
* Connection #0 to host localhost left intact
200 0.395

Where the file WCSpost.xml contains:

<?xml version="1.0" encoding="UTF-8"?>
<wcs:GetCoverage xmlns:wcs="http://www.opengis.net/wcs/2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/wcs/2.0
        http://schemas.opengis.net/wcs/2.0/wcsAll.xsd"
    service="WCS" version="2.0.1">
    <wcs:CoverageId>radar:radar_demo2</wcs:CoverageId>
    <wcs:DimensionSlice>
        <wcs:Dimension>time</wcs:Dimension>
        <wcs:SlicePoint>2023-06-01T05:25:00.000Z</wcs:SlicePoint>
    </wcs:DimensionSlice>
    <wcs:DimensionSlice>
        <wcs:Dimension>forecast</wcs:Dimension>
        <wcs:SlicePoint>30</wcs:SlicePoint>
    </wcs:DimensionSlice>
    <wcs:format>image/geotiff</wcs:format>
</wcs:GetCoverage>

Both layers have CRS EPSG:3857, the current Geoserver version on this computer is 2.22.2.

I would like to subset the second layer on both axes, be it with WCS 2.0.1 or a lower version (as far as I understand, lower versions might not support axes beside a time dimension).

Log from the request:

05 Jun 13:33:45 INFO   [wcs2_0.util] -  - Collecting layer radar:radar_demo2
05 Jun 13:33:45 DEBUG  [geoserver.wcs2_0] - Executing GetCoverage request on coverage :LayerInfoImpl[radar_demo2, resource:CoverageInfoImpl[radar_demo2]]
05 Jun 13:33:45 DEBUG  [geoserver.wcs2_0] - Extracting extensions from provided request
05 Jun 13:33:45 ERROR  [geoserver.ows] -
org.geoserver.wcs2_0.exception.WCS20Exception: Failed to read the coverage radar:radar_demo2
    at org.geoserver.wcs2_0.GetCoverage.run(GetCoverage.java:370)
    at org.geoserver.wcs2_0.DefaultWebCoverageService20.getCoverage(DefaultWebCoverageService20.java:154)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    ...
Caused by: java.lang.IllegalArgumentException: Null domain values provided
    at org.geotools.gce.imagemosaic.RasterManager$DomainManager.createFilter(RasterManager.java:800)
    at org.geotools.gce.imagemosaic.MosaicQueryBuilder.handleAdditionalFilters(MosaicQueryBuilder.java:206)
    at org.geotools.gce.imagemosaic.MosaicQueryBuilder.build(MosaicQueryBuilder.java:65)
    at org.geotools.gce.imagemosaic.RasterLayerRequest.computeCoverageBoundingBox(RasterLayerRequest.java:372)
    at org.geotools.gce.imagemosaic.RasterLayerRequest.<init>(RasterLayerRequest.java:287)
    at org.geotools.gce.imagemosaic.RasterManager.read(RasterManager.java:1250)
    at org.geotools.gce.imagemosaic.ImageMosaicReader.read(ImageMosaicReader.java:641)
    at org.geotools.gce.imagemosaic.ImageMosaicReader.read(ImageMosaicReader.java:622)
    at org.geoserver.catalog.SingleGridCoverage2DReader.read(SingleGridCoverage2DReader.java:147)
    at org.geoserver.catalog.CoverageDimensionCustomizerReader.read(CoverageDimensionCustomizerReader.java:234)
    at org.geoserver.catalog.CoverageDimensionCustomizerReader.read(CoverageDimensionCustomizerReader.java:222)
    at org.geoserver.wcs2_0.util.RequestUtils.readBestCoverage(RequestUtils.java:247)
    at org.geoserver.wcs2_0.GetCoverage.readCoverage(GetCoverage.java:1336)
    at org.geoserver.wcs2_0.GetCoverage.readCoverage(GetCoverage.java:1062)
    at org.geoserver.wcs2_0.GetCoverage.setupCoverage(GetCoverage.java:412)
    at org.geoserver.wcs2_0.GetCoverage.run(GetCoverage.java:355)
    ... 113 more
0

1 Answer 1

0

After eliminating a couple suspicions (the TIFFs had NaNs, "Nearest Match" was set in the dimensions), I've finally found the cause.

Turns out the problem was in the datatype of the "forecast" dimension. In my indexer.xml, I had that dimension read and cast as a Long. After editing the indexer.xml, so it is an Integer & republishing the layer, the WCS requests suddenly worked.

The true issue probably lies in the format of the parameter &subset=forecast(50), but not even &subset=forecast("50L") (not functional without double quotes either) worked in my case, and I had no other ideas. Fortunately, having the forecast dimension as Integer suffices my needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.