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

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Oct 30, 2016 at 8:52

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") 
answered Oct 30, 2016 at 13:36
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? Commented Oct 30, 2016 at 13:46
  • 1
    I think, yes, because the answer is for 1) Commented Oct 30, 2016 at 14:19
  • Thanks for the comment, I have posted another post: gis.stackexchange.com/questions/215982/… Commented Oct 30, 2016 at 15:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.