TransWikia.com

Getting layer extent in PyQGIS?

Geographic Information Systems Asked on November 9, 2021

I’m trying to write a processing script using grass r.neighbors algorithm for rasters. When you use the Gui for this algorithm, you can leave the GRASS layer extent field blanc to use the minimal extent. On the contrary, when used in the python console, I can’t find how to input this kind of “default” value.enter image description here

I saw on https://docs.qgis.org/2.2/en/docs/user_manual/processing/console.html that it seems to be mandatory to input the four coordinates for an extent parameter.
I tried using iface.mapCanvas().extent() but the object returned is not accepted as a parameter and I can’t find how to get its coordinates..

Is there a way to get the xmin, ymin, xmax, ymax of the layer in PyQGIS to input them in the algorithm? Am I doing it totally wrong ?

3 Answers

To take it a step further: get the extent, and build a new rectangular polygon from it.

This works like the "Extract layer extent" tool in QGIS 3.8 (may be a quicker way, but this works for me. There's some bonus stuff in here too, like adding and populating new fields to an otherwise empty layer, and changing the opacity).

In this example, sourceLayer would be your input point, line or polygon layer.

vLayer = QgsProject.instance().mapLayersByName("sourceLayerNameHere")[0]
print(vLayer.extent())
uri = "Polygon?crs=epsg:4326&field=id:integer&field=name:string(50)&index=yes"
emptyPolyLayer = QgsVectorLayer(uri, "PolyLayer_00", "memory")

if emptyPolyLayer.isValid():
  print("Layer is valid.")
else:
  print("Layer is NOT valid; exiting...")

# Add some new fields here
prov = emptyPolyLayer.dataProvider()  # get provider
prov.addAttributes([QgsField("Label", QVariant.String)])
prov.addAttributes([QgsField("someNumbers", QVariant.Double)])

emptyPolyLayer.updateFields() # updates the vector layer's schema from provider
field_names = [field.name() for field in prov.fields()]
for count, f in enumerate(field_names):
  print("{} {}".format(count, f))
caps = prov.capabilities()
if caps & prov.EditingCapabilities:
  print('The layer is editable!')
  emptyPolyLayer.startEditing()
  feat = QgsFeature() # instantiate the feature object
  feat.setFields(emptyPolyLayer.fields()) # Important step for a new, empty layer
  print("Attributes are: {}".format(feat.attributes()))
  field_names = [field.name() for field in feat.fields()]
  for count, f in enumerate(field_names):
    print("{} {}".format(count, f)) 
  feat.setGeometry(QgsGeometry.fromRect(vLayer.extent()))   # for polygon feature
  index = feat.fieldNameIndex('Label')
  print("index is: {}".format(index))
  exp = "hello_there" 
  qExp = QgsExpression(exp) # Not needed for a simple string, but good practice for more complex stuff
  print(qExp)
  feat.setAttribute(index, exp)
  emptyPolyLayer.addFeatures([feat]) # add feature 
  emptyPolyLayer.updateFeature(feat)
  emptyPolyLayer.commitChanges()

print("Feature added, layer updated.")
print("Attributes are: {}".format(feat.attributes()))
emptyPolyLayer.updateExtents()

s = QgsSymbol.defaultSymbol(emptyPolyLayer.geometryType()) # grabs the default symbol 
s.setOpacity(0.3)
emptyPolyLayer.renderer().setSymbol(s)

QgsProject.instance().addMapLayer(emptyPolyLayer)
print("{} added to map.".format(emptyPolyLayer.name()))

Answered by grego on November 9, 2021

The answer is almost completely contained in a post I recently wrote.

The extent is returned as a QgsRectangle() object with the following code:

layer = iface.activeLayer() # load the layer as you want
ext = layer.extent()

For getting the coordinates of the vertices for the current layer, you may run this code:

xmin = ext.xMinimum()
xmax = ext.xMaximum()
ymin = ext.yMinimum()
ymax = ext.yMaximum()
coords = "%f,%f,%f,%f" %(xmin, xmax, ymin, ymax) # this is a string that stores the coordinates

Finally, you may run the following code for using the r.neighbors module from the Python Console:

processing.runalg("grass7:r.neighbors",layer,0,3,False,False,"",coords,0,None)

Answered by mgri on November 9, 2021

you were on the right track you just need to go a step further. See the QGIS documentation for QgsRectangle

Basically, you do:

  • get the current Layer

    layer = iface.activeLayer()
    
  • get the extent which is a QgsRectangle object

    ex = layer.extent()
    
  • and there extract the Values with:

    xmax = ex.xMaximum()
    ymax = ex.yMaximum()
    xmin = ex.xMinimum()
    ymin = ex.yMinimum()
    

Answered by LaughU on November 9, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP