Skip to content

Commit 2ef60da

Browse files
committedSep 4, 2012
raster transparency floating point fix
1 parent a441282 commit 2ef60da

14 files changed

+246
-96
lines changed
 

‎src/app/qgsrasterlayerproperties.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ void QgsRasterLayerProperties::on_pbnDefaultValues_clicked()
996996

997997
void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double value )
998998
{
999+
QgsDebugMsg( QString( "value = %1" ).arg( value, 0, 'g', 17 ) );
9991000
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();
10001001
if ( !provider ) return;
10011002

@@ -1026,7 +1027,7 @@ void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double
10261027
lineEdit->setValidator( new QDoubleValidator( 0 ) );
10271028
if ( !qIsNaN( value ) )
10281029
{
1029-
valueString = QString::number( value, 'f' );
1030+
valueString = QgsRasterInterface::printValue( value );
10301031
}
10311032
break;
10321033
default:
@@ -1040,18 +1041,23 @@ void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double
10401041
lineEdit->setText( valueString );
10411042
}
10421043
tableTransparency->setCellWidget( row, column, lineEdit );
1044+
adjustTransparencyCellWidth( row, column );
10431045

10441046
if ( nBands == 1 && ( column == 0 || column == 1 ) )
10451047
{
10461048
connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( transparencyCellTextEdited( const QString & ) ) );
10471049
}
1050+
tableTransparency->resizeColumnsToContents();
10481051
}
10491052

10501053
void QgsRasterLayerProperties::setTransparencyCellValue( int row, int column, double value )
10511054
{
10521055
QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( tableTransparency->cellWidget( row, column ) );
10531056
if ( !lineEdit ) return;
1054-
lineEdit->setText( QString::number( value, 'f' ) );
1057+
lineEdit->setText( QgsRasterInterface::printValue( value ) );
1058+
lineEdit->adjustSize();
1059+
adjustTransparencyCellWidth( row, column );
1060+
tableTransparency->resizeColumnsToContents();
10551061
}
10561062

10571063
double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
@@ -1064,6 +1070,17 @@ double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
10641070
return lineEdit->text().toDouble();
10651071
}
10661072

1073+
void QgsRasterLayerProperties::adjustTransparencyCellWidth( int row, int column )
1074+
{
1075+
QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( tableTransparency->cellWidget( row, column ) );
1076+
if ( !lineEdit ) return;
1077+
1078+
int width = qMax( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
1079+
width = qMax( width, tableTransparency->columnWidth( column ) );
1080+
1081+
lineEdit->setFixedWidth( width );
1082+
}
1083+
10671084
void QgsRasterLayerProperties::on_pbnExportTransparentPixelValues_clicked()
10681085
{
10691086
QSettings myQSettings;
@@ -1312,30 +1329,27 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
13121329
//Get the pixel values and add a new entry to the transparency table
13131330
if ( mMapCanvas && mPixelSelectorTool )
13141331
{
1315-
QMap< int, QString > myPixelMap;
13161332
mMapCanvas->unsetMapTool( mPixelSelectorTool );
1317-
mRasterLayer->identify( mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, canvasPoint ), myPixelMap );
1333+
QMap< int, void *> myPixelMap = mRasterLayer->dataProvider()->identify( mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, canvasPoint ) );
13181334

13191335
QList<int> bands = renderer->usesBands();
1320-
delete renderer;
13211336

1337+
QgsRasterDataProvider * provider = mRasterLayer->dataProvider();
13221338
QList<double> values;
13231339
for ( int i = 0; i < bands.size(); ++i )
13241340
{
1325-
QMap< int, QString >::const_iterator pixelResult = myPixelMap.find( bands.at( i ) );
1326-
if ( pixelResult != myPixelMap.constEnd() )
1341+
int bandNo = bands.value( i );
1342+
if ( myPixelMap.count( bandNo ) == 1 )
13271343
{
1328-
QString value = pixelResult.value();
1329-
if ( value != tr( "out of extent" ) )
1344+
void * data = myPixelMap.value( bandNo );
1345+
double value = provider->readValue( data, provider->dataType( bandNo ), 0 );
1346+
QgsDebugMsg( QString( "value = %1" ).arg( value, 0, 'g', 17 ) );
1347+
1348+
if ( provider->isNoDataValue( bandNo, value ) )
13301349
{
1331-
QgsDebugMsg( QString( "Is it %1 of band %2 nodata?" ).arg( value ).arg( bands.at( i ) ) );
1332-
if ( value == tr( "null (no data)" ) || // Very bad! TODO: improve identify
1333-
mRasterLayer->dataProvider()->isNoDataValue( bands.at( i ), value.toDouble() ) )
1334-
{
1335-
return; // Don't add nodata, transparent anyway
1336-
}
1337-
values.append( value.toDouble() );
1350+
return; // Don't add nodata, transparent anyway
13381351
}
1352+
values.append( value );
13391353
}
13401354
}
13411355
if ( bands.size() == 1 )
@@ -1350,6 +1364,7 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
13501364
}
13511365
setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
13521366
}
1367+
delete renderer;
13531368

