Skip to content

Commit

Permalink
Calculate better context (extent,size) if not given in WMS, WCS ident…
Browse files Browse the repository at this point in the history
…ify. Fixes #8724
  • Loading branch information
blazek committed Oct 16, 2013
1 parent 7dc20ef commit de8a5d6
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 23 deletions.
48 changes: 36 additions & 12 deletions src/providers/wcs/qgswcsprovider.cpp
Expand Up @@ -1628,28 +1628,52 @@ QgsRasterIdentifyResult QgsWcsProvider::identify( const QgsPoint & thePoint, Qgs
if ( myExtent.isEmpty() || theWidth == 0 || theHeight == 0 ||
theWidth > maxSize || theHeight > maxSize )
{
// context missing, use an area around the point and highest resolution if known
// context missing, use a small area around the point and highest resolution if known

// 1000 is bad in any case, either not precise or too much data requests
if ( theWidth == 0 ) theWidth = mHasSize ? mWidth : 1000;
if ( theHeight == 0 ) theHeight = mHasSize ? mHeight : 1000;
double xRes, yRes;
//if ( mHasSize )
if ( false )
{
xRes = mCoverageExtent.width() / mWidth;
yRes = mCoverageExtent.height() / mHeight;
}
else
{
// set resolution approximately to 1mm
switch ( mCrs.mapUnits() )
{
case QGis::Meters:
xRes = 0.001;
break;
case QGis::Feet:
xRes = 0.003;
break;
case QGis::Degrees:
// max length of degree of latitude on pole is 111694 m
xRes = 1e-8;
break;
default:
xRes = 0.001; // expecting meters
}
yRes = xRes;
}

if ( myExtent.isEmpty() ) myExtent = extent();
// 1000x1000 to cache data around
theWidth = 1000;
theHeight = 1000;

double xRes = myExtent.width() / theWidth;
double yRes = myExtent.height() / theHeight;
myExtent = QgsRectangle( thePoint.x() - xRes * theWidth / 2,
thePoint.y() - yRes * theHeight / 2,
thePoint.x() + xRes * theWidth / 2,
thePoint.y() + yRes * theHeight / 2 );

if ( !mCachedGdalDataset ||
!mCachedViewExtent.contains( thePoint ) ||
mCachedViewWidth == 0 || mCachedViewHeight == 0 ||
mCachedViewExtent.width() / mCachedViewWidth - xRes > TINY_VALUE ||
mCachedViewExtent.height() / mCachedViewHeight - yRes > TINY_VALUE )
{
int half = 50;
QgsRectangle extent( thePoint.x() - xRes * half, thePoint.y() - yRes * half,
thePoint.x() + xRes * half, thePoint.y() + yRes * half );
getCache( 1, extent, 2*half, 2*half );

getCache( 1, myExtent, theWidth, theHeight );
}
}
else
Expand Down
56 changes: 45 additions & 11 deletions src/providers/wms/qgswmsprovider.cpp
Expand Up @@ -3991,20 +3991,54 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
}

QgsRectangle myExtent = theExtent;
if ( myExtent.isEmpty() )

if ( !myExtent.isEmpty() )
{
// use full extent
myExtent = extent();
// we cannot reliably identify WMS if theExtent is specified but theWidth or theHeight
// are not, because we dont know original resolution
if ( theWidth == 0 || theHeight == 0 )
{
return QgsRasterIdentifyResult( ERROR( tr( "Context not fully specified (extent was defined but width and/or height was not)." ) ) );
}
}

// We don't know highest resolution, so it is difficult to guess any
// but that is why theExtent, theWidth, theHeight params are here
// Keep resolution in both axis equal! Otherwise silly server (like QGIS mapserver)
// fail to calculate coordinate because it is using single resolution average!!!
if ( theWidth == 0 ) theWidth = 1000; // just some number
if ( theHeight == 0 )
else // context (theExtent, theWidth, theHeight) not defined
{
theHeight = myExtent.height() / ( myExtent.width() / theWidth );
// We don't know original source resolution, so we take some small extent around the point.

double xRes = 0.001; // expecting meters

// TODO: add CRS as class member
QgsCoordinateReferenceSystem crs;
if ( crs.createFromOgcWmsCrs( mImageCrs ) )
{
// set resolution approximately to 1mm
switch ( crs.mapUnits() )
{
case QGis::Meters:
xRes = 0.001;
break;
case QGis::Feet:
xRes = 0.003;
break;
case QGis::Degrees:
// max length of degree of latitude on pole is 111694 m
xRes = 1e-8;
break;
default:
xRes = 0.001; // expecting meters
}
}

// Keep resolution in both axis equal! Otherwise silly server (like QGIS mapserver)
// fail to calculate coordinate because it is using single resolution average!!!
double yRes = xRes;

// 1x1 should be sufficient but at least we know that GDAL ECW was very unefficient
// so we use 2x2 (until we find that it is too small for some server)
theWidth = theHeight = 2;

myExtent = QgsRectangle( thePoint.x() - xRes, thePoint.y() - yRes,
thePoint.x() + xRes, thePoint.y() + yRes );
}

// Point in BBOX/WIDTH/HEIGHT coordinates
Expand Down

0 comments on commit de8a5d6

Please sign in to comment.