Skip to content

Commit

Permalink
selection by polygon: use 40 instead of 4 points for selection rectan…
Browse files Browse the repository at this point in the history
…gle for more accurate transformation (fixes #13754)

(cherry picked from commit 0a83f18)
  • Loading branch information
jef-n committed Jun 26, 2016
1 parent 852bd53 commit a7dcaad
Showing 1 changed file with 38 additions and 7 deletions.
45 changes: 38 additions & 7 deletions src/app/qgsmaptoolselectutils.cpp
Expand Up @@ -102,20 +102,51 @@ void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
// the rubber band.
// For example, if you project a world map onto a globe using EPSG 2163
// and then click somewhere off the globe, an exception will be thrown.
QgsGeometry selectGeomTrans( *selectGeometry );
QScopedPointer<QgsGeometry> selectGeomTrans( new QgsGeometry( *selectGeometry ) );

if ( canvas->mapSettings().hasCrsTransformEnabled() )
{
try
{
QgsCoordinateTransform ct( canvas->mapSettings().destinationCrs(), vlayer->crs() );
selectGeomTrans.transform( ct );

if ( !ct.isShortCircuited() && selectGeomTrans->type() == QGis::Polygon )
{
// convert add more points to the edges of the rectangle
// improve transformation result
QgsPolygon poly( selectGeomTrans->asPolygon() );
if ( poly.size() == 1 && poly.at( 0 ).size() == 5 )
{
const QgsPolyline &ringIn = poly.at( 0 );

QgsPolygon newpoly( 1 );
newpoly[0].resize( 41 );
QgsPolyline &ringOut = newpoly[0];

ringOut[ 0 ] = ringIn.at( 0 );

int i = 1;
for ( int j = 1; j < 5; j++ )
{
QgsVector v(( ringIn.at( j ) - ringIn.at( j - 1 ) ) / 10.0 );
for ( int k = 0; k < 9; k++ )
{
ringOut[ i ] = ringOut[ i - 1 ] + v;
i++;
}
ringOut[ i++ ] = ringIn.at( j );
}
selectGeomTrans.reset( QgsGeometry::fromPolygon( newpoly ) );
}
}

selectGeomTrans->transform( ct );
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse );
// catch exception for 'invalid' point and leave existing selection unchanged
QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
QgsDebugMsg( "Caught CRS exception " );
QgisApp::instance()->messageBar()->pushMessage(
QObject::tr( "CRS Exception" ),
QObject::tr( "Selection extends beyond layer's coordinate system" ),
Expand All @@ -139,7 +170,7 @@ void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
r->startRender( context, vlayer->fields() );

QgsFeatureRequest request;
request.setFilterRect( selectGeomTrans.boundingBox() );
request.setFilterRect( selectGeomTrans->boundingBox() );
request.setFlags( QgsFeatureRequest::ExactIntersect );
if ( r )
request.setSubsetOfAttributes( r->usedAttributes(), vlayer->fields() );
Expand All @@ -163,18 +194,18 @@ void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
const QgsGeometry* g = f.constGeometry();
if ( doContains )
{
if ( !selectGeomTrans.contains( g ) )
if ( !selectGeomTrans->contains( g ) )
continue;
}
else
{
if ( !selectGeomTrans.intersects( g ) )
if ( !selectGeomTrans->intersects( g ) )
continue;
}
if ( singleSelect )
{
foundSingleFeature = true;
double distance = g->distance( selectGeomTrans );
double distance = g->distance( *selectGeomTrans );
if ( distance <= closestFeatureDist )
{
closestFeatureDist = distance;
Expand Down

0 comments on commit a7dcaad

Please sign in to comment.