13541369
tableTransparency->resizeColumnsToContents();
13551370
tableTransparency->resizeRowsToContents();

‎src/app/qgsrasterlayerproperties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
149149
void setTransparencyCellValue( int row, int column, double value );
150150
double transparencyCellValue( int row, int column );
151151
void setTransparencyToEdited( int row );
152+
void adjustTransparencyCellWidth( int row, int column );
152153

153154
void setRendererWidget( const QString& rendererName );
154155

‎src/core/qgsrasterdataprovider.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ QString QgsRasterDataProvider::capabilitiesString() const
202202
return abilitiesList.join( ", " );
203203
}
204204

205+
#if 0
205206
bool QgsRasterDataProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
206207
{
207208
Q_UNUSED( thePoint );
@@ -215,6 +216,41 @@ bool QgsRasterDataProvider::identify( const QgsPoint & point, QMap<int, QString>
215216
results.clear();
216217
return false;
217218
}
219+
#endif
220+
221+
QMap<int, void *> QgsRasterDataProvider::identify( const QgsPoint & point )
222+
{
223+
QMap<int, void *> results;
224+
225+
QgsRectangle myExtent = extent();
226+
227+
for ( int i = 1; i <= bandCount(); i++ )
228+
{
229+
double x = point.x();
230+
double y = point.y();
231+
232+
// Calculate the row / column where the point falls
233+
double xres = ( myExtent.xMaximum() - myExtent.xMinimum() ) / xSize();
234+
double yres = ( myExtent.yMaximum() - myExtent.yMinimum() ) / ySize();
235+
236+
int col = ( int ) floor(( x - myExtent.xMinimum() ) / xres );
237+
int row = ( int ) floor(( myExtent.yMaximum() - y ) / yres );
238+
239+
double xMin = myExtent.xMinimum() + col * xres;
240+
double xMax = xMin + xres;
241+
double yMax = myExtent.yMaximum() - row * yres;
242+
double yMin = yMax - yres;
243+
QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );
244+
245+
void * data = block( i, pixelExtent, 1, 2 );
246+
247+
if ( data )
248+
{
249+
results.insert( i, data );
250+
}
251+
}
252+
return results;
253+
}
218254

