8

I wrote the script to copy a existing shapefile tc_line to a new file tc_pi, and it ran fine:

from shapely.geometry import mapping, shape
import fiona

with fiona.open('tc_line.shp', 'r') as input:
    schema = input.schema.copy()
    input_crs = input.crs
    with fiona.open('tc_pi.shp', 'w', 'ESRI Shapefile', schema, input_crs) as output:
        for elem in input:
            output.write({'properties':elem['properties'],'geometry': mapping(shape(elem['geometry']))})

Now I want to copy the existing file and add a new column (type: float) containing "1" to the attribute table (I would like the new-added column to be attached to the right of the existing columns in the attribute talle), so I edited the code above to this:

from shapely.geometry import mapping, shape
import fiona

with fiona.open('tc_line.shp', 'r') as input:
    schema = input.schema.copy()
    input_crs = input.crs
    schema['properties']['pi'] = 'float'
    with fiona.open('tc_pi.shp', 'w', 'ESRI Shapefile', schema, input_crs) as output:
        for elem in input:
            output.write({'properties':elem['properties'],'geometry': mapping(shape(elem['geometry']))})

but error occurred:

Traceback (most recent call last):


File "C:\Users\Heinz\Desktop\test.py", line 10, in <module>
    output.write({'properties':elem['properties'],'geometry': mapping(shape(elem['geometry']))})
  File "C:\Python27\lib\site-packages\fiona\collection.py", line 333, in write
    self.writerecords([record])
  File "C:\Python27\lib\site-packages\fiona\collection.py", line 327, in writerecords
    self.session.writerecs(records, self)
  File "fiona/ogrext.pyx", line 1024, in fiona.ogrext.WritingSession.writerecs (fiona/ogrext.c:17361)
ValueError: Record does not match collection schema: [u'cat_', u'value', u'label'] != ['pi', u'label', u'value', u'cat_']

How to solve this and achieve my objective of 'copy the existing file and add a new column (type: float) containing "1" to the attribute table of new file'?

I am working with python 2.7.12, Fiona 1.7.0

1 Answer 1

10

It seems to me that you have some problems with Fiona. Remember that all the elements are dictionaries

1) you define a new field schema['properties']['pi'] = 'float'
2) this field must be in in the properties of every elements

with fiona.open('tc_line.shp', 'r') as input:
    schema = input.schema.copy()
    input_crs = input.crs
    schema['properties']['pi'] = 'float'
    with fiona.open('tc_pi.shp', 'w', 'ESRI Shapefile', schema, input_crs) as output:
         for elem in input:
              elem['properties']['pi']= 1
              output.write({'properties':elem['properties'],'geometry': mapping(shape(elem['geometry']))})

If you're not comfortable with Python dictionaries, use GeoPandas (it uses Fiona)

import geopandas as gpd
gdf = gpd.read_file("tc_line.shp")
gdf["pi"]= 1
gdf.to_file("tc_pi.shp") 
3
  • Thank you for the answer, since I edited my post earlier, should I post other parts (without add column issue) of the question in a new post?
    – Heinz
    Commented Oct 30, 2016 at 13:46
  • 1
    I think, yes, because the answer is for 1)
    – gene
    Commented Oct 30, 2016 at 14:19
  • Thanks for the comment, I have posted another post: gis.stackexchange.com/questions/215982/…
    – Heinz
    Commented Oct 30, 2016 at 15:00

Your Answer

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

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