Skip to content

Commit f4451c0

Browse files
committed
WMS identify fixes
1 parent 20b4043 commit f4451c0

File tree

6 files changed

+65
-11
lines changed

6 files changed

+65
-11
lines changed

src/app/qgsmaptoolidentify.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -379,17 +379,29 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
379379
viewExtent = toLayerCoordinates( layer, viewExtent );
380380
}
381381

382-
// cut by layer extent to use possible cache, the same done when drawing
383-
viewExtent = dprovider->extent().intersect( &viewExtent );
382+
// It would be nice to use the same extent and size which was used for drawing,
383+
// so that WCS can use cache from last draw, unfortunately QgsRasterLayer::draw()
384+
// is doing some tricks with extent and size to allign raster to output which
385+
// would be difficult to replicate here.
386+
// Note: cutting the extent may result in slightly different x and y resolutions
387+
// and thus shifted point calculated back in QGIS WMS (using average resolution)
388+
//viewExtent = dprovider->extent().intersect( &viewExtent );
384389

385390
double mapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
386391
// Width and height are calculated from not projected extent and we hope that
387392
// are similar to source width and height used to reproject layer for drawing.
388-
int width = mCanvas->extent().width() / mapUnitsPerPixel;
389-
int height = mCanvas->extent().height() / mapUnitsPerPixel;
393+
// TODO: may be very dangerous, because it may result in different resolutions
394+
// in source CRS, and WMS server (QGIS server) calcs wrong coor using average resolution.
395+
int width = qRound( viewExtent.width() / mapUnitsPerPixel );
396+
int height = qRound( viewExtent.height() / mapUnitsPerPixel );
397+
398+
QgsDebugMsg( QString( "viewExtent.width = %1 viewExtent.height = %2" ).arg( viewExtent.width() ).arg( viewExtent.height() ) );
399+
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( width ).arg( height ) );
400+
QgsDebugMsg( QString( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );
390401

391402
QMap< QString, QString > attributes, derivedAttributes;
392403

404+
QgsDebugMsg( QString( "idPoint: %1 %2" ).arg( idPoint.x() ).arg( idPoint.y() ) );
393405
attributes = dprovider->identify( idPoint, viewExtent, width, height );
394406

395407
QString type;

src/core/qgsmaprenderer.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ void QgsMapRenderer::adjustExtentToSize()
206206
mExtent.setYMinimum( dymin );
207207
mExtent.setYMaximum( dymax );
208208

209+
QgsDebugMsg( QString( "Adjusted map units per pixel (x,y) : %1, %2" ).arg( mExtent.width() / myWidth, 0, 'f', 8 ).arg( mExtent.height() / myHeight, 0, 'f', 8 ) );
210+
211+
QgsDebugMsg( QString( "Recalced pixmap dimensions (x,y) : %1, %2" ).arg( mExtent.width() / mMapUnitsPerPixel, 0, 'f', 8 ).arg( mExtent.height() / mMapUnitsPerPixel, 0, 'f', 8 ) );
212+
209213
// update the scale
210214
updateScale();
211215

src/mapserver/qgspostrequesthandler.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* (at your option) any later version. *
1515
* *
1616
***************************************************************************/
17-
17+
#include <stdlib.h>
1818
#include "qgspostrequesthandler.h"
1919
#include "qgslogger.h"
2020
#include <QDomDocument>
@@ -54,7 +54,7 @@ QMap<QString, QString> QgsPostRequestHandler::parseInput()
5454
QgsDebugMsg( "error, no query string found but a QDomDocument" );
5555
return parameters; //no query string? something must be wrong...
5656
}
57-
57+
5858
requestStringToParameterMap( queryString, parameters );
5959

6060
QDomElement docElem = doc.documentElement();

src/mapserver/qgswmsserver.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,10 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
648648
return 2;
649649
}
650650

651+
QgsDebugMsg( "mMapRenderer->extent(): " + mMapRenderer->extent().toString() );
652+
QgsDebugMsg( QString( "mMapRenderer width = %1 height = %2" ).arg( mMapRenderer->outputSize().width() ).arg( mMapRenderer->outputSize().height() ) );
653+
QgsDebugMsg( QString( "mMapRenderer->mapUnitsPerPixel() = %1" ).arg( mMapRenderer->mapUnitsPerPixel() ) );
654+
651655
//find out the current scale denominater and set it to the SLD parser
652656
QgsScaleCalculator scaleCalc(( outputImage->logicalDpiX() + outputImage->logicalDpiY() ) / 2 , mMapRenderer->destinationCrs().mapUnits() );
653657
QgsRectangle mapExtent = mMapRenderer->extent();
@@ -1127,9 +1131,28 @@ int QgsWMSServer::infoPointToLayerCoordinates( int i, int j, QgsPoint* layerCoor
11271131
}
11281132

