2

I have LoD1 building data from a federal agency in Germany in the CityGML format. I would like to import and strip the data into R to get only the footprint of the buildings and an attribut about the height. In case of building parts with different heights I would ideally get a the building footprint with multiple height fields (or a list containing the different height information). sf let's me import the data but I only partially gives the expected result: While it works for some buildings, for other building only a part is imported. I included a sample from the data with one building where the import works just fine and the other where only parts of building are imported. I noticed that the structure of the cityObjectMember from the first bldg:Building is different and the gml:id for this building is empty. Although I guess this is the reason why it's not imported correctly but I was wondering if this is because the data is corrupted or if there is a logic behind this.

I have no experience with CityGML but I also couldn't find tutorials on how to work with CityGML in R or any other editor that would allow for anything beyon visualization.

How do I import and strip CityGML data in R?

Here's what I've tried so far:

Test data with two buildings

library(dplyr)
library(sf)

#Import buildings
buildings = read_sf("test_building.xml")

# First building (with empty gml_id) not correctly imported
# Only spatial information for a part of the building is imported 
plot(st_geometry(building[1,]))

#Second building (with gml_id==DENILD4300007ABe) works fine 
plot(st_geometry(building[2,]))
1

I am working with the same data facing the exactly same problem. I found it easier to use the following way to read the data:

library(rgdal)

path <- 'path/to/your/data'

BE <- readOGR(file.path(path, "LoD1_372_5804_2.xml"), encoding = 'UTF-8')

head(BE@data[, grep('measuredHeight', names(BE@data))])

You can see that the part read as a list by sf is separated into columns using rgdal. Here the ‘regular’ variable measuredHeight is now named measuredHeight_ with missing values, wherever the information is stored in the measuredHeight1, … , measuredHeight5 (in this case) variables.

0

I'm not that familiar with R, and have not worked with sf.

The CityGML format is also more complex than you described. A building has many surfaces, and a surface has its own attributes including a polygon which would probably be what you are looking for.

Geometries in CityGML are at the finest level stored as polygons. Try looking for tags with <gml:posList srsDimension="3"> in your CityGML file, you will probably find many polygons. Every line in the <gml:posList srsDimension="3"> tag is a list of vertices. I have not worked with LoD1 data, but it's likely that it will have the format of x0 y0 x1 y1 x2 y2 if it's a 2D triangle. For example, this is what a polygon looks like in my CityGML LoD2 file:

<gml:posList srsDimension="3">317107.971596384 79697.4604185931 15.3638404876802 317107.971596384 79697.4604185931 27.0662941325891 317107.028896385 79697.6447185921 27.0662941325891 317107.028896385 79697.6447185921 15.3638404876802 317107.971596384 79697.4604185931 15.3638404876802</gml:posList>

So, sounds like you want to extract multiple Polygons for a single building, as you say a building can have many footprints. If you are open to other tools, here is a Python tool I wrote that extract polygons and store as .obj mesh files, which You can easily extract polygons from.

You can also check out a data warehousing software called FME, which can also be used to extract geometries from CityGML files. I have a blog post here describing how, you can look at section 2 only.

After acquiring building meshes, you can look up how to import geometries into R. .obj is a very common format for 3D data. All my experience are from handling 3D data only, but should be applicable to 2D too.

Another useful tool for parsing cityGML.

Finally, if you are familiar with .xml files, you can also try parsing the polygons yourself. As mentioned all geometries are stored in the tag <gml:posList srsDimension="3">, as I have observed.

Good luck!

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.