PyQGIS – How to Zoom to Selected Feature in QGIS

pyqgis

While trying to read a layer from PostgreSQL, in order to select one polygon and zoom to this feature, I see the entire layer but not the selected feature.
I am using an unconventional way solve the problem – I am running the three lines I marked as comments in my example.

Can anyone offer me a better way?

I am working with Windows 10, QGIS 2.18.22, PostgreSQL 10.

This is my code that I am running in Python Consol Editor:

from qgis.core import *
from console import console

uri = QgsDataSourceURI()
uri.setConnection ("127.0.0.1", "5432", "DB_Layers", "postgres", "myPassword")

uri.setDataSource("public",  'blocks_lay', "wkb_geometry", "")

layer1 = QgsVectorLayer ( uri.uri(False), "blocks", "postgres")
QgsMapLayerRegistry.instance().addMapLayer(layer1, True)

crs = QgsCoordinateReferenceSystem(2039)
iface.mapCanvas().mapSettings().setDestinationCrs(crs)

layer1.setCrs(crs)
expressionCur = 'block_num = 6018'

it = layer1.getFeatures(QgsFeatureRequest().setFilterExpression(expressionCur))
layer1.setSelectedFeatures ( [ f.id() for f in it ])

boxWin = layer1.boundingBoxOfSelected() 
# console.show_console()
# print 'aaaa'
# console.show_console()
iface.mapCanvas().setExtent(boxWin)

iface.mapCanvas().refresh()

Best Answer

Use iface.actionZoomToSelected().trigger() in your code for zoom to selected feature in QGIS

change the database data using your information

Code

from qgis.core import *

uri = QgsDataSourceURI()
uri.setConnection ("localhost", "5432", "OSM", "postgres", "postgres")

uri.setDataSource("public",  'grassland', "geom", "")

layer1 = QgsVectorLayer ( uri.uri(), "grassland", "postgres")
QgsMapLayerRegistry.instance().addMapLayer(layer1, True)

crs = QgsCoordinateReferenceSystem(4326)
iface.mapCanvas().mapSettings().setDestinationCrs(crs)

expressionCur = 'cat = 10'

it = layer1.getFeatures(QgsFeatureRequest().setFilterExpression(expressionCur))
layer1.setSelectedFeatures ( [ f.id() for f in it ])

iface.actionZoomToSelected().trigger()

enter image description here

UPDATE

You are right, to use it in the console you must use some signal, like for example

from qgis.core import *

def Zoom_filter():
    iface.mapCanvas().mapCanvasRefreshed.disconnect(Zoom_filter)
    expressionCur = 'cat = 10'
    for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
        if lyr.name() == "grassland":
            it = lyr.getFeatures(QgsFeatureRequest().setFilterExpression(expressionCur))
            lyr.setSelectedFeatures ( [ f.id() for f in it ])
            iface.actionZoomToSelected().trigger()
            break

uri = QgsDataSourceURI()
uri.setConnection ("localhost", "5432", "OSM", "postgres", "postgres")

uri.setDataSource("public",  'grassland', "geom", "")

layer1 = QgsVectorLayer ( uri.uri(), "grassland", "postgres")

crs = QgsCoordinateReferenceSystem(4326)
iface.mapCanvas().mapSettings().setDestinationCrs(crs)
QgsMapLayerRegistry.instance().addMapLayer(layer1, True)
iface.mapCanvas().mapCanvasRefreshed.connect(Zoom_filter)