Merge pull request #8330 from 3nids/fix9160

Properly zoom to feature for single point selected
This commit is contained in:
Denis Rouzaud 2018-10-25 13:34:49 -08:00 committed by GitHub
commit 8eb193020a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 1 deletions

View File

@ -183,6 +183,13 @@ Scale the rectangle around its center point.
void scale( double scaleFactor, double centerX, double centerY );
%Docstring
Scale the rectangle around its center point.
%End
QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = 0 ) const;
%Docstring
Scale the rectangle around its ``center`` point.
.. versionadded:: 3.4
%End
void grow( double delta );

View File

@ -58,6 +58,13 @@ QgsRectangle QgsRectangle::fromCenterAndSize( QgsPointXY center, double width, d
return QgsRectangle( xMin, yMin, xMax, yMax );
}
QgsRectangle QgsRectangle::scaled( double scaleFactor, const QgsPointXY *center ) const
{
QgsRectangle scaledRect = QgsRectangle( *this );
scaledRect.scale( scaleFactor, center );
return scaledRect;
}
QgsRectangle QgsRectangle::operator-( const QgsVector v ) const
{
double xmin = mXmin - v.x();

View File

@ -261,6 +261,12 @@ class CORE_EXPORT QgsRectangle
mYmax = centerY + newHeight / 2.0;
}
/**
* Scale the rectangle around its \a center point.
* \since QGIS 3.4
*/
QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
/**
* Grows the rectangle in place by the specified amount.
* \see buffered()

View File

@ -996,8 +996,40 @@ void QgsMapCanvas::zoomToSelected( QgsVectorLayer *layer )
}
rect = mapSettings().layerExtentToOutputExtent( layer, rect );
// zoom in if point cannot be distinguished from others
// also check that rect is empty, as it might not in case of multi points
if ( layer->geometryType() == QgsWkbTypes::PointGeometry && rect.isEmpty() )
{
int scaleFactor = 5;
QgsPointXY center = mSettings.mapToLayerCoordinates( layer, rect.center() );
QgsRectangle extentRect = mSettings.mapToLayerCoordinates( layer, extent() ).scaled( 1.0 / scaleFactor, &center );
QgsFeatureRequest req = QgsFeatureRequest().setFilterRect( extentRect ).setLimit( 1000 ).setNoAttributes();
QgsFeatureIterator fit = layer->getFeatures( req );
QgsFeature f;
QgsPointXY closestPoint;
double closestSquaredDistance = extentRect.width() + extentRect.height();
bool pointFound = false;
while ( fit.nextFeature( f ) )
{
QgsPointXY point = f.geometry().asPoint();
double sqrDist = point.sqrDist( center );
if ( sqrDist > closestSquaredDistance || sqrDist < 4 * std::numeric_limits<double>::epsilon() )
continue;
pointFound = true;
closestPoint = point;
closestSquaredDistance = sqrDist;
}
if ( pointFound )
{
// combine selected point with closest point and scale this rect
rect.combineExtentWith( mSettings.layerToMapCoordinates( layer, closestPoint ) );
rect.scale( scaleFactor, &center );
}
}
zoomToFeatureExtent( rect );
} // zoomToSelected
}
void QgsMapCanvas::zoomToFeatureExtent( QgsRectangle &rect )
{

View File

@ -40,6 +40,7 @@ class TestQgsRectangle: public QObject
void isFinite();
void combine();
void dataStream();
void scale();
};
void TestQgsRectangle::isEmpty()
@ -348,5 +349,22 @@ void TestQgsRectangle::dataStream()
QCOMPARE( result, original );
}
void TestQgsRectangle::scale()
{
QgsRectangle rect( 10, 20, 30, 60 );
rect.scale( 2 );
QCOMPARE( rect, QgsRectangle( 0, 0, 40, 80 ) );
rect.scale( .5 );
QCOMPARE( rect, QgsRectangle( 10, 20, 30, 60 ) );
QgsPointXY center( 10, 20 );
// with center
rect.scale( 2, &center );
QCOMPARE( rect, QgsRectangle( -10, -20, 30, 60 ) );
// scaled
QCOMPARE( rect, QgsRectangle( 10, 20, 30, 60 ).scaled( 2, &center ) );
}
QGSTEST_MAIN( TestQgsRectangle )
#include "testqgsrectangle.moc"