2

I've been working on this problem for several questions now - the most recent one here. I believe the code below had created the polygon from the points, and added this polygon to a layer as a polygon in a feature object. The layer is also added to the table of contents. However, for some reason I don't understand the polygon does not display on the canvas?

# Attach libraries
from qgis.core import * # attach main QGIS library
from qgis.utils import * # attach main python library
import os # attach operating system library

# Set a object for the current project
Prj = QgsProject.instance() # Object for current project

# Create an array [] object with the polygon vertices
vrtcs = []
vrtcs.append(QgsPointXY(396100,8969000))
vrtcs.append(QgsPointXY(396100,8973900))
vrtcs.append(QgsPointXY(397900,8973900))
vrtcs.append(QgsPointXY(397900,8969000))

# Create a polygon from the coordinates
ply_01 = QgsGeometry.fromPolygonXY([vrtcs])

# Create a feature object then put the polygon into the feature
ftr = QgsFeature()
ftr.setGeometry(ply_01)
print(ftr.geometry())

# Create a scratch layer for the feature, in the desired CRS
lyr = QgsVectorLayer('Polygon?crs=epsg:29194', '200909_Bdy',"memory")
Prj.addMapLayers([lyr])

# Set an object for the data provider for the layer (not sure why I need this?)
prv = lyr.dataProvider()

# Make the layer editable
lyr.startEditing()

# Add the feature with the polygon to the layer (this fails)
lyr.addFeatures(ftr)

# Save the layer changes
lyr.commitChanges()

# refresh the canvas to show the polygon ?
iface.mapCanvas().refreshAllLayers()

I also expect there is method to interrogate each object to determine what objects have been appended as I go like the line print(ftr.geometry()) which reports the that the object contains a polygon with listed coordinates.

Is there a similar function, which reports what is in the layer?

1 Answer 1

3

You are calling lyr.addFeatures() but passing a single layer object instead of wrapping it in a list.

So do either:

lyr.addFeatures([ftr])

Or:

lyr.addFeature(ftr)

Your code can really be simplified to the following minimal snippet which is working fine for me in the Python console in QGIS 3.14

project = QgsProject().instance()

ply_01 = QgsGeometry.fromPolygonXY(
        [[QgsPointXY(396100,8969000),
        QgsPointXY(396100,8973900),
        QgsPointXY(397900,8973900),
        QgsPointXY(397900,8969000)]]
        )

lyr = QgsVectorLayer('Polygon?crs=epsg:29194', '200909_Bdy', "memory")
ftr = QgsFeature()
ftr.setGeometry(ply_01)
with edit(lyr):
    lyr.addFeature(ftr)
project.addMapLayer(lyr)

For the last part of your question, you can use the getFeatures() method to access the features in your layer e.g.

print([f for f in lyr.getFeatures()])

Or to just get the number of features:

print(lyr.featureCount())

5
  • Ben thanks for taking the time to answer in detail and provide tips on how to simplify the code. The layer loads into the TOC and I'm not getting any errors from the console, however I'm not seeing the polygon appear on the cavass window - not sure what I am missing here? Also regarding interrogating objects how do you get a listing of what types of features may be in a layer (polygon, points and so on?) Sep 9, 2020 at 10:04
  • @user2627043, what if you right click the layer in the TOC and 'zoom to layer'? Copying the code directly from my answer and pasting into Python console is working for me. Really not sure why it wouldn't work for you.
    – Ben W
    Sep 9, 2020 at 10:30
  • Ben thanks again that 'zoom to layer' worked (happy dance). I most probably need to include a line that does this programmatically - will have a hunt as I think I've seen this on another question. Sep 9, 2020 at 10:44
  • Great. iface.zoomToActiveLayer() should work.
    – Ben W
    Sep 9, 2020 at 10:53
  • 1
    Ben that works nicely - I've certainly learned a lot here Sep 9, 2020 at 12:35

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.