3

Being new with python so far, I got inspired by this answer: https://gis.stackexchange.com/a/155988/8202 to dive into it a bit.

When creating features in a new target layer from an existing source layer, all "solutions" I found so far to create that new layer, were to either

  1. prepare the new target layer manually in QGIS beforehand, adding all fields (with field types, lengths etc).
  2. Hard-code the field settings into the python script when creating that new target layer. How to create a new empty vector layer programmatically?

It seems a bit odd to me that there should be no programmatic way to clone the attribute scheme of a layer, and create a new (memory) layer with this scheme, so you wont have to change your script for each new layer, or fumble things together manually.

I'm focused on the creation of memory-layers, cause I want to have the opportunity to decide by myself if the outcome is satisfactory and save it manually when it fits my needs.

1 Answer 1

8

Here's some quick-and-dirty Python code that works on a simple shapefile layer:

# Get the currently selected layer
inLayer = iface.activeLayer()

# Get its list of fields
inFields = inLayer.dataProvider().fields()

# Convert its geometry type enum to a string we can pass to
# QgsVectorLayer's constructor
inLayerGeometryType = ['Point','Line','Polygon'][inLayer.geometryType()]

# Convert its CRS to a string we can pass to QgsVectorLayer's constructor
inLayerCRS = inLayer.crs().authid()

# Make the output layer
outLayer = QgsVectorLayer(inLayerGeometryType + '?crs='+inLayerCRS, \
    inLayer.name() + u'_copy', \
    'memory')

# Copy the fields from the old layer into the new layer
outLayer.startEditing()
outLayer.dataProvider().addAttributes(inFields.toList())
outLayer.commitChanges()

# Add it to the map
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

I load up a simple shape file, select that layer in the Layers box, paste the above code into the Python console, and a new layer appears with the same attributes.

The key parts here (I'm guessing from your question) are the lines that get the list of fields from the input layer (inLayer.dataProvider().fields(), documented here) and add those same fields to the output layer (outLayer.dataProvider().addAttributes(inFields.toList()), documented here)

3
  • 1
    Thanx a lot. Exactly what I was looking for. Thank you also for pointing out to the documentation ... which doesn't help me much as a beginner. Only fragments and no big picture. Learning from working examples is simply the best :)
    – Bernd V.
    Jul 28, 2015 at 15:38
  • 1
    toProj4() may be more robust than authid() for the CRS, as there could be cases where a useful authid is not available for the CRS. Nov 28, 2016 at 13:59
  • not working for line layer !
    – drama
    Jan 30, 2018 at 11:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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