5

I have been trying to get one layer's clicked-on feature to have an effect on another layer's viewed features with some success, but I am unable to get the map canvas to be filled by the the selected layer's features when using python code called from within the layer actions call.

For reference, I have two layers - one not referred to in the code is a layer of zones. The other (referred to below) is the same zones intersected with same to identify all zones with their neighbouring zones. My intention is that on clicking on a zone in the former layer, I get the neighbouring zones highlighted, and zoomed to as a seamless operation.

When I run this code from the python console, it behaves exactly as I was hoping for:

registry = QgsMapLayerRegistry.instance();
name= 'intersecting_zones';
layer = registry.mapLayersByName( name )[0];
layer.removeSelection();
expr = QgsExpression("\"msoa_code_\"='E02002869'");
it = layer.getFeatures(QgsFeatureRequest(expr));
ids = [i.id() for i in it];
layer.setSelectedFeatures(ids);
box = layer.boundingBoxOfSelected();
iface.mapCanvas().setExtent(box);
iface.mapCanvas().refresh();

This will not work in the exact form within the python call of the original layer's action properties and I have understood that instead of using iface, I needed to switch to using a reference to QgsMapCanvas, hence I use code of the following form - first easy to read, second same code in the single line for use within Layer Actions.

from qgis.coreimport QgsApplication;
from qgis.gui import QgsMapCanvas;
registry = QgsMapLayerRegistry.instance();
canvas = QgsMapCanvas();
name= 'intersecting_zones';
layer = registry.mapLayersByName( name )[0];
layer.removeSelection();
expr = QgsExpression("\"msoa_code_\"='[% "msoa_code_" %]'");
it = layer.getFeatures(QgsFeatureRequest(expr));
ids = [i.id() for i in it];
layer.setSelectedFeatures(ids);
canvas.setExtent(layer.extent());
canvas.refresh();
from qgis.core import QgsApplication; from qgis.gui import QgsMapCanvas; registry = QgsMapLayerRegistry.instance(); canvas = QgsMapCanvas(); name= 'intersecting_zones'; layer = registry.mapLayersByName( name )[0]; layer.removeSelection(); expr = QgsExpression("\"msoa_code_\"='[% "msoa_code_" %]'"); it = layer.getFeatures(QgsFeatureRequest(expr)); ids = [i.id() for i in it]; layer.setSelectedFeatures(ids); canvas.setExtent(layer.extent()); canvas.refresh();

This code (from within Layer Actions) works to a point, I get no error message and the desired target features are selected. However, I cannot get the zoom to selected features functionality to work at all. Am I using the pyqgis code incorrectly, or is there some other approach I should be using to get this last bit working?

nash
1,99615 silver badges19 bronze badges
asked Feb 27, 2017 at 16:53

2 Answers 2

5

Try this code snippet to zoom to selected features of the layer:

canvas = qgis.utils.iface.mapCanvas()
canvas.zoomToSelected(layer) # zooms to selected feature extent for layer
answered Feb 28, 2017 at 13:29
3
  • is there any way to run qgis,utils.iface in headless mode (outside QGIS) ? Commented Apr 4, 2018 at 3:48
  • Yes, you need to create the app object then import the qgis module. Commented Apr 4, 2018 at 12:47
  • But it return "NoneType".. so i got this error (NoneType object has no attribute mapCanvas) Commented May 22, 2018 at 3:16
2

Excellent - that works perfectly. Final code used is:

from qgis.coreimport QgsApplication;
from qgis.gui import QgsMapCanvas;
registry = QgsMapLayerRegistry.instance();
canvas = qgis.utils.iface.mapCanvas()
name= 'intersecting_zones';
layer = registry.mapLayersByName( name )[0];
layer.removeSelection();
expr = QgsExpression("\"msoa_code_\"='[% "msoa_code_" %]'");
it = layer.getFeatures(QgsFeatureRequest(expr));
ids = [i.id() for i in it];
layer.setSelectedFeatures(ids);
canvas.zoomToSelected(layer)
canvas.refresh();
answered Feb 28, 2017 at 14:48
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.