219255
QString QgsRasterDataProvider::lastErrorFormat()
220256
{

‎src/core/qgsrasterdataprovider.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,18 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
414414
virtual QString metadata() = 0;
415415

416416
/** \brief Identify raster value(s) found on the point position */
417-
virtual bool identify( const QgsPoint & point, QMap<QString, QString>& results );
417+
//virtual bool identify( const QgsPoint & point, QMap<QString, QString>& results );
418418

419-
virtual bool identify( const QgsPoint & point, QMap<int, QString>& results );
419+
//virtual bool identify( const QgsPoint & point, QMap<int, QString>& results );
420+
421+
/** \brief Identify raster value(s) found on the point position
422+
* @param point coordinates in data source CRS
423+
* @return list of pointers to data blocks for all bands,
424+
* caller is responsible to free the allocated memory,
425+
* readValue() may be used to get values
426+
*/
427+
// TODO: Consider QVariant or similar instead of void*
428+
virtual QMap<int, void *> identify( const QgsPoint & point );
420429

421430
/**
422431
* \brief Identify details from a server (e.g. WMS) from the last screen update

‎src/core/raster/qgsrasterinterface.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,41 @@ double QgsRasterInterface::time( bool cumulative )
210210
return t;
211211
}
212212

213+
QString QgsRasterInterface::printValue( double value )
214+
{
215+
/*
216+
* IEEE 754 double has 15-17 significant digits. It specifies:
217+
*
218+
* "If a decimal string with at most 15 significant decimal is converted to
219+
* IEEE 754 double precision and then converted back to the same number of
220+
* significant decimal, then the final string should match the original;
221+
* and if an IEEE 754 double precision is converted to a decimal string with at
222+
* least 17 significant decimal and then converted back to double, then the final
223+
* number must match the original."
224+
*
225+
* If printing only 15 digits, some precision could be lost. Printing 17 digits may
226+
* add some confusing digits.
227+
*
228+
* Default 'g' precision on linux is 6 digits, not all significant digits like
229+
* some sprintf manuals say.
230+
*
231+
* We need to ensure that the number printed and used in QLineEdit or XML will
232+
* give the same number when parsed.
233+
*
234+
* Is there a better solution?
235+
*/
236+
237+
QString s;
238+
239+
for ( int i = 15; i <= 17; i++ )
240+
{
241+
s.setNum( value, 'g', i );
242+
if ( s.toDouble() == value )
243+
{
244+
return s;
245+
}
246+
}
247+
// Should not happen
248+
QgsDebugMsg( "Cannot correctly parse printed value" );
249+
return s;
250+
}

‎src/core/raster/qgsrasterinterface.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ class CORE_EXPORT QgsRasterInterface
191191
* returned. */
192192
double time( bool cumulative = false );
193193

