move the optimal extent calculation for a point layer to its own method

This commit is contained in:
Denis Rouzaud 2020-09-21 07:29:44 +02:00
parent dd19040226
commit b47346ba20
2 changed files with 43 additions and 27 deletions

View File

@ -1240,6 +1240,40 @@ void QgsMapCanvas::clearExtentHistory()
emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
}// clearExtentHistory
QgsRectangle QgsMapCanvas::optimalExtentForPointLayer( QgsVectorLayer *layer, const QgsPointXY &center, int scaleFactor )
{
QgsRectangle rect( center, center );
if ( layer->geometryType() == QgsWkbTypes::PointGeometry )
{
QgsPointXY centerLayerCoordinates = mSettings.mapToLayerCoordinates( layer, center );
QgsRectangle extentRect = mSettings.mapToLayerCoordinates( layer, extent() ).scaled( 1.0 / scaleFactor, &centerLayerCoordinates );
QgsFeatureRequest req = QgsFeatureRequest().setFilterRect( extentRect ).setLimit( 1000 ).setNoAttributes();
QgsFeatureIterator fit = layer->getFeatures( req );
QgsFeature f;
QgsPointXY closestPoint;
double closestSquaredDistance = pow( extentRect.width(), 2.0 ) + pow( extentRect.height(), 2.0 );
bool pointFound = false;
while ( fit.nextFeature( f ) )
{
QgsPointXY point = f.geometry().asPoint();
double sqrDist = point.sqrDist( centerLayerCoordinates );
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 );
}
}
return rect;
}
void QgsMapCanvas::zoomToSelected( QgsVectorLayer *layer )
{
if ( !layer )
@ -1264,34 +1298,8 @@ void QgsMapCanvas::zoomToSelected( QgsVectorLayer *layer )
// 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 centerMapCoordinates = rect.center();
QgsPointXY centerLayerCoordinates = mSettings.mapToLayerCoordinates( layer, centerMapCoordinates );
QgsRectangle extentRect = mSettings.mapToLayerCoordinates( layer, extent() ).scaled( 1.0 / scaleFactor, &centerLayerCoordinates );
QgsFeatureRequest req = QgsFeatureRequest().setFilterRect( extentRect ).setLimit( 1000 ).setNoAttributes();
QgsFeatureIterator fit = layer->getFeatures( req );
QgsFeature f;
QgsPointXY closestPoint;
double closestSquaredDistance = pow( extentRect.width(), 2.0 ) + pow( extentRect.height(), 2.0 );
bool pointFound = false;
while ( fit.nextFeature( f ) )
{
QgsPointXY point = f.geometry().asPoint();
double sqrDist = point.sqrDist( centerLayerCoordinates );
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, &centerMapCoordinates );
}
rect = optimalExtentForPointLayer( layer, rect.center() );
}
zoomToFeatureExtent( rect );
}

View File

@ -1265,6 +1265,14 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
*/
bool boundingBoxOfFeatureIds( const QgsFeatureIds &ids, QgsVectorLayer *layer, QgsRectangle &bbox, QString &errorMsg ) const;
/**
* Rerturns the optimal extent for a point \a layer and a given \a center point in canvas CRS.
* This will return an extent combined of the center and the closest point in the layer.
* The extent can be scaled with a \a scale factor.
* The returned extent might be an empty rect if it cannot be determnined.
*/
QgsRectangle optimalExtentForPointLayer( QgsVectorLayer *layer, const QgsPointXY &center, int scaleFactor = 5 );
void setLayersPrivate( const QList<QgsMapLayer *> &layers );
void startPreviewJobs();