GDAL – Troubleshooting Field Updates in GML Files

fields-attributesgdalogrupdate

I'm currently attempting to add a new field to each feature in a file, however, the file is not getting changed.

I've tried using driver.Open(file_path, 1) and driver.Open(file_path, update=1), but this throws a None error on the GetLayer() line. The file is not open in any other software.

When I print the layerdefn.GetFieldCount(), it is the same as previously (before adding my area field).

Here is the code I have so far:

    driver = ogr.GetDriverByName('GML')
    data_source = driver.Open(file_path)
    layer = data_source.GetLayer()

    # Create a field
    field_definition = ogr.FieldDefn("area", ogr.OFTInteger)
    layer.CreateField(field_definition)

    layer_definition = layer.GetLayerDefn()

    for feature in layer:
        area = 10  # These are different values per feature, but I've removed the code that gets areas
        feature.SetField(layer_definition.GetFieldCount() - 1, area)  # I've also tried the string "weights", but this gives an Invalid Index -1 error.
        # Apply the change
        layer.SetFeature(feature)

    data_source = None

Does anyone have any suggestion/solution?

Best Answer

The first line of the docs states:

OGR has limited support for GML reading and writing. Update of existing files is not supported.

And even if it was supported, you're opening the file in read mode driver.Open(file_path) instead of update mode driver.Open(file_path, update=1)

Here's a workaround - copy the dataset to an updateable format then update and copy to GML.

from osgeo import gdal, ogr

gml = "/vsicurl/https://raw.githubusercontent.com/OSGeo/gdal/master/autotest/ogr/data/gml/test_point.gml"
shp = '/vsimem/test.shp'  # /vsimem = in memory
outgml = '/path/to/test_point.gml'

gdal.UseExceptions()
ogr.UseExceptions()

gdal.VectorTranslate(shp, srcDS=gml, format='Esri Shapefile')

ds = ogr.Open(shp, gdal.GA_Update)

layer = ds.GetLayer(0)

# Create a field
field_definition = ogr.FieldDefn("area", ogr.OFTInteger)
layer.CreateField(field_definition)

layer_definition = layer.GetLayerDefn()

for feature in layer:
    area = 10  # These are different values per feature, but I've removed the code that gets areas
    feature.SetField(layer_definition.GetFieldCount() - 1,
                     area)  # I've also tried the string "weights", but this gives an Invalid Index -1 error.
    # Apply the change
    layer.SetFeature(feature)
del ds
gdal.VectorTranslate(outgml, shp, format='GML')
Related Question