@@ -366,13 +366,15 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
366366{
367367 QgsDebugMsg ( " Entered" );
368368
369- /*
370- if ( myExpectedSize != myImageSize ) // should not happen
369+ // Requested extent must at least partialy overlap coverage extent, otherwise
370+ // server gives error. QGIS usually does not request blocks outside raster extent
371+ // (higher level checks) but it is better to do check here as well
372+ if ( !viewExtent.intersects ( mCoverageExtent ) )
371373 {
372- QgsMessageLog::logMessage( tr( "unexpected image size" ), tr( "WCS" ) );
374+ // TODO: set block to null values
375+ memset ( block, 0 , pixelWidth * pixelHeight * typeSize ( dataType ( bandNo ) ) / 8 );
373376 return ;
374377 }
375- */
376378
377379 // abort running (untiled) request
378380 if ( mCacheReply )
@@ -382,17 +384,15 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
382384 mCacheReply = 0 ;
383385 }
384386
385- // Can we reuse the previously cached image ?
386- if ( mCachedGdalDataset &&
387- mCachedViewExtent == viewExtent &&
388- mCachedViewWidth == pixelWidth &&
389- mCachedViewHeight = = pixelHeight )
387+ // Can we reuse the previously cached coverage ?
388+ if ( ! mCachedGdalDataset ||
389+ mCachedViewExtent != viewExtent ||
390+ mCachedViewWidth != pixelWidth ||
391+ mCachedViewHeight ! = pixelHeight )
390392 {
391- // return mCachedImage ;
393+ getCache ( bandNo, viewExtent, pixelWidth, pixelHeight ) ;
392394 }
393395
394- getCache ( bandNo, viewExtent, pixelWidth, pixelHeight );
395-
396396 if ( mCachedGdalDataset )
397397 {
398398 // TODO band
@@ -408,17 +408,22 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
408408 }
409409 else
410410 {
411- QgsDebugMsg ( tr ( " Recieved coverage has wrong size" ) );
411+ QgsMessageLog::logMessage ( tr ( " Received coverage has wrong size" ), tr ( " WCS " ) );
412412 return ;
413413 }
414414 }
415415}
416416
417417void QgsWcsProvider::getCache ( int bandNo, QgsRectangle const & viewExtent, int pixelWidth, int pixelHeight )
418418{
419+ QgsDebugMsg ( " Entered" );
419420 // delete cached data
420421 clearCache ();
421422
423+ mCachedViewExtent = viewExtent;
424+ mCachedViewWidth = pixelWidth;
425+ mCachedViewHeight = pixelHeight;
426+
422427 // --------------- BOUNDING BOX --------------------------------
423428 // according to the WCS spec for 1.1, some CRS have inverted axis
424429 // box:
@@ -1484,6 +1489,105 @@ QString QgsWcsProvider::metadata()
14841489 return metadata;
14851490}
14861491
1492+ bool QgsWcsProvider::identify ( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
1493+ {
1494+ QgsDebugMsg ( " Entered" );
1495+ theResults.clear ();
1496+
1497+ if ( !extent ().contains ( thePoint ) )
1498+ {
1499+ // Outside the raster
1500+ for ( int i = 1 ; i <= bandCount (); i++ )
1501+ {
1502+ theResults[ generateBandName ( i )] = tr ( " out of extent" );
1503+ }
1504+ return true ;
1505+ }
1506+
1507+ // It would be nice to use last cached block if possible, unfortunately we don't know
1508+ // at which resolution identify() is called. It may happen, that user zoomed in with
1509+ // layer switched off, canvas resolution increased, but provider cache was not refreshed.
1510+ // In that case the resolution is too low and identify() could give wron results.
1511+ // So we have to read always a block of data around the point on highest resolution
1512+ // if not already cached.
1513+ // TODO: change provider identify() prototype to pass also the resolution
1514+
1515+ int width, height;
1516+ if ( mHasSize )
1517+ {
1518+ width = mWidth ;
1519+ height = mHeight ;
1520+ }
1521+ else
1522+ {
1523+ // Bad in any case, either not precise or too much data requests
1524+ width = height = 1000 ;
1525+ }
1526+ double xRes = mCoverageExtent .width () / width;
1527+ double yRes = mCoverageExtent .height () / height;
1528+
1529+ if ( !mCachedGdalDataset ||
1530+ !mCachedViewExtent .contains ( thePoint ) ||
1531+ mCachedViewWidth == 0 || mCachedViewHeight == 0 ||
1532+ mCachedViewExtent .width () / mCachedViewWidth - xRes > TINY_VALUE ||
1533+ mCachedViewExtent .height () / mCachedViewHeight - yRes > TINY_VALUE )
1534+ {
1535+ int half = 50 ;
1536+ QgsRectangle extent ( thePoint.x () - xRes * half, thePoint.y () - yRes * half,
1537+ thePoint.x () + xRes * half, thePoint.y () + yRes * half );
1538+ getCache ( 1 , extent, 2 *half, 2 *half );
1539+
1540+ }
1541+
1542+ if ( !mCachedGdalDataset ||
1543+ !mCachedViewExtent .contains ( thePoint ) )
1544+ {
1545+ return false ; // should not happen
1546+ }
1547+
1548+ double x = thePoint.x ();
1549+ double y = thePoint.y ();
1550+
1551+ // Calculate the row / column where the point falls
1552+ xRes = ( mCachedViewExtent .xMaximum () - mCachedViewExtent .xMinimum () ) / mCachedViewWidth ;
1553+ yRes = ( mCachedViewExtent .yMaximum () - mCachedViewExtent .yMinimum () ) / mCachedViewHeight ;
1554+
1555+ // Offset, not the cell index -> flor
1556+ int col = ( int ) floor (( x - mCachedViewExtent .xMinimum () ) / xRes );
1557+ int row = ( int ) floor (( mCachedViewExtent .yMaximum () - y ) / yRes );
1558+
1559+ QgsDebugMsg ( " row = " + QString::number ( row ) + " col = " + QString::number ( col ) );
1560+
1561+ for ( int i = 1 ; i <= GDALGetRasterCount ( mCachedGdalDataset ); i++ )
1562+ {
1563+ GDALRasterBandH gdalBand = GDALGetRasterBand ( mCachedGdalDataset , i );
1564+ double value;
1565+
1566+ CPLErr err = GDALRasterIO ( gdalBand, GF_Read, col, row, 1 , 1 ,
1567+ &value, 1 , 1 , GDT_Float64, 0 , 0 );
1568+
1569+ if ( err != CPLE_None )
1570+ {
1571+ QgsLogger::warning ( " RasterIO error: " + QString::fromUtf8 ( CPLGetLastErrorMsg () ) );
1572+ }
1573+
1574+ QString v;
1575+
1576+ if ( mValidNoDataValue && ( fabs ( value - mNoDataValue [i-1 ] ) <= TINY_VALUE || value != value ) )
1577+ {
1578+ v = tr ( " null (no data)" );
1579+ }
1580+ else
1581+ {
1582+ v.setNum ( value );
1583+ }
1584+
1585+ theResults[ generateBandName ( i )] = v;
1586+ }
1587+
1588+ return true ;
1589+ }
1590+
14871591QString QgsWcsProvider::identifyAsText ( const QgsPoint &point )
14881592{
14891593 Q_UNUSED ( point );
0 commit comments