Skip to content

Commit

Permalink
[FEATURE]: pan to current feature in attribute table
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Jul 14, 2016
1 parent b61641d commit 48da1de
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 11 deletions.
18 changes: 18 additions & 0 deletions src/gui/attributetable/qgsdualview.cpp
Expand Up @@ -430,6 +430,7 @@ void QgsDualView::viewWillShowContextMenu( QMenu* menu, const QModelIndex& atInd
if ( canvas && vl && vl->geometryType() != QGis::NoGeometry )
{
menu->addAction( tr( "Zoom to feature" ), this, SLOT( zoomToCurrentFeature() ) );
menu->addAction( tr( "Pan to feature" ), this, SLOT( panToCurrentFeature() ) );
}

//add user-defined actions to context menu
Expand Down Expand Up @@ -651,6 +652,23 @@ void QgsDualView::zoomToCurrentFeature()
}
}

void QgsDualView::panToCurrentFeature()
{
QModelIndex currentIndex = mTableView->currentIndex();
if ( !currentIndex.isValid() )
{
return;
}

QgsFeatureIds ids;
ids.insert( mFilterModel->rowToId( currentIndex ) );
QgsMapCanvas* canvas = mFilterModel->mapCanvas();
if ( canvas )
{
canvas->panToFeatureIds( mLayerCache->layer(), ids );
}
}

void QgsDualView::previewExpressionChanged( const QString& expression )
{
mLayerCache->layer()->setDisplayExpression( expression );
Expand Down
2 changes: 2 additions & 0 deletions src/gui/attributetable/qgsdualview.h
Expand Up @@ -317,6 +317,8 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas

/** Zooms to the active feature*/
void zoomToCurrentFeature();
/** Pans to the active feature*/
void panToCurrentFeature();

private:
void initLayerCache( QgsVectorLayer *layer, bool cacheGeometry );
Expand Down
57 changes: 46 additions & 11 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -1162,39 +1162,74 @@ void QgsMapCanvas::zoomToFeatureIds( QgsVectorLayer* layer, const QgsFeatureIds&
return;
}

QgsRectangle bbox;
QString errorMsg;
if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
{
zoomToFeatureExtent( bbox );
}
else
{
emit messageEmitted( tr( "Zoom to feature id failed" ), errorMsg, QgsMessageBar::WARNING );
}

}

void QgsMapCanvas::panToFeatureIds( QgsVectorLayer* layer, const QgsFeatureIds& ids )
{
if ( !layer )
{
return;
}

QgsRectangle bbox;
QString errorMsg;
if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
{
setCenter( bbox.center() );
refresh();
}
else
{
emit messageEmitted( tr( "Pan to feature id failed" ), errorMsg, QgsMessageBar::WARNING );
}
}

bool QgsMapCanvas::boundingBoxOfFeatureIds( const QgsFeatureIds& ids, QgsVectorLayer* layer, QgsRectangle& bbox, QString& errorMsg ) const
{
QgsFeatureIterator it = layer->getFeatures( QgsFeatureRequest().setFilterFids( ids ).setSubsetOfAttributes( QgsAttributeList() ) );
QgsRectangle rect;
rect.setMinimal();
bbox.setMinimal();
QgsFeature fet;
int featureCount = 0;
errorMsg.clear();

while ( it.nextFeature( fet ) )
{
const QgsGeometry* geom = fet.constGeometry();
QString errorMessage;
if ( !geom || geom->isEmpty() )
{
errorMessage = tr( "Feature does not have a geometry" );
errorMsg = tr( "Feature does not have a geometry" );
}
else if ( geom->geometry()->isEmpty() )
{
errorMessage = tr( "Feature geometry is empty" );
errorMsg = tr( "Feature geometry is empty" );
}
if ( !errorMessage.isEmpty() )
if ( !errorMsg.isEmpty() )
{
emit messageEmitted( tr( "Zoom to feature id failed" ), errorMessage, QgsMessageBar::WARNING );
return;
return false;
}
QgsRectangle r = mapSettings().layerExtentToOutputExtent( layer, geom->boundingBox() );
rect.combineExtentWith( r );
bbox.combineExtentWith( r );
featureCount++;
}

if ( featureCount != ids.count() )
{
return;
errorMsg = tr( "Feature not found" );
return false;
}

zoomToFeatureExtent( rect );
return true;
}

void QgsMapCanvas::panToSelected( QgsVectorLayer* layer )
Expand Down
12 changes: 12 additions & 0 deletions src/gui/qgsmapcanvas.h
Expand Up @@ -253,6 +253,11 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
@param ids the feature ids*/
void zoomToFeatureIds( QgsVectorLayer* layer, const QgsFeatureIds& ids );

/** Centers canvas extent to feature ids
@param layer the vector layer
@param ids the feature ids*/
void panToFeatureIds( QgsVectorLayer* layer, const QgsFeatureIds& ids );

/** Pan to the selected features of current (vector) layer keeping same extent. */
void panToSelected( QgsVectorLayer* layer = nullptr );

Expand Down Expand Up @@ -813,6 +818,13 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
*/
void endZoomRect( QPoint pos );

/** Returns bounding box of feature list (in canvas coordinates)
@param ids feature id list
@param bbox out: bounding box
@param errorMsg error message in case of error
@return true in case of success*/
bool boundingBoxOfFeatureIds( const QgsFeatureIds& ids, QgsVectorLayer* layer, QgsRectangle& bbox, QString& errorMsg ) const;

friend class TestQgsMapCanvas;

}; // class QgsMapCanvas
Expand Down

0 comments on commit 48da1de

Please sign in to comment.