@@ -259,8 +259,9 @@ QgsWcsProvider::QgsWcsProvider( QString const &uri )
259
259
mFixBox = true ;
260
260
QgsDebugMsg ( " Test response size is smaller by pixel, using mFixBox" );
261
261
}
262
- // Geoserver is sometimes giving rotated raster (probably for geographic CRS,
263
- // switched axis?)
262
+ // Geoserver is giving rotated raster for geographic CRS - switched axis,
263
+ // Geoserver developers argue that changed axis order applies also to
264
+ // returned raster, that is exagerated IMO but we have to handle that.
264
265
if (( responseWidth == requestHeight && responseHeight == requestWidth ) ||
265
266
( responseWidth == requestHeight - 1 && responseHeight == requestWidth - 1 ) )
266
267
{
@@ -546,33 +547,47 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
546
547
547
548
if ( mCachedGdalDataset )
548
549
{
549
- int width = GDALGetRasterXSize ( mCachedGdalDataset );
550
- int height = GDALGetRasterYSize ( mCachedGdalDataset );
551
-
552
550
// It may happen (Geoserver) that if requested BBOX is larger than coverage
553
551
// extent, the returned data cover intersection of requested BBOX and coverage
554
552
// extent scaled to requested WIDTH/HEIGHT => check extent
553
+ // Unfortunately if received raster does not hac CRS, the extent is raster size
554
+ // and in that case it cannot be used to verify extent
555
+ QgsCoordinateReferenceSystem cacheCrs;
556
+ if ( !cacheCrs.createFromWkt ( GDALGetProjectionRef ( mCachedGdalDataset ) ) &&
557
+ !cacheCrs.createFromWkt ( GDALGetGCPProjection ( mCachedGdalDataset ) ) )
558
+ {
559
+ QgsDebugMsg ( " Cached does not have CRS" );
560
+ }
561
+ QgsDebugMsg ( " Cache CRS: " + cacheCrs.authid () + " " + cacheCrs.description () );
562
+
555
563
QgsRectangle cacheExtent = QgsGdalProviderBase::extent ( mCachedGdalDataset );
556
564
QgsDebugMsg ( " viewExtent = " + viewExtent.toString () );
557
565
QgsDebugMsg ( " cacheExtent = " + cacheExtent.toString () );
558
- // using doubleNear is too precise, example accetable difference:
559
- // 179.9999999306699863 x 179.9999999306700431
560
- if ( !doubleNearSig ( cacheExtent.xMinimum (), viewExtent.xMinimum (), 10 ) ||
561
- !doubleNearSig ( cacheExtent.yMinimum (), viewExtent.yMinimum (), 10 ) ||
562
- !doubleNearSig ( cacheExtent.xMaximum (), viewExtent.xMaximum (), 10 ) ||
563
- !doubleNearSig ( cacheExtent.yMaximum (), viewExtent.yMaximum (), 10 ) )
566
+ // TODO: check also rotated
567
+ if ( cacheCrs.isValid () && !mFixRotate )
564
568
{
565
- QgsDebugMsg ( " cacheExtent and viewExtent differ" );
566
- QgsMessageLog::logMessage ( tr ( " Received coverage has wrong extent %1 (expected %2)" ).arg ( cacheExtent.toString () ).arg ( viewExtent.toString () ), tr ( " WCS" ) );
567
- // We are doing all possible to avoid this situation,
568
- // If it happens, it would be possible to rescale the portion we get
569
- // to only part of the data block, but it is better to left it
570
- // blank, so that the problem may be discovered in its origin.
571
- return ;
569
+ // using doubleNear is too precise, example accetable difference:
570
+ // 179.9999999306699863 x 179.9999999306700431
571
+ if ( !doubleNearSig ( cacheExtent.xMinimum (), viewExtent.xMinimum (), 10 ) ||
572
+ !doubleNearSig ( cacheExtent.yMinimum (), viewExtent.yMinimum (), 10 ) ||
573
+ !doubleNearSig ( cacheExtent.xMaximum (), viewExtent.xMaximum (), 10 ) ||
574
+ !doubleNearSig ( cacheExtent.yMaximum (), viewExtent.yMaximum (), 10 ) )
575
+ {
576
+ QgsDebugMsg ( " cacheExtent and viewExtent differ" );
577
+ QgsMessageLog::logMessage ( tr ( " Received coverage has wrong extent %1 (expected %2)" ).arg ( cacheExtent.toString () ).arg ( viewExtent.toString () ), tr ( " WCS" ) );
578
+ // We are doing all possible to avoid this situation,
579
+ // If it happens, it would be possible to rescale the portion we get
580
+ // to only part of the data block, but it is better to left it
581
+ // blank, so that the problem may be discovered in its origin.
582
+ return ;
583
+ }
572
584
}
573
585
574
- GDALRasterBandH gdalBand = GDALGetRasterBand ( mCachedGdalDataset , bandNo );
586
+ int width = GDALGetRasterXSize ( mCachedGdalDataset );
587
+ int height = GDALGetRasterYSize ( mCachedGdalDataset );
575
588
QgsDebugMsg ( QString ( " cached data width = %1 height = %2 (expected %3 x %4)" ).arg ( width ).arg ( height ).arg ( pixelWidth ).arg ( pixelHeight ) );
589
+
590
+ GDALRasterBandH gdalBand = GDALGetRasterBand ( mCachedGdalDataset , bandNo );
576
591
// TODO: check type? , check band count?
577
592
if ( mFixRotate && width == pixelHeight && height == pixelWidth )
578
593
{
@@ -742,12 +757,16 @@ void QgsWcsProvider::getCache( int bandNo, QgsRectangle const & viewExtent, int
742
757
// GridOffsets WCS 1.1:
743
758
// GridType urn:ogc:def:method:WCS:1.1:2dSimpleGrid : 2 values
744
759
// GridType urn:ogc:def:method:WCS:1.1:2dGridIn2dCrs : 4 values, the center two of these offsets will be zero when the GridCRS is not rotated or skewed in the GridBaseCRS.
745
- // The second offset must be negative because origin is in upper corner
760
+ // The yOff must be negative because origin is in upper corner
746
761
// WCS 1.1.2: BaseX = origin(1) + offsets(1) * GridX
747
762
// BaseY = origin(2) + offsets(2) * GridY
748
763
// otherwise GeoServer gives mirrored result, however
749
764
// Mapserver works OK with both positive and negative
750
- double yOff = mFixRotate ? yRes : -yRes;
765
+ // OTOH, the yOff offset must not be negative with mFixRotate and Geoserver 2.1-SNAPSHOT
766
+ // but it must be negative with GeoServer 2.1.3 and mFixRotate. I am not sure
767
+ // at this moment 100% -> disabling positive yOff for now - TODO: try other servers
768
+ // double yOff = mFixRotate ? yRes : -yRes; // this was working with some servers I think
769
+ double yOff = -yRes;
751
770
QString gridOffsets = QString ( changeXY ? " %2,%1" : " %1,%2" )
752
771
// setQueryItem( url, "GRIDTYPE", "urn:ogc:def:method:WCS:1.1:2dGridIn2dCrs" );
753
772
// QString gridOffsets = QString( changeXY ? "%2,0,0,%1" : "%1,0,0,%2" )
@@ -1426,13 +1445,27 @@ bool QgsWcsProvider::calculateExtent()
1426
1445
QgsRectangle cacheExtent = QgsGdalProviderBase::extent ( mCachedGdalDataset );
1427
1446
QgsDebugMsg ( " mCoverageExtent = " + mCoverageExtent .toString () );
1428
1447
QgsDebugMsg ( " cacheExtent = " + cacheExtent.toString () );
1429
- if ( !doubleNearSig ( cacheExtent.xMinimum (), mCoverageExtent .xMinimum (), 10 ) ||
1430
- !doubleNearSig ( cacheExtent.yMinimum (), mCoverageExtent .yMinimum (), 10 ) ||
1431
- !doubleNearSig ( cacheExtent.xMaximum (), mCoverageExtent .xMaximum (), 10 ) ||
1432
- !doubleNearSig ( cacheExtent.yMaximum (), mCoverageExtent .yMaximum (), 10 ) )
1448
+ QgsCoordinateReferenceSystem cacheCrs;
1449
+ if ( !cacheCrs.createFromWkt ( GDALGetProjectionRef ( mCachedGdalDataset ) ) &&
1450
+ !cacheCrs.createFromWkt ( GDALGetGCPProjection ( mCachedGdalDataset ) ) )
1433
1451
{
1434
- QgsDebugMsg ( " cacheExtent and mCoverageExtent differ, mCoverageExtent cut to cacheExtent" );
1435
- mCoverageExtent = cacheExtent;
1452
+ QgsDebugMsg ( " Cached does not have CRS" );
1453
+ }
1454
+ QgsDebugMsg ( " Cache CRS: " + cacheCrs.authid () + " " + cacheCrs.description () );
1455
+
1456
+ // We can only verify extent if CRS is set
1457
+ // If dataset comes rotated, GDAL probably cuts latitude extend, disable
1458
+ // extent check for rotated, TODO: verify
1459
+ if ( cacheCrs.isValid () && !mFixRotate )
1460
+ {
1461
+ if ( !doubleNearSig ( cacheExtent.xMinimum (), mCoverageExtent .xMinimum (), 10 ) ||
1462
+ !doubleNearSig ( cacheExtent.yMinimum (), mCoverageExtent .yMinimum (), 10 ) ||
1463
+ !doubleNearSig ( cacheExtent.xMaximum (), mCoverageExtent .xMaximum (), 10 ) ||
1464
+ !doubleNearSig ( cacheExtent.yMaximum (), mCoverageExtent .yMaximum (), 10 ) )
1465
+ {
1466
+ QgsDebugMsg ( " cacheExtent and mCoverageExtent differ, mCoverageExtent cut to cacheExtent" );
1467
+ mCoverageExtent = cacheExtent;
1468
+ }
1436
1469
}
1437
1470
}
1438
1471
else
0 commit comments