[Geoserver-devel] [JIRA] (GEOS-10439) Problem(s) using WCS’s rangesubset parameter with netCDF Coverage Views

Martin Pontius created an issue

GeoServer / BugGEOS-10439

Problem(s) using WCS’s rangesubset parameter with netCDF Coverage Views

Issue Type:

BugBug

Affects Versions:

2.18.2, 2.18.3, 2.20.3

Assignee:

Unassigned

Attachments:

gis_stackexchange_geoserver_netcdf_coverage_view_issue_full_log.txt

Components:

NetCDF, WCS

Created:

31/Mar/22 5:45 PM

Environment:

I use Ubuntu 20.04.4 LTS. Tests with versions 2.18.2, 2.20.3 and 2.20.x (nightly/snapshot, today - 31.03.2022) were made on a local installation with the platform independent binary. Tests with version 2.18.3 were made as part of a GeoNode Docker setup.

Priority:

MediumMedium

Reporter:

Martin Pontius

The problem was first reported on GIS StackExchange (https://gis.stackexchange.com/questions/427504/problems-using-wcs-s-rangesubset-parameter-with-netcdf-coverage-views-in-geose ) where I was encouraged to open a bug report. Below is a copy of the detailed description of the problem.


Use case

My use case is to store environmental data downloaded from the Copernicus Marine Environment Monitoring Service (CMEMS) as netCDF files in GeoServer and make them available via Web Coverage Service using GetCoverage requests. I would like to be able to apply spatial, temporal and thematic subsetting. While spatial and temporal subsetting work smoothly (with subset parameter), I have trouble using thematic subsetting (with rangesubset parameter). Details are following below after explaining my setup first.

Setup

I use GeoServer 2.18.3 as part of a GeoNode setup, however the problems occur with GeoServer 2.18.2 and 2.20.3 outside of the GeoNode setup, too. Along my GeoServer installation I installed the two extensions netcdf and netcdf-out with the corresponding GeoServer version. In order to use scale_factor correctly I added -Dorg.geotools.coverage.io.netcdf.enhance.ScaleMissing=true to the JAVA_OPTS environment variable.

I have created a netCDF store with an example netCDF file (global-analysis-forecast-wav-001-027_20220101.nc, ~280 MB). Here is the output of ncdump -h:

netcdf global-analysis-forecast-wav-001-027_20220101 {
dimensions:
    time = 8 ;
    latitude = 2041 ;
    longitude = 4320 ;
variables:
    short VHM0(time, latitude, longitude) ;
        VHM0:_FillValue = -32767s ;
        VHM0:long_name = "Spectral significant wave height (Hm0)" ;
        VHM0:units = "m" ;
        VHM0:standard_name = "sea_surface_wave_significant_height" ;
        VHM0:cell_methods = "time:point area:mean" ;
        VHM0:type_of_analysis = "spectral analysis" ;
        VHM0:WMO_code = 100LL ;
        VHM0:_ChunkSizes = 1LL, 681LL, 1440LL ;
        VHM0:add_offset = 0. ;
        VHM0:scale_factor = 0.01 ;
    short VMDR(time, latitude, longitude) ;
        VMDR:_FillValue = -32767s ;
        VMDR:long_name = "Mean wave direction from (Mdir)" ;
        VMDR:units = "degree" ;
        VMDR:standard_name = "sea_surface_wave_from_direction" ;
        VMDR:cell_methods = "time:point area:mean" ;
        VMDR:type_of_analysis = "spectral analysis" ;
        VMDR:WMO_code = 200LL ;
        VMDR:_ChunkSizes = 1LL, 681LL, 1440LL ;
        VMDR:add_offset = 180. ;
        VMDR:scale_factor = 0.01 ;
    double longitude(longitude) ;
        longitude:_FillValue = NaN ;
        longitude:standard_name = "longitude" ;
        longitude:long_name = "longitude coordinate" ;
        longitude:units = "degrees_east" ;
        longitude:axis = "X" ;
        longitude:step = 0.08332825 ;
        longitude:_ChunkSizes = 4320LL ;
    double latitude(latitude) ;
        latitude:_FillValue = NaN ;
        latitude:standard_name = "latitude" ;
        latitude:long_name = "latitude coordinate" ;
        latitude:units = "degrees_north" ;
        latitude:axis = "Y" ;
        latitude:step = 0.08333588 ;
        latitude:_ChunkSizes = 2041LL ;
    double time(time) ;
        time:_FillValue = NaN ;
        time:standard_name = "time" ;
        time:long_name = "time" ;
        time:axis = "T" ;
        time:step = 3LL ;
        time:_ChunkSizes = 1LL ;
        time:units = "hours since 1950-01-01" ;
        time:calendar = "standard" ;

// global attributes:
        :Conventions = "CF-1.6" ;
        :time_coverage_start = "20220311-03:00:00" ;
        :time_coverage_end = "20220312-00:00:00" ;
        :date_created = "20220302-07:35:00" ;
        :product_type = "forecast" ;
        :product = "GLOBAL_ANALYSIS_FORECAST_WAV_001_027" ;
        :product_ref_date = "20220302-00:00:00" ;
        :product_range = "D+9" ;
        :product_user_manual = "http://marine.copernicus.eu/documents/PUM/CMEMS-GLO-PUM-001-027.pdf" ;
        :quality_information_document = " http://marine.copernicus.eu/documents/QUID/CMEMS-GLO-QUID-001-027." ;
        :dataset = "global-analysis-forecast-wav-001-027" ;
        :title = "Mean fields from global wave model MFWAM of Meteo-France with ECMWF forcing" ;
        :institution = "METEO-FRANCE" ;
        :references = "http://marine.copernicus.eu" ;
        :credit = "E.U. Copernicus Marine Service Information (CMEMS)" ;
        :licence = "http://marine.copernicus.eu/services-portfolio/service-commitments-and" ;
        :contact = "servicedesk.cmems@anonymised.com" ;
        :producer = "CMEMS - Global Monitoring and Forecasting Centre" ;
        :area = "GLO" ;
        :geospatial_lon_min = -180. ;
        :geospatial_lon_max = 179.9167 ;
        :geospatial_lon_step = 0.08332825 ;
        :geospatial_lon_units = "degree" ;
        :geospatial_lat_min = -80. ;
        :geospatial_lat_max = 90. ;
        :geospatial_lat_step = 0.08333588 ;
        :geospatial_lat_units = "degree" ;
}

On top of this netCDF store I created a Coverage View including the two variables (in this order: VHM0, VMDR) as bands. Because I would like to use 10 or more variables in the end, I don’t want to use separate layers for each variable. In order to serve a long (~several months/years) time series of data I would like to use an ImageMosaic instead of a netCDF store later, but as the problems are identical I stick to the simpler case of a netCDF store in this post.

Problem(s)

If I use the Coverage View to make the following GetCoverage request

http://localhost/geoserver/geonode/wcs?service=WCS&version=2.0.1&request=GetCoverage&coverageid=geonode%3Aglobal-analysis-forecast-wav-001-027_20220101&rangesubset=VMDR&subset=Lat(40,50)&subset=Long(-10,0)&srs=EPSG%3A4326&format=application/x-netcdf4

I get a java.lang.NullPointerException:

geoserver_n52_geonode  | 30 Mar 13:53:39 INFO [org.vfny.geoserver.servlets] - OutputStream was successfully aborted.
geoserver_n52_geonode  | 30 Mar 13:53:39 ERROR [org.geoserver.ows] -
geoserver_n52_geonode  | java.lang.NullPointerException
geoserver_n52_geonode  |     at com.sun.media.jai.iterator.RandomIterFallback.makeCurrent(RandomIterFallback.java:110)
geoserver_n52_geonode  |     at com.sun.media.jai.iterator.RandomIterFallback.getSampleDouble(RandomIterFallback.java:133)
geoserver_n52_geonode  |     at org.geoserver.wcs.responses.AbstractNetCDFEncoder.setPixel(AbstractNetCDFEncoder.java:642)
geoserver_n52_geonode  |     at org.geoserver.wcs.responses.DefaultNetCDFEncoder.writeDataValues(DefaultNetCDFEncoder.java:423)
geoserver_n52_geonode  |     at org.geoserver.wcs.responses.AbstractNetCDFEncoder.write(AbstractNetCDFEncoder.java:482)

The full log with logging profile GEOTOOLS_DEVELOPER_LOGGING.properties applied can be found here: https://gist.github.com/MartinPontius/bd4ac2c6db4ac80f863c5bc298ba37ec

Interestingly with only the first band (VHM0) the server returns data correctly (apart from some minor naming/metadata issues). Making a request with both bands - i.e. using &rangesubset=VMDR,VHM0 - returns a netCDF file but only including one variable (always the first variable in the rangesubset list). I would expect to get a netCDF file containing both variables.

If I work with a different netCDF file (https://github.com/GeoNode/geoserver-restconfig/blob/master/test/data/polyphemus_20120401.nc ) that is shown in some of the online examples (see https://geoserver.geo-solutions.it/multidim/multidim/netcdf/netcdf_config.html or https://geoserver.geo-solutions.it/multidim/multidim/imagemosaic/mosaic_indexer.html , actual file name is slightly different but should be very similar), the server returns data for separate bands correctly (same minor naming/metadata issues) - i.e. &rangesubset=N02 or &rangesubset=O3. However, if both bands are chosen - i.e. &rangesubset=N02,O3 - it only returns the first band again like with the other file.

Additional observations:

  • Using separate layers for each variable instead of a single Coverage View works
  • In the Layer preview with OpenLayers, GetFeatureInfo shows the correct values for both bands
  • Increasing the memory that GeoServer and JAI are allowed to use and removing WCS resource consumption limits didn’t help
  • Changing netCDF version from 4 to 3 didn’t help

Add Comment

Add Comment

Get Jira notifications on your phone! Download the Jira Cloud app for Android or iOS


This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100197-sha1:666e164)

Atlassian logo