[gdal-dev] [python-ogr] GML attributes are missing

Even Rouault even.rouault at mines-paris.org
Fri Feb 25 05:34:41 EST 2011


Selon Frank Broniewski <brfr at metrico.lu>:

> Hello,
>
> I have a problem when converting datasources from one format to GML.
> Whenever I export my source datasource to a GML - datasource the
> attributes of the features are missing in the resulting gml file. Other
> exports to formats like shapefile, kml or geojson have the attributes
> included. When I use ogr2ogr the gml has attributes included. So my
> question is: What's the difference between e.g. a kml and a gml
> outputformat and why does one have attributes and the other doesn't?
> I tried on windows using gdal 1.8 and on Hardy 8.04 with 1.7.x, and on
> both there're no attributes with the gml.

Watching the below code, I'm in fact surprised that it actually works with
shapefile, kml or geojson...

I'm really surprised for shapefile since the call to Layer.CreateField() is
needed to create the appropriate columns in the .DBF. For GeoJSON, from a quick
code review, it might indeed work but you shouldn't rely on that. For KML, I
guess you only get the Name and Description but not ExtendedData.

>
> I use the following code to transform from one format to another:
>
>
> target_driver = driver_by_name(target_format_name)
> target_datasource = create_datasource(target_driver, output_destination)
>
> for layer in iterate_layers(source_datasource):
>      layer_name = layer.GetName()
>      geometry_type = get_geometry_type(layer)
>      target_layer = target_datasource.CreateLayer(layer_name, source_srs,
>                                                   geometry_type)

# At that point, the layer has no fields.

>      feature_definition = layer.GetLayerDefn()

Here you need to use target_layer.CreateField() to create the fields of the
target_layer based on the source layer feature definition.
Something like (untested. might need some minor adjustments on method names)

       # Populate the target layer with field definitions coming from the source
layer definition
       for i in range(feature_definition.GetFieldCount()):
            target_layer.CreateField(feature_definition.GetFieldDefn(i))

       # Now fetch the resulting target feature definition
       target_feature_definition = target_layer.GetLayerDefn()

>      for feature in iterate_features(layer):


>          target_feature = ogr.Feature(feature_definition)

Here's the error : you create a target_feature with the source layer feature
definition. This is bound to fail (and possibly even crash). Replace with :
           target_feature = ogr.Feature(target_feature_definition)

>          target_feature.SetFrom(feature)
>          target_feature.SetFID(feature.GetFID())
>
>          if transformation is not None:
>              geometry_reference = feature.GetGeometryRef()
>              geometry = geometry_reference.Clone()
>              geometry.Transform(transformation)
>              target_feature.SetGeometryDirectly(geometry)
>
>          target_layer.CreateFeature(target_feature)
>
>
> Full code:
> http://paste.pocoo.org/show/344283/
> Python test file
> http://paste.pocoo.org/show/344284/

We should probably add some testing (in the binding code possibly, or deeper in
OGR) to check that the feature passed to Layer.CreateFeature() has a feature
definition matching the Layer.GetLayerDefn(). I would think that most (if not
all) drivers relies on that assumpution, although I don't see it explicitely
documented in
http://gdal.org/ogr/ogr__api_8h.html#301d319111285a47fe6cda6e079214f8

>
>
>
> Frank
>
>
>
>
> --
> Frank BRONIEWSKI
>
> METRICO s.à r.l.
> géomètres
> technologies d'information géographique
> rue des Romains 36
> L-5433 NIEDERDONVEN
>
> tél.: +352 26 74 94 - 28
> fax.: +352 26 74 94 99
> http://www.metrico.lu
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/gdal-dev
>




More information about the gdal-dev mailing list