Tutorials
Citygml2obj

CityGML2OBJv2

CityGML2OBJv2 (opens in a new tab) is a command line tool for converting CityGML to OBJ files while maintaining crucial semantic information.

Setting up the Software

Step 1 Clone the GitHub repository (opens in a new tab) to your device.

Step 2 Set up a a Python (3.8) environment

Step 3 Install all the required dependencies using pip install -r requirements.txt

Standard Standard Conversion to OBJ

In the standard conversion mode (without any optional parameters invoked), the whole city model will be converted into one .obj file. The only required command line arguments are -i <path-to-your-input-directory> and -o <path-pyth-to-your-output-directory>

Optional Parameters

In addition to the standard conversion to OBJ, the application offers various processing options that make the software applicaple for a broader range of applications.

Semantics option

Invoke with the optional parameter -s 1.

This option is going to create an individual OBJ file for each of the boundary surfaces (e.g. RoofSurface WallSurface GroundSurface)

Geometry validation

Invoke with the optional parameter -v 1.

This option can be used in order to validate the geometries and skip invalid ones. invalid geometries are reported with their respective gml:id

Object preservation

Invoke with the optional parameter -g 1.

The name of the object will be derived from the gml:id, if not, an ordered list will be made starting from 1, and each object will be named as an integer from 1 to n, where n is the number of objects

Skipping the triangulation

Invoke with the optional parameter -p 1.

OBJ supports polygons, but most software packages prefer triangles. Hence the polygons are triangulated by default (another reason is that OBJ doesn't support polys with holes). However, this may cause problems in some instances, or you might prefer to preserve polygons. Sometimes it also helps to bypass invalid geometries in CityGML data sets.

Conversion of the resulting dataset into a local CRS

Invoke with the optional parameter -t 1.

Normally CityGML data sets are geo-referenced. This may be a problem for some software packages. This option can be used in order to convert the data set to a local system. The origin of the local system correspond to the point with the smallest coordinates (usually the one closest to south-west). this conversion takes place after theprocessing and only affects the vertices in the .obj file.

CitGML translation before processing

Invoke either with -tC 1 or -tCw 1.

If this functionality is invoked, the CityGML datasets in the input folder are translated into a local coordinate system before any further processing. The implementation of this function is motivated by numerical instabilities of the conversion functionality. For some datasets numerical instabilities can cause errors due to the high absoulte coordinate values. The idea of this translation function is to reduce the absolute value of the coordinates by performing a translation into a local coordinate system. the following graphic gives an example on the effect of using this optional functionality.

Better_Window

The image on the left side displays the circular window without translation into a local CRS. the image in the right side shows, how the translation into a local CRS before processing has improved the result.

Calculation of the translation parameters

The translation parameters are calculated ba averaging the upper and lower corners of all the envelopes that are found in the CityGML dataset. Fist, all the envelopes are extracted from the file using the function def getEnvelopes(...). Next, the upper and lower corners are identified and averaged in the function def getTranslationParameters(...)to find the translation parameters. For simplicity, the translation parameters are only considered as integer numbers.

Application of the translation parameters

To apply the translation parameters, the strings that contain the translation parameters have to be identified, splitted and parsed. For this purpose, the functions def appyTranslationToCityGML(...) and def splitAndApplyTrafo(...) are used. The addition of the translation parameters to the coordinates is implemented in two ways. The first is simply based on the Decimal library. A precision of 28 digits is user here. The second approach is implemented in the function def performStableAddition(...). This is an experimental function that should only be used very carefully as errors can not be excluded. Therefore it is not used in the project by default.

Component separation

Invoke with the optional parameter -sepC 1.

This option can be used to separate the different components (walls / roofs / windows / etc.) into individual output files. The index.json file contains information on the gml:id, the gml:parentID and the tag of the objects represented in the indexed files.

This functionality only works for CityGML 1.0 and CityGML 2.0. Version 3.0 is currently not supported. Support for CityGML 3.0 is planned for the future.

Addition of Bounding Box

Invoke with the optional parameter -addBB 1.

Currently, this option can only be used along with the -sepC 1 option. If the -sepC 1 option is not invoked, -addBB 1 will not have any effect.

Screenshot from 2024-08-01 10-15-18

Small triangles indicating the buffered bounding box of the building.

Approximate Windows

Invoke with the optional parameter -appW 1.

Currently, this option can only be used along with the -sepC 1 option. If the -sepC 1 option is not invoked, -appW 1 will not have any effect.

This option can be used to approximate intricate widows that comprise a large number of polygons by their convex hull.

Screenshot from 2024-08-01 10-29-16 Screenshot from 2024-08-01 10-30-28

The same window from slightly different perspectives. Left: The original, detailed window geometry. Right: The approximation by the convex hull of the window.