194+
/** \brief Print double value with all necessary significant digits.
195+
* It is ensured that conversion back to double gives the same number.
196+
* @param value the value to be printed
197+
* @return string representing the value*/
198+
static QString printValue( double value );
199+
194200
protected:
195201
// QgsRasterInterface used as input
196202
QgsRasterInterface* mInput;
@@ -255,7 +261,6 @@ inline double QgsRasterInterface::readValue( void *data, QgsRasterInterface::Dat
255261

256262
inline void QgsRasterInterface::writeValue( void *data, QgsRasterInterface::DataType type, int index, double value )
257263
{
258-
if ( !mInput ) return;
259264
if ( !data ) return;
260265

261266
switch ( type )

‎src/core/raster/qgsrasterlayer.cpp

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -957,22 +957,62 @@ bool QgsRasterLayer::hasStatistics( int theBandNo )
957957
bool QgsRasterLayer::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
958958
{
959959
theResults.clear();
960-
// QgsDebugMsg( "identify provider : " + mProviderKey ) ;
961-
return ( mDataProvider->identify( thePoint, theResults ) );
960+
961+
if ( !mDataProvider ) return false;
962+
963+
QMap<int, QString> results;
964+
if ( ! identify( thePoint, results ) ) return false;
965+
966+
foreach ( int bandNo, results.keys() )
967+
{
968+
theResults[ mDataProvider->generateBandName( bandNo )] = results.value( bandNo );
969+
}
970+
return true;
962971
}
963972

964-
bool QgsRasterLayer::identify( const QgsPoint & point, QMap<int, QString>& results )
973+
bool QgsRasterLayer::identify( const QgsPoint & point, QMap<int, QString>& theResults )
965974
{
966-
if ( !mDataProvider )
975+
if ( !mDataProvider ) return false;
976+
977+
theResults.clear();
978+
//return mDataProvider->identify( point, theResults );
979+
980+
QMap<int, void *> dataMap = mDataProvider->identify( point );
981+
foreach ( int bandNo, dataMap.keys() )
967982
{
968-
return false;
983+
QgsRasterInterface::DataType dataType = mDataProvider->dataType( bandNo );
984+
void * data = dataMap.value( bandNo );
985+
QString str;
986+
if ( !data )
987+
{
988+
str = tr( "Cannot read data" );
989+
}
990+
else
991+
{
992+
if ( mDataProvider->typeIsNumeric( dataType ) )
993+
{
994+
double value = mDataProvider->readValue( data, dataType, 0 );
995+
if ( mDataProvider->isNoDataValue( bandNo, value ) )
996+
{
997+
str = tr( "null (no data)" );
998+
}
999+
else
1000+
{
1001+
str.setNum( value );
1002+
}
1003+
}
1004+
else
1005+
{
1006+
QRgb c((( uint* )data )[0] );
1007+
str = QString( "%1,%2,%3,%4" ).arg( qRed( c ) ).arg( qGreen( c ) ).arg( qBlue( c ) ).arg( qAlpha( c ) );
1008+
}
1009+
free( data );
1010+
}
1011+
theResults[ bandNo ] = str;
9691012
}
970-
971-
results.clear();
972-
return mDataProvider->identify( point, results );
1013+
return true;
9731014
}
9741015

975-
9761016
/**
9771017
* @note The arbitraryness of the returned document is enforced by WMS standards up to at least v1.3.0
9781018
*

‎src/core/raster/qgsrastertransparency.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ email : ersts@amnh.org
1616
* *
1717
***************************************************************************/
1818

19+
#include "qgsrasterinterface.h"
1920
#include "qgsrastertransparency.h"
2021
#include "qgis.h"
2122
#include "qgslogger.h"
@@ -114,7 +115,9 @@ int QgsRasterTransparency::alphaValue( double theValue, int theGlobalTransparenc
114115
for ( int myListRunner = 0; myListRunner < mTransparentSingleValuePixelList.count(); myListRunner++ )
115116
{
116117
myTransparentPixel = mTransparentSingleValuePixelList[myListRunner];
117-
if ( theValue >= myTransparentPixel.min && theValue <= myTransparentPixel.max )
118+
if (( theValue >= myTransparentPixel.min && theValue <= myTransparentPixel.max ) ||
119+
doubleNear( theValue, myTransparentPixel.min ) ||
120+
doubleNear( theValue, myTransparentPixel.max ) )
118121
{
119122
myTransparentPixelFound = true;
120123
break;
@@ -181,8 +184,8 @@ bool QgsRasterTransparency::isEmpty( double nodataValue ) const
181184
( mTransparentSingleValuePixelList.size() == 1 &&
182185
( doubleNear( mTransparentSingleValuePixelList.at( 0 ).min, nodataValue ) ||
183186
doubleNear( mTransparentSingleValuePixelList.at( 0 ).max, nodataValue ) ||
184-
( nodataValue > mTransparentSingleValuePixelList.at( 0 ).min &&
185-
nodataValue < mTransparentSingleValuePixelList.at( 0 ).max ) ) ) )
187+
( nodataValue >= mTransparentSingleValuePixelList.at( 0 ).min &&
188+
nodataValue <= mTransparentSingleValuePixelList.at( 0 ).max ) ) ) )
186189
&&
187190
( mTransparentThreeValuePixelList.isEmpty() ||
188191
( mTransparentThreeValuePixelList.size() == 1 &&
@@ -202,8 +205,8 @@ void QgsRasterTransparency::writeXML( QDomDocument& doc, QDomElement& parentElem
202205
{
203206
QDomElement pixelListElement = doc.createElement( "pixelListEntry" );
204207
//pixelListElement.setAttribute( "pixelValue", QString::number( it->pixelValue, 'f' ) );
205-
pixelListElement.setAttribute( "min", QString::number( it->min, 'f' ) );
206-
pixelListElement.setAttribute( "max", QString::number( it->max, 'f' ) );
208+
pixelListElement.setAttribute( "min", QgsRasterInterface::printValue( it->min ) );
209+
pixelListElement.setAttribute( "max", QgsRasterInterface::printValue( it->max ) );
207210
pixelListElement.setAttribute( "percentTransparent", QString::number( it->percentTransparent ) );
208211
singleValuePixelListElement.appendChild( pixelListElement );
209212
}
@@ -217,9 +220,9 @@ void QgsRasterTransparency::writeXML( QDomDocument& doc, QDomElement& parentElem
217220
for ( ; it != mTransparentThreeValuePixelList.constEnd(); ++it )
218221
{
219222
QDomElement pixelListElement = doc.createElement( "pixelListEntry" );
220-
pixelListElement.setAttribute( "red", QString::number( it->red, 'f' ) );
221-
pixelListElement.setAttribute( "green", QString::number( it->green, 'f' ) );
222-
pixelListElement.setAttribute( "blue", QString::number( it->blue, 'f' ) );
223+
pixelListElement.setAttribute( "red", QgsRasterInterface::printValue( it->red ) );
224+
pixelListElement.setAttribute( "green", QgsRasterInterface::printValue( it->green ) );
225+
pixelListElement.setAttribute( "blue", QgsRasterInterface::printValue( it->blue ) );
223226
pixelListElement.setAttribute( "percentTransparent", QString::number( it->percentTransparent ) );
224227
threeValuePixelListElement.appendChild( pixelListElement );
225228
}

‎src/providers/gdal/qgsgdalprovider.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ QgsGdalProvider::QgsGdalProvider( QString const & uri )
103103

104104
QgsGdalProviderBase::registerGdalDrivers();
105105

106+
// GDAL tends to open AAIGrid as Float32 which results in lost precision
107+
// and confusing values shown to users, force Float64
108+
CPLSetConfigOption( "AAIGRID_DATATYPE", "Float64" );
109+
106110
// To get buildSupportedRasterFileFilter the provider is called with empty uri
107111
if ( uri.isEmpty() )
108112
{
@@ -816,15 +820,18 @@ int QgsGdalProvider::yBlockSize() const
816820
int QgsGdalProvider::xSize() const { return mWidth; }
817821
int QgsGdalProvider::ySize() const { return mHeight; }
818822

819-
bool QgsGdalProvider::identify( const QgsPoint & point, QMap<int, QString>& results )
823+
QMap<int, void *> QgsGdalProvider::identify( const QgsPoint & point )
820824
{
821-
// QgsDebugMsg( "Entered" );
825+
QgsDebugMsg( "Entered" );
826+
QMap<int, void *> results;
822827
if ( !mExtent.contains( point ) )
823828
{
824829
// Outside the raster
825830
for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
826831
{
827-
results[ i ] = tr( "out of extent" );
832+
void * data = VSIMalloc( dataTypeSize( i ) / 8 );
833+
writeValue( data, dataType( i ), 0, noDataValue() );
834+
results.insert( i, data );
828835
}
829836
}
830837
else
@@ -845,7 +852,6 @@ bool QgsGdalProvider::identify( const QgsPoint & point, QMap<int, QString>& resu
845852
for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
846853
{
847854
GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
848-
double data[4];
849855

850856
int r = 0;
851857
int c = 0;
@@ -872,38 +878,29 @@ bool QgsGdalProvider::identify( const QgsPoint & point, QMap<int, QString>& resu
872878
}
873879
}
874880
#endif
881+
int typeSize = dataTypeSize( i ) / 8;
882+
void * tmpData = VSIMalloc( typeSize * width * height );
875883

876884
CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, width, height,
877-
data, width, height, GDT_Float64, 0, 0 );
885+
tmpData, width, height,
886+
( GDALDataType ) mGdalDataType[i-1], 0, 0 );
878887

879888
if ( err != CPLE_None )
880889
{
881890
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
882891
}
883-
double value = data[r*2+c];
892+
void * data = VSIMalloc( typeSize );
893+
memcpy( data, ( void* )(( char* )tmpData + ( r*width + c )*typeSize ), typeSize );
894+
results.insert( i, data );
884895

885-
//double value = readValue( data, type, 0 );
886-
// QgsDebugMsg( QString( "value=%1" ).arg( value ) );
887-
QString v;
888-
889-
if ( mValidNoDataValue && ( fabs( value - mNoDataValue[i-1] ) <= TINY_VALUE || value != value ) )
890-
{
891-
v = tr( "null (no data)" );
892-
}
893-
else
894-
{
895-
v.setNum( value );
896-
}
897-
898-
results[ i ] = v;
899-
900-
//CPLFree( data );
896+
CPLFree( tmpData );
901897
}
902898
}
903899

904-
return true;
900+
return results;
905901
}
906902

903+
#if 0
907904
bool QgsGdalProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
908905
{
909906
QMap<int, QString> results;
@@ -914,6 +911,7 @@ bool QgsGdalProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>
914911
}
915912
return true;
916913
}
914+
#endif
917915

918916
int QgsGdalProvider::capabilities() const
919917
{

‎src/providers/gdal/qgsgdalprovider.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
122122
bool isValid();
123123

124124
/** \brief Identify raster value(s) found on the point position */
125-
bool identify( const QgsPoint & point, QMap<QString, QString>& results );
125+
//bool identify( const QgsPoint & point, QMap<QString, QString>& results );
126126

127-
bool identify( const QgsPoint & point, QMap<int, QString>& results );
127+
//bool identify( const QgsPoint & point, QMap<int, QString>& results );
128+
129+
QMap<int, void *> identify( const QgsPoint & point );
128130

129131
/**
130132
* \brief Identify details from a GDAL layer from the last screen update

‎src/providers/grass/qgsgrassrasterprovider.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -364,25 +364,35 @@ int QgsGrassRasterProvider::yBlockSize() const
364364
int QgsGrassRasterProvider::xSize() const { return mCols; }
365365
int QgsGrassRasterProvider::ySize() const { return mRows; }
366366

367-
bool QgsGrassRasterProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
367+
QMap<int, void *> QgsGrassRasterProvider::identify( const QgsPoint & thePoint )
368368
{
369369
QgsDebugMsg( "Entered" );
370-
//theResults["Error"] = tr( "Out of extent" );
370+
QMap<int, void *> results;
371+
372+
// TODO: use doubles instead of strings
371373
//theResults = QgsGrass::query( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
372-
QString value = mRasterValue.value( thePoint.x(), thePoint.y() );
373-
theResults.clear();
374+
QString strValue = mRasterValue.value( thePoint.x(), thePoint.y() );
374375
// attention, value tool does his own tricks with grass identify() so it stops to refresh values outside extent or null values e.g.
375-
if ( value == "out" )
376-
{
377-
value = tr( "Out of extent" );
378-
}
379-
if ( value == "null" )
376+
377+
double value = noDataValue();
378+
379+
if ( strValue != "out" && strValue != "null" )
380380
{
381-
value = tr( "null (no data)" );
381+
bool ok;
382+
value = strValue.toDouble( & ok );
383+
if ( !ok )
384+
{
385+
value = 999999999;
386+
QgsDebugMsg( "Cannot convert string to double" );
387+
}
382388
}
383-
theResults["value"] = value;
384-
QgsDebugMsg( "value = " + value );
385-
return true;
389+
void * data = malloc( dataTypeSize( 1 ) / 8 );
390+
writeValue( data, dataType( 1 ), 0, value );
391+
392+
results.insert( 1, data );
393+
QgsDebugMsg( "strValue = " + strValue );
394+
395+
return results;
386396
}
387397

388398
int QgsGrassRasterProvider::capabilities() const

‎src/providers/grass/qgsgrassrasterprovider.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider
141141
bool isValid();
142142

143143
/** \brief Identify raster value(s) found on the point position */
144-
bool identify( const QgsPoint & point, QMap<QString, QString>& results );
144+
//bool identify( const QgsPoint & point, QMap<QString, QString>& results );
145+
QMap<int, void *> identify( const QgsPoint & thePoint );
145146

146147
/**
147148
* \brief Identify details from a GRASS layer from the last screen update

‎src/providers/wcs/qgswcsprovider.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,19 +1503,21 @@ QString QgsWcsProvider:: htmlRow( const QString &text1, const QString &text2 )
15031503
return "<tr>" + htmlCell( text1 ) + htmlCell( text2 ) + "</tr>";
15041504
}
15051505

1506-
bool QgsWcsProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
1506+
QMap<int, void *> QgsWcsProvider::identify( const QgsPoint & thePoint )
15071507
{
15081508
QgsDebugMsg( "Entered" );
1509-
theResults.clear();
1509+
QMap<int, void *> results;
15101510

15111511
if ( !extent().contains( thePoint ) )
15121512
{
15131513
// Outside the raster
15141514
for ( int i = 1; i <= bandCount(); i++ )
15151515
{
1516-
theResults[ generateBandName( i )] = tr( "out of extent" );
1516+
void * data = VSIMalloc( dataTypeSize( i ) / 8 );
1517+
writeValue( data, dataType( i ), 0, noDataValue() );
1518+
results.insert( i, data );
15171519
}
1518-
return true;
1520+
return results;
15191521
}
15201522

15211523
// It would be nice to use last cached block if possible, unfortunately we don't know
@@ -1556,7 +1558,7 @@ bool QgsWcsProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>&
15561558
if ( !mCachedGdalDataset ||
15571559
!mCachedViewExtent.contains( thePoint ) )
15581560
{
1559-
return false; // should not happen
1561+
return results; // should not happen
15601562
}
15611563

15621564
double x = thePoint.x();
@@ -1575,31 +1577,20 @@ bool QgsWcsProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>&
15751577
for ( int i = 1; i <= GDALGetRasterCount( mCachedGdalDataset ); i++ )
15761578
{
15771579
GDALRasterBandH gdalBand = GDALGetRasterBand( mCachedGdalDataset, i );
1578-
double value;
15791580

1581+
void * data = VSIMalloc( dataTypeSize( i ) / 8 );
15801582
CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, 1, 1,
1581-
&value, 1, 1, GDT_Float64, 0, 0 );
1583+
data, 1, 1, ( GDALDataType ) mGdalDataType[i-1], 0, 0 );
15821584

15831585
if ( err != CPLE_None )
15841586
{
15851587
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
15861588
}
15871589

1588-
QString v;
1589-
1590-
if ( mValidNoDataValue && ( fabs( value - mNoDataValue[i-1] ) <= TINY_VALUE || value != value ) )
1591-
{
1592-
v = tr( "null (no data)" );
1593-
}
1594-
else
1595-
{
1596-
v.setNum( value );
1597-
}
1598-
1599-
theResults[ generateBandName( i )] = v;
1590+
results.insert( i, data );
16001591
}
16011592

1602-
return true;
1593+
return results;
16031594
}
16041595

16051596
QString QgsWcsProvider::identifyAsText( const QgsPoint &point )

‎src/providers/wcs/qgswcsprovider.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ class QgsWcsProvider : public QgsRasterDataProvider, QgsGdalProviderBase
153153
int xSize() const;
154154
int ySize() const;
155155
QString metadata();
156-
bool identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults );
156+
//bool identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults );
157+
QMap<int, void *> identify( const QgsPoint & thePoint );
157158
QString identifyAsHtml( const QgsPoint& point );
158159
QString identifyAsText( const QgsPoint& point );
159160
QString lastErrorTitle();

0 commit comments

Comments
 (0)
Please sign in to comment.