Skip to content

Commit

Permalink
netCDF: fix reading MODIS_ARRAY.nc file that has non CF-compliant way…
Browse files Browse the repository at this point in the history
… of expressing axis and CRS (fixes #4075)
  • Loading branch information
rouault committed Jul 7, 2021
1 parent a26ec1e commit 080e975
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
Binary file added autotest/gdrivers/data/netcdf/MODIS_ARRAY.nc
Binary file not shown.
11 changes: 11 additions & 0 deletions autotest/gdrivers/netcdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4687,6 +4687,17 @@ def test_netcdf_metadata_sentinel5():
assert j['attributes']['ISO_METADATA'] == expected


###############################################################################
# Test opening a file with particular georeferencing encoding


def test_netcdf_modis_array():

ds = gdal.Open('data/netcdf/MODIS_ARRAY.nc')
assert ds.GetGeoTransform(can_return_null=True) is not None
assert ds.GetSpatialRef() is not None


def test_clean_tmp():
# [KEEP THIS AS THE LAST TEST]
# i.e. please do not add any tests after this one. Put new ones above.
Expand Down
30 changes: 28 additions & 2 deletions gdal/frmts/netcdf/netcdfdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3368,6 +3368,17 @@ void netCDFDataset::SetProjectionFromVar( int nGroupId, int nVarId,
// oSRS.SetWellKnownGeogCS("WGS84");
}
}
else
{
// Dataset from https://github.com/OSGeo/gdal/issues/4075 has a "crs"
// attribute hold on the variable of interest that contains a PROJ.4 string
pszValue = FetchAttr(nGroupId, nVarId, "crs");
if( pszValue && strstr(pszValue, "+proj=") &&
oSRS.importFromProj4(pszValue) == OGRERR_NONE )
{
bGotCfSRS = true;
}
}
// Read projection coordinates.

int nGroupDimXID = -1;
Expand All @@ -3392,6 +3403,11 @@ void netCDFDataset::SetProjectionFromVar( int nGroupId, int nVarId,
// variables without same name than dimension using the same resolving
// logic. This should handle for example NASA Ocean Color L2 products.

const bool bIgnoreXYAxisNameChecks =
CPLTestBool(CPLGetConfigOption("GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS", "NO")) ||
// Dataset from https://github.com/OSGeo/gdal/issues/4075 has a res and transform attributes
(FetchAttr(nGroupId, nVarId, "res") != nullptr &&
FetchAttr(nGroupId, nVarId, "transform") != nullptr);

// Check that they are 1D or 2D variables
if( nVarDimXID >= 0 )
Expand All @@ -3400,14 +3416,19 @@ void netCDFDataset::SetProjectionFromVar( int nGroupId, int nVarId,
nc_inq_varndims(nGroupId, nVarDimXID, &ndims);
if( ndims == 0 || ndims > 2 )
nVarDimXID = -1;
else
else if( !bIgnoreXYAxisNameChecks )
{
if( !NCDFIsVarLongitude(nGroupId, nVarDimXID, nullptr) &&
!NCDFIsVarProjectionX(nGroupId, nVarDimXID, nullptr) &&
// In case of inversion of X/Y
!NCDFIsVarLatitude(nGroupId, nVarDimXID, nullptr) &&
!NCDFIsVarProjectionY(nGroupId, nVarDimXID, nullptr) )
{
CPLDebug("netCDF",
"Georeferencing ignored due to non-specific "
"enough X axis name. "
"Set GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS=YES "
"as configuration option to bypass this check");
nVarDimXID = -1;
}
}
Expand All @@ -3419,14 +3440,19 @@ void netCDFDataset::SetProjectionFromVar( int nGroupId, int nVarId,
nc_inq_varndims(nGroupId, nVarDimYID, &ndims);
if( ndims == 0 || ndims > 2 )
nVarDimYID = -1;
else
else if( !bIgnoreXYAxisNameChecks )
{
if( !NCDFIsVarLatitude(nGroupId, nVarDimYID, nullptr) &&
!NCDFIsVarProjectionY(nGroupId, nVarDimYID, nullptr) &&
// In case of inversion of X/Y
!NCDFIsVarLongitude(nGroupId, nVarDimYID, nullptr) &&
!NCDFIsVarProjectionX(nGroupId, nVarDimYID, nullptr) )
{
CPLDebug("netCDF",
"Georeferencing ignored due to non-specific "
"enough Y axis name. "
"Set GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS=YES "
"as configuration option to bypass this check");
nVarDimYID = -1;
}
}
Expand Down

0 comments on commit 080e975

Please sign in to comment.