Skip to content

Commit

Permalink
Merge pull request #8330 from 3nids/fix9160
Browse files Browse the repository at this point in the history
Properly zoom to feature for single point selected
  • Loading branch information
3nids committed Oct 25, 2018
2 parents 1118f4a + daca55a commit 8eb1930
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 1 deletion.
7 changes: 7 additions & 0 deletions python/core/auto_generated/geometry/qgsrectangle.sip.in
Expand Up @@ -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 );
Expand Down
7 changes: 7 additions & 0 deletions src/core/geometry/qgsrectangle.cpp
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions src/core/geometry/qgsrectangle.h
Expand Up @@ -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()
Expand Down
34 changes: 33 additions & 1 deletion src/gui/qgsmapcanvas.cpp
Expand Up @@ -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 )
{
Expand Down
18 changes: 18 additions & 0 deletions tests/src/core/testqgsrectangle.cpp
Expand Up @@ -40,6 +40,7 @@ class TestQgsRectangle: public QObject
void isFinite();
void combine();
void dataStream();
void scale();
};

void TestQgsRectangle::isEmpty()
Expand Down Expand Up @@ -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"

0 comments on commit 8eb1930

Please sign in to comment.