From 82164b4a21a75bd08306717bb206f4117d799f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=27Hont=20Ren=C3=A9-Luc?= Date: Mon, 17 Mar 2014 09:40:29 +0100 Subject: [PATCH 1/2] [Feature][RASTER] Generate band name with NetCDF EXTRA_DIM funded by Ifremer The NetCDF provided extra dimensional information. This information provides metadata on each band. These metadat can be used to explain the name of each band. For example, the bands of a NetCDF file represents the temperature at a given depth. For the user, it is easier to select a band with depth information, rather than the number. If the GDAL version is equal or greater than 1.10.0, the band name is generated with the extra_dim information. --- src/core/raster/qgsrasterinterface.h | 2 +- src/providers/gdal/qgsgdalprovider.cpp | 71 ++++++++++++++++++++++++++ src/providers/gdal/qgsgdalprovider.h | 2 + 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/core/raster/qgsrasterinterface.h b/src/core/raster/qgsrasterinterface.h index 3b20b2239f0..cd16c27497f 100644 --- a/src/core/raster/qgsrasterinterface.h +++ b/src/core/raster/qgsrasterinterface.h @@ -97,7 +97,7 @@ class CORE_EXPORT QgsRasterInterface virtual int ySize() const { if ( mInput ) return mInput->ySize(); else return 0; } /** \brief helper function to create zero padded band names */ - virtual QString generateBandName( int theBandNumber ) const + virtual QString generateBandName( int theBandNumber ) const { return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) ); } diff --git a/src/providers/gdal/qgsgdalprovider.cpp b/src/providers/gdal/qgsgdalprovider.cpp index e13fe6bd155..9a2a430b64d 100644 --- a/src/providers/gdal/qgsgdalprovider.cpp +++ b/src/providers/gdal/qgsgdalprovider.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include "gdalwarper.h" #include "ogr_spatialref.h" @@ -875,6 +876,76 @@ int QgsGdalProvider::yBlockSize() const int QgsGdalProvider::xSize() const { return mWidth; } int QgsGdalProvider::ySize() const { return mHeight; } +QString QgsGdalProvider::generateBandName( int BandNo ) const +{ +#ifdef GDAL_COMPUTE_VERSION /* only available in GDAL 1.10 or later */ +#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,10,0) + if ( strcmp( GDALGetDriverShortName( GDALGetDatasetDriver( mGdalDataset ) ), "netCDF" ) == 0 ) + { + char ** GDALmetadata = GDALGetMetadata( mGdalDataset, NULL ); + + if ( GDALmetadata ) + { + QStringList metadata = cStringList2Q_( GDALmetadata ); + QStringList dimExtraValues; + QMap< QString, QString > unitsMap; + for ( QStringList::const_iterator i = metadata.begin(); + i != metadata.end(); + ++i ) + { + QString val(*i); + if ( !val.startsWith( "NETCDF_DIM_EXTRA" ) && !val.contains( "#units=" ) ) + continue; + QStringList values = val.split( "=" ); + val = values.at( 1 ); + if ( values.at( 0 ) == "NETCDF_DIM_EXTRA" ) { + dimExtraValues = val.replace(QString("{"), QString("")).replace(QString("}"), QString("")).split(","); + //http://qt-project.org/doc/qt-4.8/qregexp.html#capturedTexts + } else { + unitsMap[ values.at(0).split( "#" ).at(0) ] = val; + } + } + if ( dimExtraValues.count() > 0 ) + { + QStringList bandNameValues; + GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, BandNo ); + GDALmetadata = GDALGetMetadata( gdalBand, NULL ); + + if ( GDALmetadata ) + { + metadata = cStringList2Q_( GDALmetadata ); + for ( QStringList::const_iterator i = metadata.begin(); + i != metadata.end(); + ++i ) + { + QString val(*i); + if ( !val.startsWith( "NETCDF_DIM_" ) ) + continue; + QStringList values = val.split( "=" ); + for ( QStringList::const_iterator j = dimExtraValues.begin(); + j != dimExtraValues.end(); + ++j ) + { + QString dim = (*j); + if ( values.at( 0 ) != "NETCDF_DIM_"+dim ) + continue; + if ( unitsMap.contains( dim ) ) + bandNameValues.append( values.at(1)+" "+unitsMap[ dim ] ); + else + bandNameValues.append( values.at(1) ); + } + } + } + if ( bandNameValues.count() > 0 ) + return bandNameValues.join(" "); + } + } + } +#endif +#endif + return tr( "Band" ) + QString( " %1" ) .arg( BandNo, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) ); +} + QgsRasterIdentifyResult QgsGdalProvider::identify( const QgsPoint & thePoint, QgsRaster::IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight ) { QgsDebugMsg( QString( "thePoint = %1 %2" ).arg( thePoint.x(), 0, 'g', 10 ).arg( thePoint.y(), 0, 'g', 10 ) ); diff --git a/src/providers/gdal/qgsgdalprovider.h b/src/providers/gdal/qgsgdalprovider.h index 9e766626218..ff9a22b42c2 100644 --- a/src/providers/gdal/qgsgdalprovider.h +++ b/src/providers/gdal/qgsgdalprovider.h @@ -169,6 +169,8 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase int xSize() const; int ySize() const; + QString generateBandName( int theBandNumber ) const; + /**Reimplemented from QgsRasterDataProvider to bypass second resampling (more efficient for local file based sources)*/ QgsRasterBlock *block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight ); From 77108827e9f9a272ed2587538d474378cdc43f56 Mon Sep 17 00:00:00 2001 From: Etienne Tourigny Date: Tue, 18 Mar 2014 22:32:15 -0300 Subject: [PATCH 2/2] change output of QgsGdalProvider::generateBandName() and fix indentation --- src/providers/gdal/qgsgdalprovider.cpp | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/providers/gdal/qgsgdalprovider.cpp b/src/providers/gdal/qgsgdalprovider.cpp index 9a2a430b64d..e4384602169 100644 --- a/src/providers/gdal/qgsgdalprovider.cpp +++ b/src/providers/gdal/qgsgdalprovider.cpp @@ -876,10 +876,10 @@ int QgsGdalProvider::yBlockSize() const int QgsGdalProvider::xSize() const { return mWidth; } int QgsGdalProvider::ySize() const { return mHeight; } -QString QgsGdalProvider::generateBandName( int BandNo ) const +QString QgsGdalProvider::generateBandName( int theBandNumber ) const { #ifdef GDAL_COMPUTE_VERSION /* only available in GDAL 1.10 or later */ -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,10,0) +#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,10,0) if ( strcmp( GDALGetDriverShortName( GDALGetDatasetDriver( mGdalDataset ) ), "netCDF" ) == 0 ) { char ** GDALmetadata = GDALGetMetadata( mGdalDataset, NULL ); @@ -890,60 +890,62 @@ QString QgsGdalProvider::generateBandName( int BandNo ) const QStringList dimExtraValues; QMap< QString, QString > unitsMap; for ( QStringList::const_iterator i = metadata.begin(); - i != metadata.end(); - ++i ) + i != metadata.end(); ++i ) { - QString val(*i); + QString val( *i ); if ( !val.startsWith( "NETCDF_DIM_EXTRA" ) && !val.contains( "#units=" ) ) continue; QStringList values = val.split( "=" ); val = values.at( 1 ); - if ( values.at( 0 ) == "NETCDF_DIM_EXTRA" ) { - dimExtraValues = val.replace(QString("{"), QString("")).replace(QString("}"), QString("")).split(","); + if ( values.at( 0 ) == "NETCDF_DIM_EXTRA" ) + { + dimExtraValues = val.replace( QString( "{" ), QString( "" ) ).replace( QString( "}" ), QString( "" ) ).split( "," ); //http://qt-project.org/doc/qt-4.8/qregexp.html#capturedTexts - } else { - unitsMap[ values.at(0).split( "#" ).at(0) ] = val; + } + else + { + unitsMap[ values.at( 0 ).split( "#" ).at( 0 )] = val; } } if ( dimExtraValues.count() > 0 ) { QStringList bandNameValues; - GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, BandNo ); + GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, theBandNumber ); GDALmetadata = GDALGetMetadata( gdalBand, NULL ); if ( GDALmetadata ) { metadata = cStringList2Q_( GDALmetadata ); for ( QStringList::const_iterator i = metadata.begin(); - i != metadata.end(); - ++i ) + i != metadata.end(); ++i ) { - QString val(*i); + QString val( *i ); if ( !val.startsWith( "NETCDF_DIM_" ) ) continue; QStringList values = val.split( "=" ); for ( QStringList::const_iterator j = dimExtraValues.begin(); - j != dimExtraValues.end(); - ++j ) + j != dimExtraValues.end(); ++j ) { - QString dim = (*j); - if ( values.at( 0 ) != "NETCDF_DIM_"+dim ) + QString dim = ( *j ); + if ( values.at( 0 ) != "NETCDF_DIM_" + dim ) continue; - if ( unitsMap.contains( dim ) ) - bandNameValues.append( values.at(1)+" "+unitsMap[ dim ] ); + if ( unitsMap.contains( dim ) && unitsMap[ dim ] != "" && unitsMap[ dim ] != "none" ) + bandNameValues.append( dim + "=" + values.at( 1 ) + " (" + unitsMap[ dim ] + ")" ); else - bandNameValues.append( values.at(1) ); + bandNameValues.append( dim + "=" + values.at( 1 ) ); } } } + if ( bandNameValues.count() > 0 ) - return bandNameValues.join(" "); + return tr( "Band" ) + QString( " %1 / %2" ) .arg( theBandNumber, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) ).arg( bandNameValues.join( " / " ) ); } } } #endif #endif - return tr( "Band" ) + QString( " %1" ) .arg( BandNo, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) ); + + return QgsRasterDataProvider::generateBandName( theBandNumber ); } QgsRasterIdentifyResult QgsGdalProvider::identify( const QgsPoint & thePoint, QgsRaster::IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )