8

I have about 400 features in a point dataset. I would like to (quickly) visually check their locations one by one on the map. For now, I open the attribute table alongside the map. I select the first row and use the "Zoom to selected feature" button. Then I manually select the 2nd row, and click the button again, and so on, and so on.

I was however wondering if there is a way/plugin/shortcut key/... to do that quicker in QGIS?

  • You want to zoom to a selection as soon as it's made? – Dror Bogin Oct 10 at 7:07
  • Yes, it could be the case but I will do the selection in the table in this case.. – Marc Oct 10 at 7:31
  • 1
    In fact I had in mind a kind of button "Next" and "Previous" that could just select the next/previous feature in the table and automatically zoom on it – Marc Oct 10 at 8:22
12

You can use the following script. It creates a toolbar containing Zoom Previous, Zoom Next actions and ID text box. When you click the action it zooms to next/previous feature (in active layer) with next/previous ID (means feauture.id()) in text box.

enter image description here

Run the script in QGIS Python Editor.

layer = iface.activeLayer()
canvas = iface.mapCanvas()
ID = 0

def zoom_next():
    global ID
    ID += 1
    zoom(ID)
    
def zoom_prev():
    global ID
    ID -= 1
    zoom(ID)
    
def zoom(ID):
    canvas.zoomToFeatureIds(layer, [ID])
    text_id.setText(str(ID))
    
def reset_id():
    global ID
    global layer
    ID = 0
    text_id.setText('0')
    layer = iface.activeLayer()
    canvas.zoomToFeatureIds(layer, [ID])

## ACTIONS
zoom_next_action = QAction("Zoom Next")
zoom_next_action.triggered.connect(zoom_next)

zoom_prev_action = QAction("Zoom Previous")
zoom_prev_action.triggered.connect(zoom_prev)

label = QLabel("ID:")
text_id = QLineEdit()
text_id.setMaximumSize(QSize(40, 100))
text_id.setText('0')

## TOOLBAR
zoom_toolbar = iface.addToolBar("Zoom Features")
zoom_toolbar.addAction(zoom_prev_action)
zoom_toolbar.addAction(zoom_next_action)
zoom_toolbar.addWidget(label)
zoom_toolbar.addWidget(text_id)

iface.layerTreeView().currentLayerChanged.connect(reset_id)
| improve this answer | |
  • Wonderful! Thanks a lot! It works nice and clean! – Marc Oct 10 at 10:29
5

There is no "Next" and "Previous" buttons,
You could however dock your table for easier viewing of both table and canvas,
and then use the "zoom to selection" keyboard shortcut (Ctrl+J).

enter image description here

| improve this answer | |
  • Thanks for the short cut. It removes one click! The selection process is still a bit bothersome however... – Marc Oct 10 at 9:00
5

Several ways of doing this, which is good :)

Here is another one using the Space bar (from another answer):

enter image description here

Steps

  1. Download the script iterate_features.py and save it in the same folder as your QGIS project.

  2. Open the QGIS Python console and enter the following line:

    import iterate_features

  3. Close the QGIS Python console.

  4. Select a layer in the Layers panel and press the Space bar to start iterating features. Press Escape to reset the iteration.


Notes

  • You can change the active layer anytime and start iterating its features.
  • Iterating points is a special case, so you set the scale that works for you and after pressing the Space bar, the script pans to the next feature. For other geometry types, the script zooms to them.
  • Press Shift+F6 (and embed the attribute table) to visualize also the selected feature attributes.
  • This works also for geometryless tables. Specially if they have relations with other layers. See it in action:

enter image description here

| improve this answer | |
3

@Marc, you can also try this script, super short, for a quick review, sequential, without clicking, you just sit and eat pop corn :D .

Procedure:

  1. select the vectorial layer of interest

  2. open the console, then open the editor

  3. you remove the visibility of any web layer, base maps, either quick map services or xyz tiles (these layers will delay the updating of the canvas, but if you are patient and have a good connection you can leave them)

  4. you paste the code, you can change the time, the delay variable, but I recommend to leave it like this

  5. place the console window where it does not obstruct the canvas and click run

    import time
    
    tdelay=0.5 #delay of update
    capa= iface.activeLayer()
    le=list(capa.getFeatures())
    canvas=iface.mapCanvas()
    for i in le:
        canvas.zoomToFeatureIds(capa,[i.id()])
        canvas.flashFeatureIds(capa,[i.id()])
        canvas.waitWhileRendering()
        time.sleep(tdelay)
    

It's a bit forced because I stop the execution with time.sleep(), but in my Windows10 computer and QGIS3.4 I work fine.

With higher versions of QGIS you can access the time driver and do something much better, without risk of crash.

Another option is threaded, but requires much more code

| improve this answer | |
  • Haha, thanks! It can be useful for sure! – Marc Oct 11 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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