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?

Taras
  • 32,823
  • 4
  • 66
  • 137
user2627043
  • 403
  • 3
  • 12

1 Answers1

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())

Ben W
  • 21,426
  • 3
  • 15
  • 39
  • 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?) – user2627043 Sep 09 '20 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 09 '20 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. – user2627043 Sep 09 '20 at 10:44
  • Great. iface.zoomToActiveLayer() should work. – Ben W Sep 09 '20 at 10:53
  • 1
    Ben that works nicely - I've certainly learned a lot here – user2627043 Sep 09 '20 at 12:35