11291133
//first transform i,j to map output coordinates
1130-
QgsPoint mapPoint = mapRender->coordinateTransform()->toMapCoordinates( i, j );
1134+
// toMapCoordinates() is currently (Oct 18 2012) using average resolution
1135+
// to calc point but GetFeatureInfo request may be sent with different
1136+
// resolutions in each axis
1137+
//QgsPoint mapPoint = mapRender->coordinateTransform()->toMapCoordinates( i, j );
1138+
double xRes = mapRender->extent().width() / mapRender->width();
1139+
double yRes = mapRender->extent().height() / mapRender->height();
1140+
QgsPoint mapPoint( mapRender->extent().xMinimum() + i * xRes,
1141+
mapRender->extent().yMaximum() - j * yRes );
1142+
1143+
QgsDebugMsg( QString( "mapPoint (corner): %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );
1144+
// use pixel center instead of corner
1145+
// Unfortunately going through pixel (integer) we cannot reconstruct precisely
1146+
// the coordinate clicked on client and thus result may differ from
1147+
// the same raster loaded and queried localy on client
1148+
mapPoint.setX( mapPoint.x() + xRes / 2 );
1149+
mapPoint.setY( mapPoint.y() - yRes / 2 );
1150+
1151+
QgsDebugMsg( QString( "mapPoint (pixel center): %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );
1152+
11311153
//and then to layer coordinates
11321154
*layerCoords = mapRender->mapToLayerCoordinates( layer, mapPoint );
1155+
QgsDebugMsg( QString( "mapPoint: %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );
11331156
return 0;
11341157
}
11351158

@@ -1303,9 +1326,11 @@ int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer,
13031326
return 1;
13041327
}
13051328

1329+
QgsDebugMsg( QString( "infoPoint: %1 %2" ).arg( infoPoint->x() ).arg( infoPoint->y() ) );
1330+
13061331
QMap<QString, QString> attributes;
1307-
// TODO: use context extent, width height (comes with request) to use WCS cache
1308-
attributes = layer->dataProvider()->identify( *infoPoint );
1332+
// use context extent, width height (comes with request) to use WCS cache
1333+
attributes = layer->dataProvider()->identify( *infoPoint, mMapRenderer->extent(), mMapRenderer->outputSize().width(), mMapRenderer->outputSize().height() );
13091334

13101335
for ( QMap<QString, QString>::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); ++it )
13111336
{

src/providers/gdal/qgsgdalprovider.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ QMap<int, QVariant> QgsGdalProvider::identify( const QgsPoint & thePoint, Identi
834834
Q_UNUSED( theExtent );
835835
Q_UNUSED( theWidth );
836836
Q_UNUSED( theHeight );
837-
QgsDebugMsg( "Entered" );
837+
QgsDebugMsg( QString( "thePoint = %1 %2" ).arg( thePoint.x() ).arg( thePoint.y() ) );
838838

839839
QMap<int, QVariant> results;
840840

src/providers/wms/qgswmsprovider.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -3794,18 +3794,31 @@ QMap<int, QVariant> QgsWmsProvider::identify( const QgsPoint & thePoint, Identif
37943794

37953795
// We don't know highest resolution, so it is difficult to guess any
37963796
// but that is why theExtent, theWidth, theHeight params are here
3797+
// Keep resolution in both axis equal! Otherwise silly server (like QGIS mapserver)
3798+
// fail to calculate coordinate because it is using single resolution average!!!
37973799
if ( theWidth == 0 ) theWidth = 1000; // just some number
3798-
if ( theHeight == 0 ) theHeight = 1000;
3800+
if ( theHeight == 0 )
3801+
{
3802+
theHeight = myExtent.height() / ( myExtent.width() / theWidth );
3803+
}
37993804

38003805
// Point in BBOX/WIDTH/HEIGHT coordinates
38013806
// No need to fiddle with extent origin not covered by layer extent, I believe
38023807
double xRes = myExtent.width() / theWidth;
38033808
double yRes = myExtent.height() / theHeight;
38043809

3810+
QgsDebugMsg( "myExtent = " + myExtent.toString() );
3811+
QgsDebugMsg( QString( "theWidth = %1 theHeight = %2" ).arg( theWidth ).arg( theHeight ) );
3812+
QgsDebugMsg( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ) );
3813+
38053814
QgsPoint point;
38063815
point.setX( floor(( thePoint.x() - myExtent.xMinimum() ) / xRes ) );
38073816
point.setY( floor(( myExtent.yMaximum() - thePoint.y() ) / yRes ) );
38083817

3818+
QgsDebugMsg( QString( "point = %1 %2" ).arg( point.x() ).arg( point.y() ) );
3819+
3820+
QgsDebugMsg( QString( "recalculated orig point (corner) = %1 %2" ).arg( myExtent.xMinimum() + point.x()*xRes ).arg( myExtent.yMaximum() - point.y()*yRes ) );
3821+
38093822
// Collect which layers to query on
38103823
//according to the WMS spec for 1.3, the order of x - and y - coordinates is inverted for geographical CRS
38113824
bool changeXY = false;

0 commit comments

Comments
 (0)