Skip to content

Scalable Workflow for Cities with LiDAR point cloud data

Akshay Patil edited this page Apr 24, 2025 · 1 revision

City4CFD - TUTORIAL

This tutorial is aimed at providing a scalable solution when using City4CFD for cities where the input data is easily available. Thusfar, this workflow has allowed us to reconstruct cities in USA, Australia, The Netherlands, Japan, Spain, New Zealand, Belgium, Canada, to list a few.


INPUT DATA REQUIREMENTS

  1. Semantic surfaces and building footprints
  2. LiDAR point cloud with a point cloud density $\geq 5$ points per buildings. Typically the requirements for the LiDAR point cloud mainly limit the accuracy of the level of detail (LoD) of the buildings in the urban environment as shown in Figure 1. Ideally, a point cloud density of 5 points per building allows for LoD 1.2 reconstruction and higher point cloud density will improve the reconstruction at a higher LoD.

Level of Detail - Definition Biljecki et al. 2013

Figure 1: Various levels of detail for building geometry in the urban environment based on the work by Biljecki et al. (2013) $^1$.


STEPS TO RECONSTRUCT URBAN BUILT ENVIRONMENT

  • Fetch the semantic surfaces and building footprints

To simplify the urban reconstruction, we rely on Open-Street Map (OSM) $^2$ data that contains a large portion of the input data that is routinely updated $\left[ \sim \mathcal{O}(weeks) \right]^3$. As a result, for globally scalable solutions, we assume the building footprint data and the semantic surfaces can be reliably procured from this data source when no local data-set is available.

In order to fetch the buildings polygons and semantic surfaces automatically, use the City4CFD/tools/fetch_polygons/fetch_osm.py python script.

This python script requires the following input data

  1. A text file named cities.txt in the same directory where fetch_osm.py is placed.
#<city-name>, <country-code>, <center-lat>, <center-lon>, <output-EPSG-code>
Chicago, USA, 41.8755616, -87.6244212, EPSG:6455
Barcelona, ESP, 41.39563705715212, 2.1619087803576256, EPSG:25831
Denver, USA, 39.7392364, -104.984862, EPSG:4269

Each line in the cities.txt file uses the following either the two letter code or the three letter coding defined in ISO 3166-1 alpha-2$^4$ and ISO 3166-1 alpha-3$^5$, respectively. The <center-lat> and <center-lon> correspond to the center of the region of interest (assuming a circular region of interest) in EPSG:4326. The column for input per city is the EPSG in which the final output is exported. It is vital to have the <output-EPSG-code> in the same Coordinate Reference System (CRS) as the point cloud.

  1. Within the fetch_osm.py script, the user input parameters that will be applied per city listed in the cities.txt file.
Hmax = 230                            
rbuildings = 1200                    
rpolygons = 4000                      
outdir = "data" 

In the listing above, the first line is used to define the region of interest based on best practice guidelines $^6$. Line number 2 fetches the building footprint polygons within a radius specified by the value. Line number 3 does the same for semantic surfaces defined within the script as line 2. In line 3, the semantic surfaces are defined as detailed below. For most cases the below defined OSM-tags should correctly capture the various surfaces, however, in certain cases, it might be important to either remove or append additional categories to correctly include the necessary surface features. Line number 3 is activated only when $H_{max} &lt; 0$. Line 4 redirects the output polygons within the output directory.

tags = {
    "buildings": {
         "building": True,
         "height": True,
         "building:levels": True
     },
    "vegetation": {
        "landuse": ["forest", "grass", "meadow", "orchard"],
        "leisure": ["park", "nature_reserve", "garden", "dog_park"],
        "natural": ["grassland", "wood"]
    },
    "water": {
        "natural": ["water", "sea"],
        "waterway": True,
    },
    "ocean": {
        "natural": ["coastline"]
    }
}
  1. Dealing with the ocean polygon The ocean "polygon" is downloaded as a line segment instead of a polygon when using OSM. This requires a fair bit of manual edits before it can be directly used in City4CFD. Consider the ocean line segment for the city of Barcelona, ESP downloaded using the fetch_osm.py script shown below.
Coastal Line Segment for adjacent to the city of Barcelona, Spain

Figure 2: Ocean line segment for the city of Barcelona, Spain.

As seen in the figure above, the solid-black line marks the boundary of the ocean polygon. Since there is no adjacent land on the right side of this segment OSM only downloads the line segment corresponding to the "coastline" of the city.

