Hi All,<br><br>- I am attempting to use a NetCDF file as a data source for a raster layer in Mapserver. According to a very useful email sent in November 2005 from Norman Barker, <a href="http://lists.osgeo.org/pipermail/mapserver-users/2005-November/012153.html">http://lists.osgeo.org/pipermail/mapserver-users/2005-November/012153.html</a>, and from Mapserver documentation at <a href="http://www.mapserver.org/ogc/wcs_format.html#netcdf">http://www.mapserver.org/ogc/wcs_format.html#netcdf</a>, it seems like this should be possible using Mapserver's gdal driver to read the file. However, I am running into some problems when trying to implement these examples using GDAL 1.5.2, released 2008/05/29.<br>
<br>- The NetCDF file which I am using to test with is a "CF Convention" sample file which I downloaded from <a href="http://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc">http://www.unidata.ucar.edu/software/netcdf/examples/tos_O1_2001-2002.nc</a>. This file contains information about sea-surface temperatures, and when viewed by gdalinfo has the following characteristics:<br>
<br>$ gdalinfo tos_O1_2001-2002.nc<br>Driver: netCDF/Network Common Data Format<br>Files: tos_O1_2001-2002.nc<br>Size is 512, 512<br>Coordinate System is `'<br>Metadata:<br> NC_GLOBAL#title=IPSL model output prepared for IPCC Fourth Assessment SRES A2 experiment<br>
NC_GLOBAL#institution=IPSL (Institut Pierre Simon Laplace, Paris, France)<br> NC_GLOBAL#source=IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v<br>
NC_GLOBAL#contact=Sebastien Denvil, <a href="mailto:sebastien.denvil@ipsl.jussieu.fr">sebastien.denvil@ipsl.jussieu.fr</a><br> NC_GLOBAL#project_id=IPCC Fourth Assessment<br> NC_GLOBAL#table_id=Table O1 (13 November 2004)<br>
NC_GLOBAL#experiment_id=SRES A2 experiment<br> NC_GLOBAL#realization=1<br> NC_GLOBAL#cmor_version=9.600000e-01<br> NC_GLOBAL#Conventions=CF-1.0<br> NC_GLOBAL#history=YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements<br>
NC_GLOBAL#references=Dufresne et al, Journal of Climate, 2015, vol XX, p 136<br> NC_GLOBAL#comment=Test drive<br>Subdatasets:<br> SUBDATASET_1_NAME=NETCDF:"tos_O1_2001-2002.nc":lon_bnds<br> SUBDATASET_1_DESC=[180x2] lon_bnds (64-bit floating-point)<br>
SUBDATASET_2_NAME=NETCDF:"tos_O1_2001-2002.nc":lat_bnds<br> SUBDATASET_2_DESC=[170x2] lat_bnds (64-bit floating-point)<br> SUBDATASET_3_NAME=NETCDF:"tos_O1_2001-2002.nc":time_bnds<br> SUBDATASET_3_DESC=[24x2] time_bnds (64-bit floating-point)<br>
SUBDATASET_4_NAME=NETCDF:"tos_O1_2001-2002.nc":tos<br> SUBDATASET_4_DESC=[24x170x180] sea_surface_temperature (32-bit floating-point)<br>Corner Coordinates:<br>Upper Left ( 0.0, 0.0)<br>Lower Left ( 0.0, 512.0)<br>
Upper Right ( 512.0, 0.0)<br>Lower Right ( 512.0, 512.0)<br>Center ( 256.0, 256.0)<br><br>- The SUBDATASET of interest is the "tos" one, and when queried by gdalinfo it shows that it contains 24 bands, each of which varies by NETCDF_DIMENSION_time that increments by 15. When specifically queried by gdalinfo, this SUBDATASET looks like this:<br>
<br>$ gdalinfo NETCDF:"tos_O1_2001-2002.nc":tos<br>Driver: netCDF/Network Common Data Format<br>Files: none associated<br>Size is 180, 170<br>Coordinate System is `'<br>Origin = (0.000000000000000,90.000000000000000)<br>
Pixel Size = (2.000000000000000,-1.000000000000000)<br>Metadata:<br> NC_GLOBAL#title=IPSL model output prepared for IPCC Fourth Assessment SRES A2 experiment<br> NC_GLOBAL#institution=IPSL (Institut Pierre Simon Laplace, Paris, France)<br>
NC_GLOBAL#source=IPSL-CM4_v1 (2003) : atmosphere : LMDZ (IPSL-CM4_IPCC, 96x71x19) ; ocean ORCA2 (ipsl_cm4_v1_8, 2x2L31); sea ice LIM (ipsl_cm4_v<br> NC_GLOBAL#contact=Sebastien Denvil, <a href="mailto:sebastien.denvil@ipsl.jussieu.fr">sebastien.denvil@ipsl.jussieu.fr</a><br>
NC_GLOBAL#project_id=IPCC Fourth Assessment<br> NC_GLOBAL#table_id=Table O1 (13 November 2004)<br> NC_GLOBAL#experiment_id=SRES A2 experiment<br> NC_GLOBAL#realization=1<br> NC_GLOBAL#cmor_version=9.600000e-01<br> NC_GLOBAL#Conventions=CF-1.0<br>
NC_GLOBAL#history=YYYY/MM/JJ: data generated; YYYY/MM/JJ+1 data transformed At 16:37:23 on 01/11/2005, CMOR rewrote data to comply with CF standards and IPCC Fourth Assessment requirements<br> NC_GLOBAL#references=Dufresne et al, Journal of Climate, 2015, vol XX, p 136<br>
NC_GLOBAL#comment=Test drive<br> tos#standard_name=sea_surface_temperature<br> tos#long_name=Sea Surface Temperature<br> tos#units=K<br> tos#cell_methods=time: mean (interval: 30 minutes)<br> tos#_FillValue=1.000000e+20<br>
tos#missing_value=1.000000e+20<br> tos#original_name=sosstsst<br> tos#original_units=degC<br> tos#history= At 16:37:23 on 01/11/2005: CMOR altered the data in the following ways: added 2.73150E+02 to yield output units; Cyclical dimension was output starting at a different lon;<br>
lon#standard_name=longitude<br> lon#long_name=longitude<br> lon#units=degrees_east<br> lon#axis=X<br> lon#bounds=lon_bnds<br> lon#original_units=degrees_east<br> lat#standard_name=latitude<br> lat#long_name=latitude<br>
lat#units=degrees_north<br> lat#axis=Y<br> lat#bounds=lat_bnds<br> lat#original_units=degrees_north<br> time#standard_name=time<br> time#long_name=time<br> time#units=days since 2001-1-1<br> time#axis=T<br> time#calendar=360_day<br>
time#bounds=time_bnds<br> time#original_units=seconds since 2001-1-1<br>Corner Coordinates:<br>Upper Left ( 0.0000000, 90.0000000) <br>Lower Left ( 0.0000000, -80.0000000) <br>Upper Right ( 360.000, 90.000) <br>
Lower Right ( 360.000, -80.000) <br>Center ( 180.0000000, 5.0000000) <br>Band 1 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br>
NETCDF_DIMENSION_time=15<br> NETCDF_time_units=days since 2001-1-1<br>Band 2 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=45<br>
NETCDF_time_units=days since 2001-1-1<br>Band 3 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=75<br> NETCDF_time_units=days since 2001-1-1<br>
Band 4 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=105<br> NETCDF_time_units=days since 2001-1-1<br>Band 5 Block=180x1 Type=Float32, ColorInterp=Undefined<br>
NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=135<br> NETCDF_time_units=days since 2001-1-1<br>Band 6 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br>
Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=165<br> NETCDF_time_units=days since 2001-1-1<br>Band 7 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br>
NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=195<br> NETCDF_time_units=days since 2001-1-1<br>Band 8 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br>
NETCDF_DIMENSION_time=225<br> NETCDF_time_units=days since 2001-1-1<br>Band 9 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=255<br>
NETCDF_time_units=days since 2001-1-1<br>Band 10 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=285<br> NETCDF_time_units=days since 2001-1-1<br>
Band 11 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=315<br> NETCDF_time_units=days since 2001-1-1<br>Band 12 Block=180x1 Type=Float32, ColorInterp=Undefined<br>
NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=345<br> NETCDF_time_units=days since 2001-1-1<br>Band 13 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br>
Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=375<br> NETCDF_time_units=days since 2001-1-1<br>Band 14 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br>
NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=405<br> NETCDF_time_units=days since 2001-1-1<br>Band 15 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br>
NETCDF_DIMENSION_time=435<br> NETCDF_time_units=days since 2001-1-1<br>Band 16 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=465<br>
NETCDF_time_units=days since 2001-1-1<br>Band 17 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=495<br> NETCDF_time_units=days since 2001-1-1<br>
Band 18 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=525<br> NETCDF_time_units=days since 2001-1-1<br>Band 19 Block=180x1 Type=Float32, ColorInterp=Undefined<br>
NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=555<br> NETCDF_time_units=days since 2001-1-1<br>Band 20 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br>
Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=585<br> NETCDF_time_units=days since 2001-1-1<br>Band 21 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br>
NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=615<br> NETCDF_time_units=days since 2001-1-1<br>Band 22 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br>
NETCDF_DIMENSION_time=645<br> NETCDF_time_units=days since 2001-1-1<br>Band 23 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=675<br>
NETCDF_time_units=days since 2001-1-1<br>Band 24 Block=180x1 Type=Float32, ColorInterp=Undefined<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=705<br> NETCDF_time_units=days since 2001-1-1<br>
<br>- I am able to test that I can extract one of these bands with GDAL, and convert it to GeoTIFF with the following command:<br>gdal_translate -b 1 NETCDF:"tos_O1_2001-2002.nc":tos sea_temp_band_1.tif. Here however is where the first problem appears. As you can see from the screenshot of the sea_temp_band_1.tif that I've posted at <a href="http://2.bp.blogspot.com/_-yICqdt0mtY/SZxtI4yUHdI/AAAAAAAAA-I/z7W_O6qBXho/s1600-h/upside_down_netcdf.jpg">http://2.bp.blogspot.com/_-yICqdt0mtY/SZxtI4yUHdI/AAAAAAAAA-I/z7W_O6qBXho/s1600-h/upside_down_netcdf.jpg</a>, the data in the file appears to be represented upside down. Since this file is a sample from the Unidata web site, I'm reasonably confident that the file follows the CF convention. Every NetCDF file I have tried to read with GDAL has had this problem, including ones that I have created with gdal_translate. As you can see from the gdalinfo output above, the georeferencing and pixel dimensions seem to be reasonable. In the past I have used flip_raster.py to "fix" this, and created an intermediary GeoTIFF. Now that I would like to use the NetCDF itself as the data source to feed a WCS service, this is no longer an acceptable solution. Of interest though, is that the georeferencing info between the flipped and unflipped files are exactly the same. See below:<br>
<br>- Flipped file:<br>---------------<br>$ gdalinfo flipped_sea_temp_band_1.tif<br>Driver: GTiff/GeoTIFF<br>Files: flipped_sea_temp_band_1.tif<br>Size is 180, 170<br>Coordinate System is `'<br>Origin = (0.000000000000000,90.000000000000000)<br>
Pixel Size = (2.000000000000000,-1.000000000000000)<br>Image Structure Metadata:<br> INTERLEAVE=BAND<br>Corner Coordinates:<br>Upper Left ( 0.0000000, 90.0000000) <br>Lower Left ( 0.0000000, -80.0000000) <br>Upper Right ( 360.000, 90.000) <br>
Lower Right ( 360.000, -80.000) <br>Center ( 180.0000000, 5.0000000) <br>Band 1 Block=180x11 Type=Float32, ColorInterp=Gray<br><br>- Unflipped file:<br>-----------------<br>$ gdalinfo sea_temp_band_1.tif<br>
Driver: GTiff/GeoTIFF<br>Files: sea_temp_band_1.tif<br>Size is 180, 170<br>Coordinate System is `'<br>Origin = (0.000000000000000,90.000000000000000)<br>Pixel Size = (2.000000000000000,-1.000000000000000)<br><snip> (Metadata removed for clarity)<br>
Image Structure Metadata:<br> INTERLEAVE=BAND<br>Corner Coordinates:<br>Upper Left ( 0.0000000, 90.0000000) <br>Lower Left ( 0.0000000, -80.0000000) <br>Upper Right ( 360.000, 90.000) <br>Lower Right ( 360.000, -80.000) <br>
Center ( 180.0000000, 5.0000000) <br>Band 1 Block=180x11 Type=Float32, ColorInterp=Gray<br> NoData Value=1.00000002004087734e+20<br> Metadata:<br> NETCDF_VARNAME=tos<br> NETCDF_DIMENSION_time=15<br> NETCDF_time_units=days since 2001-1-1<br>
<br>- I'm unsure if this is a bug in GDAL, or an incorrectly formatted NetCDF file. So, would it be possible for someone who has a NetCDF file that is read "right-side-up" to post it as a sample for me to test with?<br>
<br>Thanks in advance,<br><br>Roger<br><br>