Saturday, 9 December 2017

qgis - I have an existing attribute table that I'd like to add values to the fields within it while preserving the geometry, how can I do this?



I've tried to use fiona and shapely and ogr, but the tutorials seem to be insufficient to describe how to do such a seemingly simple task. In arcpy this could be done simply with an update cursor. I'm trying to use open source tools here but I'm having some difficulty with editing the attribute table. I'm not interested in creating a new shapefile.


Any suggestions?


(Edit) For example how can I implement the following code using open source tools?


cursor = arcpy.da.UpdateCursor(shpfilepath, ["OID@", "Elevation"]) 
for row in cursor:
row[1] = 15
cursor.updateRow(row)
del cursor

This would change the values of the "Elevation" attribute of all features of shpfilepath to be 15.



(Edit 2) I'm trying to run this as an external script, not as part of QGIS. (Edit 3) I ended up doing it like this:


def addfields(shapefilename, fieldNames):                                             
#adds fields and values to shapefile
#using fieldName, a dictionary that has the structure:
#["ColumnName":"Value"]

#filehandling to open layer
shape = shapefilename
driver = ogr.GetDriverByName('ESRI Shapefile')
dataSource = driver.Open(shape, 1) #1 is read/write

layer = dataSource.GetLayer()

#add fieldnames using ogr
for field in fieldNames:
fldDef1 = ogr.FieldDefn(field, ogr.OFTString)
fldDef1.SetWidth(16) #16 char string width
layer.CreateField(fldDef1)


#iterate through features using fid and add values with ogr

for fieldName in fieldNames:
for fid in range(layer.GetFeatureCount()):
feature = layer.GetFeature(fid)
feature.SetField(fieldName, fieldNames[fieldName])
layer.SetFeature(feature)

Answer



Fiona use dictionaries therefore with your example


for feature in fiona.open(a shapefile): # = for row in cursor:
feature['properties']['Elevation']= 15 # = row[1] = 15


And no need to update a cursor because feature is a dictionary


Now, if you want to update the layer, and not the dictionary, Fiona does not like very much to modify an open shapefile (as ogr). It is preferable to make a copy


with fiona.open(ashapefile) as input:
# schema and crs of the the new shapefile = those of input shapefile
schema = input.schema
crs = input.crs
# creation of the new shapefile
with fiona.open('copy.shp', 'w',schema=schema, crs=crs) as output:
for features in input:
geom = input['geometry']

prop = input['properties']
# change value of the row
prop['properties']['Elevation']= 15
output.write({'geometry':geom, 'properties': prop})

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...