I'm trying to parse a CityGML file in python in order to generate python objects from the buildings. Optimally the objects would have attributes corresponding to the elements in the GML, more or less like city.buildingID('123').roof.geom, which would give me the roof geometry.

I'm aware that specific elements/features can be extracted from CityGML using ElementTree, however I'm looking for a more comprehensive approach, because I need to iteratively access several different parts of each building.

I came accross PyXB, which to my understanding, could help me achieve exactly what I need. It generates python bindings from XSDs, then parses any XML using the corresponding schema to python objects. I generated the bindings using PyXB's provided binding-generator, adapted for CityGML2.0 (https://gist.github.com/balazsdukai/39668a068baf769f64d704e97baa6bbd).

Unfortunately my minimal example does not parse my minimal file. The file contains about 10 buildings, its CityGML2.0, semantically valid and has a non-planar surface according to val3dity.

import os
import pyxb
import pyxb.bundles.opengis.citygml.pbase as pbase # http://www.opengis.net/citygml/profiles/base/2.0

path = "loerrach_sub1.gml"

def citygml_read(gml_path):
    Generates python classes from a citygml file.
    gml = open(gml_path).read()
    pyxb.RequireValidWhenParsing(True) # do/not validate gml file when parsing to binding instance
        citygml_model = pbase.CreateFromDocument(gml, location_base=gml_path)
        return citygml_model
    except pyxb.ValidationError as e:

loer_sub1 = citygml_read(path)

The problem is that with pyxb.RequireValidWhenParsing(False) PyXB raises and exception:

{http://www.opengis.net/gml}FeaturePropertyType cannot accept wildcard content <pyxb.utils.saxdom.Element object at 0x7f5d728f1240>

The package author says that this is, because wildcards are not allowed by the schema (https://github.com/pabigot/pyxb/issues/53). Now, I manually checked if there are wildcards any* in the file but there are none.

Following I tried pyxb.RequireValidWhenParsing(True), but then I get:

The containing element {http://www.opengis.net/citygml/2.0}cityObjectMember is defined at cityGMLBase.xsd[47:1].
The containing element type {http://www.opengis.net/gml}FeaturePropertyType is defined at feature.xsd[76:1]
The unrecognized content WallSurface begins at loerrach_sub1.gml[10:0]
The {http://www.opengis.net/gml}FeaturePropertyType automaton is in an accepting state.
The following element and wildcard content would be accepted:
An element {http://www.opengis.net/gml}_Feature per feature.xsd[81:3]
Unable to convert DOM node {http://www.opengis.net/citygml/building/2.0}WallSurface at loerrach_sub1.gml[10:0] to binding

So, I don't really know what is going wrong here. It seems like something is missing from the bindings, but I believe I included all CityGML-related XSDs.


You might find the CityGML2OBJs and gml2obj tools helpful.

They are both Python tools parsing buildings meshes from CityGML files.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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