2

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()
10
  • use iface.actionZoomToSelected().trigger()
    – Fran Raga
    Commented Oct 3, 2018 at 14:29
  • @Francisco Raga. Thanks. But it does not help. I got the same result
    – Arie
    Commented Oct 3, 2018 at 14:40
  • @Francisco Raga. Sorry, my mistake - it's WORKS . I put your code in the last line of file and it did the work.
    – Arie
    Commented Oct 3, 2018 at 14:47
  • 1
    I'm glad,I put my comment as an answer?
    – Fran Raga
    Commented Oct 3, 2018 at 14:52
  • @Francisco Raga . Hi. After additional check I discovered that iface.actionZoomToSelected().trigger() works only if I already have some layer in TOC. In my case - the layer is the first to be displayed and zoomed to selected feature . So my problem is not solved.
    – Arie
    Commented Oct 4, 2018 at 7:05

3 Answers 3

4

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)
3
  • Thanks. I also succeeded when I execute each line separately in Python Console. But it did not work when I ran it as a script in Python Console Editor or in my plugin.
    – Arie
    Commented Oct 4, 2018 at 8:45
  • your are right!Update again
    – Fran Raga
    Commented Oct 4, 2018 at 10:39
  • Thanks,, the program does the zoom successfully, but only after the entire layer is displayed in full extention. And this I want to avoid because it is unnecessary and that continues 2 minutes
    – Arie
    Commented Oct 4, 2018 at 12:03
0

These statements should work too:

canvas = qgis.utils.iface.mapCanvas()
canvas.zoomToSelected(layer1)
layer1.triggerRepaint()
3
  • Hi, My problem is to make zoom to selected features in layer (that is first and the only layer in QGIS display) without to display in the beginning the layer in full extent. Francisco Raga already explained me how to make zoom, but in his way I still must display first the layer in full extent. Thanks
    – Arie
    Commented Oct 4, 2018 at 13:03
  • Why do you first need to zoom to layer - all features?
    – artwork21
    Commented Oct 5, 2018 at 13:07
  • Hi, Sorry I did not explain myself well. I'll try to fix it. I want open the first layer in QGIS and immediately zoom to selected feature according to parameters defined before it in plugin ( polygon number)
    – Arie
    Commented Oct 5, 2018 at 13:35
0

I found the solution - after drawing the layer, I use : QApplication.processEvents()

Here is explanation about it : https://doc.qt.io/qt-5/qcoreapplication.html#processEvents So - the code must be like it:

from qgis.core import *
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)

QApplication.processEvents()

expressionCur = 'block_num = 6018'
it = layer1.getFeatures(QgsFeatureRequest().setFilterExpression(expressionCur))
layer1.setSelectedFeatures ( [ f.id() for f in it ])
boxWin = layer1.boundingBoxOfSelected() 
iface.mapCanvas().setExtent(boxWin)
iface.mapCanvas().refresh()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.