Step 3.a: Open the line segment in QGIS $^7$ as shown in the figure 2. Step 3.b: Toggle the edit mode by clicking the "Yellow pencil" icon and choose the "Digitise with segment option and create additional line segments such that it forms a closed polygon as shown in figure 3.

Barcelona_Ocean_2

Figure 3: Editing the Ocean line segment using QGIS.

Step 3.c: Once you have generated the closed polygon, export it as a new polygon in the same EPSG as the final output.

Step 3.d: Use the City4CFD/tools/polyprep/polyprep.py script to generate a polygon using the line segment data obtained in Step 3.c.

The output from polyprep.py can be used to supply the Ocean polygon.

  1. Handling large water polygons: For certain cases it is important to split large water and vegetation polygons into multiple smaller polygons using QGIS so that they are imprinted within the region of interest. Typically City4CFD handles this quite well, but if the problem persists then it is advised to split the polygon into smaller polygons such that they fit within the region of interest.
  • Fetch the Point cloud Data

Downloading the point cloud data does not have an automated method similar to the polygon data detailed in the previous section. This is mainly a consequence of LiDAR generation and maintenance methods which are heterogenous depending on the local municipality/agency hosting the data. Consequently, we defer the point cloud acquisition to the local methods/sources for sake of brevity.

Classified Point Clouds

Step 4.a: For a classified point cloud, City4CFD requires the following point classes: Vegetation, Water, Ground, and Buildings. Depending on the point cloud classification ID's the class ID corresponding to these might change but for most cases these are the classifications that can be obtained by using a combination of the following commands using lastools$^8$.

2 9 - Terrain
6 - Buildings

Extract classes 2 6 and 9 into a single point cloud.

lasmerge64 -i *.laz -keep_class 2 6 9 -o out.laz

Extract terrain point cloud after thinning it by keeping every 10th point in the point cloud

las2las64 -i out.laz -keep_every_nth 10 -keep_class 2 9 -o terrain.laz

Extract building point cloud after thinning it by keeping every 2nd point in the point cloud

las2las -i out.laz -keep_every_nth 2 -keep_class 6 -o buildings.laz

Unclassified Point Clouds

For unclassified point clouds, there is no easy way to separate the buildings from the terrain using lastools as the points are not classified. Hence, we need to make use of the Cloth Simulation Filter (CSF)$^9$. This can be done either via a python script or Cloud Compare.

Steps below to use Cloud Compare and apply the CSF filter.

Step 4.a: Load the point cloud in Cloud Compare Step 4.b: Click on Plugins/CSF Filter - Choose the terrain follow option. Cloud compare will generate the two points clouds corresponding to ground and buildings. Step 4.c: Export the individual point clouds to files titled terrain.laz and buildings.laz, respectively.

NOTE on usage: When using the CSF filter there is a high chance that a lot of noise is contained within the building point cloud. Consequently, use a relatively lower percentile when reconstructing the building geometry using City4CFD.


Now that all data is available for City4CFD, you can follow the regular tutorial to successfully run the reconstruction process.


References

  1. Biljecki, F., Zhao, J., Stoter, J., & Ledoux, H. (2013). Revisiting the concept of level of detail in 3D city modelling. ISPRS Annals of The Photogrammetry, Remote Sensing and Spatial Information Sciences, 2, 63-74.
  2. Main Page. (2024, September 6). OpenStreetMap Wiki, Retrieved 09:03, April 23, 2025 from https://wiki.openstreetmap.org/w/index.php?title=Main_Page&oldid=2752444.
  3. Planet Homepage. (2025, April 11). OpenStreetMap Wiki, Retrieved 09:04, April 23, 2025 from https://wiki.openstreetmap.org/wiki/Planet.osm
  4. ISO 3166-1 alpha-2. (22 April 2025). Wikipedia, Retrieved 10:00, April 23, 2025 from a https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
  5. ISO 3166-1 alpha-3. (22 April 2025). Wikipedia, Retrieved 10:00, April 23, 2025 from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
  6. J. Franke, A. Hellsten, K. H. Schlunzen, B. Carissimo, (2011). The cost 732 best practice guideline for cfd simulation of flows in the urban environment: A summary, International Journal of Environment and Pollution 44 419–427.
  7. QGIS Development Team, (2025). QGIS Geographic Information System. QGIS Association. https://www.qgis.org
  8. https://lastools.github.io/
  9. Zhang W, Qi J, Wan P, Wang H, Xie D, Wang X, Yan G. (2016), An Easy-to-Use Airborne LiDAR Data Filtering Method Based on Cloth Simulation. Remote Sensing; 8(6):501.