osm2city Documentation Release 1.0

osm2city team

Feb 27, 2021

Contents

1 Using Generated Scenery [User]3 1.1 Finding and Downloading a osm2city Scenery...... 3 1.2 Adding to FG_SCENERY Path...... 3 1.3 Adjusting Visibility of Scenery Objects...... 3 1.4 Disable Urban Shader and Random Buildings...... 4 1.5 Showing Detailed Objects...... 6 1.6 Change Materials to Hide Urban Textures...... 6 1.7 Change Materials to Not Crash FG for Sceneries with Shader Buildings (BUILDING_LIST).....8

2 Installation [Builder] 11 2.1 Pre-requisites...... 11 2.2 Installation of osm2city...... 12 2.3 Setting up PostGIS...... 13 2.4 Other Tools...... 14

3 Preparation [Builder] 17 3.1 Creating a Directory Structure...... 17 3.2 Getting OpenStreetMap Data...... 18 3.3 Setting a Minimal Set of Parameters...... 19 3.4 Generating Elevation Data...... 20

4 Scenery Generation [Builder] 21 4.1 Setting the Working Directory...... 21 4.2 Creating the Texture Atlas...... 21 4.3 Internet Connection for WikiData...... 22 4.4 Running the Generation Scripts with build_tiles.py...... 22 4.5 Consider Sharing Your Generated Scenery Objects...... 23

5 Parameters [Builder] 25 5.1 View a List of Parameters...... 25 5.2 Important Parameters...... 26 5.3 Buildings...... 27 5.4 Linear Objects (Roads, Railways)...... 41 5.5 Land-Use...... 43 5.6 Textures...... 47 5.7 Other Parameters...... 47

i 6 How osm2city Works 51 6.1 Specific Stuff...... 52

7 Appendix 59 7.1 OSM Data in a PostGIS Database [Builder]...... 59 7.2 Developer Information...... 59

ii osm2city Documentation, Release 1.0

While the article on FlightGear’s Wiki presents in general terms what osm2city is and which features it has, this manual goes into depth with many aspects of generating scenery objects based on OpenStreetMap (OSM) data and deploying/using them in FlightGear. Before you generate your own sceneries, you might want to get familiar with the output of osm2city by first deploy- ing some of the downloadable osm2city sceneries and have a look at chapter Using Generated Scenery. See amongst others Areas populated with osm2city scenery or look for announcements in the Sceneries part of the FlightGear Forums. User in the context of this guide means the end user in FlightGear using osm2city generated sceneries. Builder means a person using osm2city to generate a scenery. Contents:

Contents 1 osm2city Documentation, Release 1.0

2 Contents CHAPTER 1

Using Generated Scenery [User]

1.1 Finding and Downloading a osm2city Scenery

The FlightGear wiki article Howto: Install Scenery has a general overview over installing scenery in FlightGear. Areas populated with osm2city scenery is the best way currently to find osm2city generated sceneries. That wiki page also list which sceneries can be downloaded in Terrasync and for which FlightGear version. The plan for the future is to have the whole world available in constantly updated versions — however as of spring 2017 this is not yet a reality. Even though a scenery might be available for download in TerraSync, you might want to download offline by using a tool like TerraMaster or terrasync.py, because the volume of data can be quite comprehensive — the faster you fly and the slower your internet connection, the rougher the experience will be.

1.2 Adding to FG_SCENERY Path

You need to add the directory containing the Buildings, Pylons and Roads folders to the path, where Flight- Gear searches for scenery. You can to this either through the command line option --fg-scenery or setting the FG_SCENERY environment variable. This is extensively described in the README.scenery and the getstart. pdf1 documents found in $FG_ROOT/Docs as part of your FlightGear installation. If you followed the directory structure presented in chapter Preparation and we take the example of LSZS then you would e.g. use the following command line option:

--fg-scenery=/home/pingu/fg_customscenery/LSZS

1.3 Adjusting Visibility of Scenery Objects

The osm2city related programs and especially buildings.py are using heuristics and parameters to determine at what level of detail (LOD) scenery objects should be visible. This is done by adding the objects to one of the three

1 As of November 2016: chapters 3.1 and 4.2.2

3 osm2city Documentation, Release 1.0

FlightGear LOD schemes: “rough” or “detailed” (“bare” is not used). For buildings.py before creating a scenery you can influence into which of the two LOD ranges the objects are placed by using the following Parameters: • LOD_ALWAYS_DETAIL_BELOW_AREA • LOD_ALWAYS_ROUGH_ABOVE_AREA • LOD_ALWAYS_ROUGH_ABOVE_LEVELS • LOD_ALWAYS_DETAIL_BELOW_LEVELS • LOD_PERCENTAGE_DETAIL In FlightGear as a scenery user you influence the actual distance (in meters) for the respective ranges by one of the following ways: 1. In The FlightGear user interface use menu View > menu item Adjust LOD Ranges and then change the values manually. 2. Include command line options into your fgfsrc file or Properties in FGRun like follows (adjust the values to your needs and depending on your hardware capabilities):

--prop:double:/sim/rendering/static-lod/detailed=5000 --prop:double:/sim/rendering/static-lod/rough=10000 --prop:/sim/rendering/max-paged-lod=400

See also PagedLOD.

1.4 Disable Urban Shader and Random Buildings

There is no point in having both OSM building scenery objects and dynamically generated buildings in FlightGear. Therefore it is recommended to turn off the random building and urban shader features in FlightGear. Please be aware that this will also affect those areas in FlightGear, where there are no generated scenery objects from OSM. Use the FlightGear menu View, menu item Rendering Options. • Scenery layers: * Buildings: Choose OpenStreetMap Data (i.e. Randomly Generated is turned off) * Pylons and power lines: not only used for electrical power pylons and cables, but also e.g. wind turbines * Detailed Roads and Railways: draped over the grey roads and railways lines in the default scenery. • If you also enable Atmospheric Light Scattering (ALS) you also get better effects during day and night as well as moving cars. Not using ALS might give odd graphical effects.

4 Chapter 1. Using Generated Scenery [User] osm2city Documentation, Release 1.0

In the same dialog press the Shader Options button and set the slider for Urban to the far left in order to disable the urban shader.

1.4. Disable Urban Shader and Random Buildings 5 osm2city Documentation, Release 1.0

1.5 Showing Detailed Objects

NB: this is only needed if you are using a FlightGear version 2020.3 or older. Some of the generated sceneries might contain a sub-folder Details apart from e.g. Buildings. If you want to show more scenery details like railway overhead lines, smaller electrical pylons and cables, railway platforms etc. (and accept that this might drain some system resources), then rename the folder to Objects.

1.6 Change Materials to Hide Urban Textures

FlightGear allows to change the texture used for a given land-class. More information is available in $FG_ROOT/ Docs/README.materials as well as in the FlightGear Forum thread regarding New Regional Textures. There is not yet a good base texture replacing the urban textures. However many users find it more visually appealing to use a uniform texture like grass under the generated buildings etc. instead of urban textures (because urban textures interfere visually with ways, houses etc.). A drawback of using different textures is the absence of trees — however in many regions of the world there are lot of trees / vegetation in urban areas. An important drawback is that you will find the texturing missing when flying high over ground (due to level of distance not loading OSM objects) or for stuff far in the distance, where OSM data has not yet been loaded. E.g. for the airport LSZS in Engadin in Switzerland you would have to go to $FG_ROOT/Materials/regions and edit file europe.xml in a text editor: add name-tags for e.g. BuiltUpCover, Urban, Town, SubUrban to a material as shown below and comment out the existing name-tags using . Basically all name-tags, which relate to a material using Effects/urban. The outcome before and after edit (you need to restart FlightGear in between!) can be seen in the screenshots below (for illustration purposes the buildings and roads do not have textures).

... (continues on next page)

6 Chapter 1. Using Generated Scenery [User] osm2city Documentation, Release 1.0

(continued from previous page) Effects/cropgrass Effects/tree-european-mixed CropGrassCover CropGrass BuiltUpCover Urban Town SubUrban Terrain/cropgrass-hires-autumn.png Terrain/cropgrass-hires.mask.png ...

... Effects/urban ...

1.6. Change Materials to Hide Urban Textures 7 osm2city Documentation, Release 1.0

Depending on your region and your shader settings you might want to search for e.g. GrassCover in file global-summer.xml instead (shown in screenshot below with ALS and more random vegetation). However be aware that you still need to comment out in e.g. europe.xml and within global-summer.xml.

1.7 Change Materials to Not Crash FG for Sceneries with Shader Buildings (BUILDING_LIST)

If you are using a scenery, which uses BUILDING_LIST and your FlightGear version is older than 2019.2 (e.g. 2019.1.x, 2018.3.x or earlier), then FlightGear will crash. The easiest way to handle this is to not use such a scenery. Alternatively you can follow the instructions below - it might help. You can spot whether you are using such a scenery by finding files with names like *_buildings_shader.txt (e.g. TEST/Buildings/e000n40/e008n47/e000n40_e008n47_3088961_buildings_shader.

8 Chapter 1. Using Generated Scenery [User] osm2city Documentation, Release 1.0 txt). Add the following after the last tag and before the tag at the end of $FG_ROOT/Materials/regions/global.xml:

OSMBuildings

0.4 0.5 0.1 0.8 0.8 0.4

1 2

2 3

3 5

9 14 8 12

15 20 10 15

15 22 12 18

1.7. Change Materials to Not Crash FG for Sceneries with Shader Buildings (BUILDING_LIST) 9 osm2city Documentation, Release 1.0

10 Chapter 1. Using Generated Scenery [User] CHAPTER 2

Installation [Builder]

The following specifies software and data requirements as part of the installation. Please be aware that different steps in scenery generation (e.g. generating elevation data, generating scenery objects) might require a lot of memory and are CPU intensive. Either use decent hardware or experiment with the size of the sceneries. However it is more probable that your computer gets at limits when flying around in FlightGear with sceneries using osm2city than when generating the sceneries. As an alternative to the official guide below, there is an article on the Flightgear wiki for osm2city on Windows maintained by a user.

2.1 Pre-requisites

2.1.1 Python osm2city is written in Python and needs Python for execution. Python is available on all major desktop operating systems — including but not limited to Windows, and Mac OS X. See http://www.python.org. Currently Python version 3.8 is used for development and is therefore the recommended version.

2.1.2 Python Extension Packages osm2city uses the following Python extension packages, which must be installed on your system and be included in your PYTHONPATH: • descartes • matplotlib • networkx • numpy (on Windows you need Numpy+MKL) • Pillow

11 osm2city Documentation, Release 1.0

• pyproj • requests • scipy • shapely • psycopg2-binary Please make sure to use Python 3.8+ compatible extensions. Often Python 3 compatible packages have a “3” in their name. Most Linux distributions come by default with the necessary packages — often they are prefixed with python- (e.g. python-numpy). On Windows WinPython (https://winpython.github.io/) together with Christoph Gohlke’s unofficial Windows binaries for Python extension packages (http://www.lfd.uci.edu/~gohlke/pythonlibs/) works well.

2.1.3 Virtual Environments

The following is optional respectively a better way to install Python extension packages then what was described above — however it might be a bit more difficult. You might want to consider using a Python Virtualenv instead of using Python directly as installed in your OS. Once you have installed virtualenv on your system, you should create a base directory for your virtual environments (e.g. $HOME/bin/virtualenvs). Then:

user$ python3 -m venv /home/pingu/bin/virtualenvs/o2c38 user$ source /home/pingu/bin/virtualenvs/o2c38/bin/activate (o2c38) user$ cd /home/pingu/osm2city

(o2c38) user$ pip install --upgrade pip (o2c38) user$ pip install --upgrade setuptools

(o2c36) user$ pip install -r requirements.txt

2.2 Installation of osm2city

There is no installer package - neither on Windows nor Linux. “osm2city” consists of a set of Python programs and the related data in “osm2city-data”. You need both. Do the following: 1. Download the packages either using Git or as a zip-package. 2. Add the osm2city directory to your PYTHONPATH (see below). 3. Make sure that you have set $FG_ROOT.

2.2.1 Setting PYTHONPATH

You can read more about this at https://docs.python.org/3.5/using/cmdline.html#envvar-PYTHONPATH. On Linux you would typically add something like the following to your .bashrc file:

PYTHONPATH=$HOME/develop_vcs/python3/osm2city export PYTHONPATH

12 Chapter 2. Installation [Builder] osm2city Documentation, Release 1.0

2.2.2 Setting Environment Variable $FG_ROOT

The environment variable $FG_ROOT must be set in your operating system or at least your current session, such that fgelev can work optimally. How you set environment variables is depending on your operating system and not described here. I.e. this is NOT something you set as a parameter in params.ini! You might have to restart Windows to be able to read the environment variable that you set through the control panel. In Linux you might have to create a new console session. $FG_ROOT is typically a path ending with directories data or fgdata (e.g. on Linux it could be /home/pingu/bin/fgfs_git/next/install/flightgear/fgdata; on Windows it might be :\flightGear\2017.3.1\data). BTW: you have to set the name of the variable in your operating system to FG_ROOT (not $FG_ROOT).

2.3 Setting up PostGIS

2.3.1 Installed Packages on Linux

On Ubuntu 20.04 the following packages have amongst others been installed (not exhaustive list): • postgresql-12 • postgis • postgresql-12-postgis-3 • postgresql-client-12 • postgresql-common • pgadmin3 • python3-psycopg2

2.3.2 Installing on Windows

For windows, the best way to get PostgreSQL and PostGI is to use this download page: https://www.enterprisedb.com/ downloads/postgres-postgresql-downloads: version 9.6 was tested and works well on Windows. After installation of PostgreSQL, use the Stackbuilder tool included with PostgreSQL to download and install PostGIS version 2.5, which is found under “spatial extensions”.

2.3.3 Creating a database and loading data

Create a database user:

$ sudo -u postgres psql postgres=# CREATE USER gisuser WITH PASSWORD 'myPassword'; postgres=# \q

• The following examples of usage will assume that the database name is kbos and the user is gisuser. Of course your installation can differ and you can set different parameters for´ Database. • See Getting OpenStreetMap Data. To get data for the whole planet go to Planet OSM (http://planet.osm.org/).

2.3. Setting up PostGIS 13 osm2city Documentation, Release 1.0

• Setting up a PostGIS database as described in PostGIS setup (replace pgsnapshot with whatever you named the database, e.g. osmogis). For now schema support for linestrings does not have to be set up. However you need to run at least pgsnapshot_schema_0.6.sql and pgsimple_schema_0.6_bbox.sql. • Load data (see also PostGIS Tasks (Snapshot Schema)) • Update the indices in the database Preparing the database might look as follows: sudo-u postgres createdb--encoding=UTF8--owner=gisuser kbos sudo-u postgres psql postgres=# \connect kbos kbos=# CREATE EXTENSION postgis; kbos=# CREATE EXTENSION hstore; kbos=# GRANT ALL PRIVILEGES ON DATABASE kbos to gisuser; kbos=# \q psql--username=gisuser-d kbos-f/home/pingu/bin/osmosis-latest/script/pgsnapshot_

˓→schema_0.6.sql psql--username=gisuser-d kbos-f/home/pingu/bin/osmosis-latest/script/pgsnapshot_

˓→schema_0.6_bbox.sql

The you might first cut down the downloaded OSM pbf-file to the needed area and finally import it to the database:

$ /home/vanosten/bin/osmosis-latest/bin/osmosis --read-pbf file="/media/sf_fg_

˓→customscenery/projects/TEST/massachusetts-latest.osm.pbf" --bounding-box

˓→completeWays=yes top=42.625 left=-72 bottom=42.125 right=-70.5 --write-pbf file="/

˓→media/sf_fg_customscenery/projects/TEST/kbos.pbf"

$ /home/vanosten/bin/osmosis-latest/bin/osmosis --read-pbf file="/media/sf_fg_

˓→customscenery/projects/TEST/kbos.pbf" --log-progress --write-pgsql database=kbos

˓→host=localhost:5433 user=gisuser password=!Password1

And finally you might want to index the tags in hstore to get some more query speed after loading the data. However, this can take a long time and actually not even be worth it, even though you might use the database many times:

CREATE INDEX idx_nodes_tags ON nodes USING gist(tags); CREATE INDEX idx_ways_tags ON ways USING gist(tags); CREATE INDEX idx_relations_tags ON relations USING gist(tags);

2.3.4 Remarks

• I have not found out how to add an additional region to an already populated database. Therefore you might need to run /home/pingu/bin/osmosis-latest/bin/osmosis --truncate-pgsql database=kbos before getting a new region into the database if you have only one database. The better approach is of course using several databases in parallel.

2.4 Other Tools

You might want to check out Sławek Mikuła’s scripts for osm2city parsing and generation, which make some of the repetitive manual tasks involved in generating a scenery a bit easier.

14 Chapter 2. Installation [Builder] osm2city Documentation, Release 1.0

2.4.1 OSMOSIS

You might also need a 0.6+ version of Osmosis. Please be aware of the fact that you also need a related version of Java and that e.g. in Ubuntu 17.10 Osmosis is out of date — i.e. you should NOT use a (Linux) distribution package and instead use the one from the source.

2.4.2 JOSM

JOSM is an offline editor for OSM-data. It is not strictly required for pre- or post-processing of osm2city, but it might be handy for debugging and detailed investigations. Information about JOSM including installation instructions can be found at https://josm.openstreetmap.de/.

2.4. Other Tools 15 osm2city Documentation, Release 1.0

16 Chapter 2. Installation [Builder] CHAPTER 3

Preparation [Builder]

Before osm2city related programs can be run to generate FlightGear scenery objects, the following steps need to be done: 1. Creating a Directory Structure 2. Getting OpenStreetMap Data 3. Setting Minimal Parameters 4. Generating elevation data It is recommended to start with generating scenery objects for a small area around a smaller airport outside of big cities, such that manual errors are found fast. Once you are acquainted with all process steps, you can experiment with larger and denser areas.

3.1 Creating a Directory Structure

The following shows a directory structure, which one of the developers is using — feel free to use any other structure.

HOME/ flightgear/ fgfs_terrasync/ Airports/ Models/ Objects/ Terrain/ terrasync-cache.xml development osm2city/ osm2city-data/ ... fg_customscenery/ KBOS/ Buildings/ (continues on next page)

17 osm2city Documentation, Release 1.0

(continued from previous page) w080n40/ w071n42/ 3105315.btg w080n40_w071n42_1794312city00000.ac ... Pylons/ ... Roads/ ... LSME/ Buildings/ ... projects/ KBOS/ kbos_narrow.osm (not needed it database is used) params.py LSME/ ...

The directory flightgear contains folder fgfs_terrasync. This is where you have your default FlightGear scenery. The FlightGear Wiki has extensive information about TerraSync and how to get data. You need this data in folder, as osm2city only enhances the scenery with e.g. additional buildings or power pylons. The directory development contains the osm2city programs and data after installation as explained in Installa- tion. In the example directory structure above the directory fg_customscenery hosts the input and output information — here two sceneries for airports KBOS and LSME (however there is no need to structure sceneries by airports). The output of osm2city scenery generation goes into e.g. fg_customscenery/KBOS while the input to the scenery generation is situated in e.g. fg_customscenery/projects/KBOS (how to get the input files in this folder is discussed in the following chapters). The directory structure in the output folders (e.g. fg_customscenery/KBOS) is created by osm2city related programs, i.e. you do not need to create it manually. The directory .../fg_customscenery/projects will be called WORKING_DIRECTORY in the following. This is important because osm2city related programs will have assumptions about this.

3.2 Getting OpenStreetMap Data

The OpenStreetMap Wiki has comprehensive information about how to get OSM data. An easy way to start is using Geofabrik’s extracts (http://download.geofabrik.de/). It is highly recommend to limit the area covered as much as possible: it leads to faster processing and it is eas- ier to experiment with smaller areas until you found suitable parameters. If you use Osmosis to cut the area with --bounding-box, then you need to use completeWays=yes1. E.g. on Windows it could look as follows:

c:\>"C:\FlightGear\osmosis-latest \bin\osmosis.bat"--read-pbf file="C:\FlightGear \fg_

˓→customscenery\raw_data\switzerland-latest.osm.pbf" --bounding-box completeWays=yes top=46.7 left=9.75 bottom=46.4 right=10.0--wx

˓→file="C:\FlightGear\fg_customscenery\projects\LSZS\lszs_wider.osm"

1 Failing to do so might result in an exception, where the stack trace might contain something like KeyError: 1227981870.

18 Chapter 3. Preparation [Builder] osm2city Documentation, Release 1.0

3.3 Setting a Minimal Set of Parameters osm2city has a large amount of parameters, by which the generation of scenery objects based on OSM data can be influenced. Chapter Parameters has detailed information about the most important of these parameters[#]_. However to get started only a few parameters must be specified — actually it is generally recommended only to specify those parameters, which need to get a different value from the default values, so as to have a better understanding for which parameters you have taken an active decision. Create a params.py file with your favorite text editor. In our example it would get stored in fg_customscenery/ projects/LSZS and the minimal content could be as follows:

PREFIX="LSZS" PATH_TO_SCENERY="/home/flightgear/fgfs_terrasync" PATH_TO_OUTPUT="/home/fg_customscenery/LSZS" PATH_TO_OSM2CITY_DATA="/home/user/osm2city-data"

NO_ELEV= False FG_ELEV='/home/pingu/bin/fgfs_git/next/install/flightgear/bin/fgelev'

DB_HOST="localhost" DB_PORT= 5433 DB_NAME="osmgis" DB_USER="gisuser" DB_USER_PASSWORD="n/a"

A few comments on the parameters: PREFIX Needs to be the same as the specific folder below fg_customscenery/projects/. Do not use spaces in the name. PATH_TO_SCENERY Full path to the scenery folder without trailing slash. This is where we will probe elevation and check for overlap with static objects. Most likely you’ll want to use your TerraSync path here. PATH_TO_OUTPUT The generated scenery files (.stg, .ac) will be written to this path — specified without trailing slash. If empty then the correct location in PATH_TO_SCENERY is used. Note that if you use TerraSync for PATH_TO_SCENERY, you MUST choose a different path here. Otherwise, TerraSync will overwrite the generated scenery. Unless you know what you are doing, there is no reason not to specify a dedicated path here. While not absolutely needed, it is good practice to name the output folder the same as PREFIX. NO_ELEV Set this to False. The only reason to set this to True would be for builders to check generated scenery objects a bit faster not caring about the vertical position in the scenery. FG_ELEV Set parameter FG_ELEV to point to the full path of the fgelev executable. On Linux it could be something like FG_ELEV = '/home/pingu/bin/fgfs_git/next/install/flightgear/bin/ fgelev'. On Windows you might have to put quotes around the path due to whitespace e.g. FG_ELEV = '"D:/Program Files/FlightGear/bin/Win64/fgelev.exe"' (yes, both single and double quotes). DB_* Connection settings for PostGIS: see database parameters.

3.3.1 Advanced Parameter Setting

The parameter files are just regular Python files, the content of which is merged with the default parameters. This actually allows for some scripting, if you know very basic Python programming. The parameter AREA has been added with the sole purpose of helping you reuse some parameters, while having some saved for special areas. This saves the trouble of having different parameter files for different areas.

3.3. Setting a Minimal Set of Parameters 19 osm2city Documentation, Release 1.0

The following is an example of how that can be used, where the only change between two generations is that I have to update AREA to be either “HAWAII” or “SCOTLAND”. NB: “. . . ” in the example below is just to tell that there would be other parameters - you must not have it in your file.

AREA='HAWAII' ... OWBB_USE_EXTERNAL_LANDUSE_FOR_BUILDING_GENERATION= True OWBB_LANDUSE_CACHE= True ... if AREA =='HAWAII': OWBB_GENERATE_BUILDINGS= True OWBB_USE_BTG_LANDUSE= True ... elif AREA =='SCOTLAND': OWBB_USE_EXTERNAL_LANDUSE_FOR_BUILDING_GENERATION= False ...

The drawback of this advanced parameter setting is, that you might get difficult to interpret error messages, if you do something wrong. Python knowledge helps in that case. If you want to use your own variables, then make sure you prefix them with “_” (underscore) - otherwise the process will abort immediately because an unknown parameter was found.

3.4 Generating Elevation Data osm2city uses scenery elevation data from the FlightGear sceneries (TerraSync) for two reasons: • No need to get additional data from elsewhere. • The elevation of the generated scenery objects need to be aligned with the underlying scenery data (otherwise houses could hover over the ground or be invisible because below ground level). This comes at the cost that elevation data must be obtained by “flying” through the scenery, which can be a time consuming process for larger areas — especially if you need a good spatial resolution e.g. in mountain areas like Switzerland. Please be aware that the scenery data needed for your area might not have been downloaded yet by TerraSync, e.g. if you have not yet “visited” a specific tile. An easy way to download large areas of data is by using TerraMaster. If you are exclusively using TerraMaster to download data, then make sure that you in TerraMaster also use button “Synchronise shared models”.

20 Chapter 3. Preparation [Builder] CHAPTER 4

Scenery Generation [Builder]

4.1 Setting the Working Directory osm2city needs to make some assumption about the absolute paths. It is recommended to make conscious decisions about the directory structure and choosing the WORKING_DIRECTORY accordingly. Therefore before running osm2city related programs please either: • set the working directory explicitly if you are using an integrated development environment (e.g. PyCharm) • change into the working directory in your console, e.g.

$ cd /home/pingu/fg_customscenery/projects

4.2 Creating the Texture Atlas

If you are creating sceneries to be consumed by others using a FG version 2017.2 or later, then please skip this chapter — unless you know what you are doing. Skipping will just use the texture atlas already provided by osm2city-data. In order to be able to use textures for buildings a texture atlas (a structured collection of textures stored in a single image file) needs to be created. Re-creating a texture atlas should only be done if the contained textures change. That is rarely the case. Also remember that if the texture atlas changes, then also the content has to be copied into FGData /Textures/osm2city (which has to be done either manually by the scenery user og by committing to the FlightGear FGData repository - meaning that it is first generally available with the next FlightGear release). In most situations it is enough to call the following command once and then only if the textures have changed:

/usr/bin/python3/home/pingu/develop_vcs/osm2city/prepare_textures.py-f LSZS/params.

˓→py

21 osm2city Documentation, Release 1.0

Chapter Textures has an overview of how roof and facade textures can be filtered to suit a given scenery’s needs by means of parameters.

4.3 Internet Connection for WikiData

OSM data can contain links to WikiData, where more information can be stored. This is used in osm2city for fetching population data used in determining the settlement type. This improves the accuracy of the heuristics, but you can run the scripts without internet connection.

4.4 Running the Generation Scripts with build_tiles.py

As a first step you must prepare OSM data in a database. Be sure that the data in the database covers the whole area for batch processing. Calling the batch process is then pretty easy in just one step:

$ /usr/bin/python3 /home/pingu/develop_vcs/osm2city/batch_processing/build_tiles_db.

˓→py -f TEST/params.py -b 8.25_47_8.5_47.2 -p 3

Mandatory command line arguments: • -b BOUNDARY: the boundary as an underscore delimited string WEST_SOUTH_EAST_NORTH like 9.1_47.0_11_48.8 (use ‘.’ as decimal separator). If the Western longitude is negative (e.g. in Americas), then use an asterisk character (*) in front (e.g. -b *-71.25_42.25_-70.75_42.5 for the Boston Logan airport KBOS). • -f FILE_PATH: the relative path to the main params.py file. Remember that the paths are relative to the WORKING_DIRECTORY. • -p NUMBER: number of parallel processes (should not be more than the number of cores/CPUs) and might be constrained by memory Optional arguments: • -h, --help: show a help message and exit • -m NUMBER: the maximum of child tasks a worker process completes before it will exit. Unless you know what you are doing and have problems with constantly increasing use of resources, then do not specify a value here (otherwise start with assigning the most conservative value of 1). The default is unlimited. • -l LOGLEVEL, --loglevel LOGLEVEL: sets the logging level. Valid levels are DEBUG, INFO, WARN- ING, ERROR, CRITICAL • -o, --logtofile: writes the logging information into files in the working directory. There will be a set of log files: – osm2city-exceptions.log: is always existing and appended to whenever a tile cannot be processed due to an exception. You should consider deleting the file whenever you are done processing and satisfied with the result. But have first a look at it to make sure that all tiles actually got processed (tile index number and processing time get stored if something is wrong along with the exception) – osm2city_main_YYYY-MM-DD_hhmmss.log (e.g. osm2city_main_2017-12-28_222432.log): the main process splitting the area up into tiles and assigning to sub-processes. Gives an idea about the overall processing on a per tile level.

22 Chapter 4. Scenery Generation [Builder] osm2city Documentation, Release 1.0

– osm2city_process_SpawnPoolWorker-#_YYYY-MM-DD_hhmmss.log (e.g. osm2city_process_SpawnPoolWorker-2_2017-12-28_222442.log): the detailed processing log. Un- less you have specified argument -m then there will be as many files as there are processes as per argument -p NUMBER. • -e PROCEDURE, --execute PROCEDURE: execute only the given procedure[s]. Otherwise everything is generated i.e. main and details (subject to refinement by parameters, not arguments): – buildings: generates buildings – roads: generates different types of roads and railway lines – pylons: generates pylons and cables between them for (major) power lines. Also creates wind turbines, storage tanks and chimneys. – main: all of the above – details: generates (railway) platforms, piers and boats as well as minor power lines, aerial ways, railway overhead lines as well as street-lamps. – trees: generates trees mapped in OSM as well as heuristics for trees in parks and gardens – all: all of the above You might want to consider setting parameter FG_ELEV_CACHE to False in case you build a huge area due to disk usage.

4.5 Consider Sharing Your Generated Scenery Objects

Although this guide hopefully helps, not everybody might be able to generate scenery objects wih osm2city related programs. Therefore please consider sharing your generated scenery objects. You can do so by announcing it in the Sceneries part of the FlightGear Forums and linking from the bottom of the osm2city related Wiki article.

4.5. Consider Sharing Your Generated Scenery Objects 23 osm2city Documentation, Release 1.0

24 Chapter 4. Scenery Generation [Builder] CHAPTER 5

Parameters [Builder]

Please consider the following: • Python does not recognize operating system environment variables, please use full paths in the parameters file (no $HOME etc). • These parameters determine how scenery objects are generated offline as described in chapter Scenery Genera- tion. • All decimals need to be with “.” — i.e. local specific decimal separators like “,” are not accepted. • Unless specified otherwise then all length is in metres and areas are in square metres. • You do not have to specify all parameters in your params.py file. Actually it is better only to specify those parameters, which you want to actively control — the rest just gets the defaults.

5.1 View a List of Parameters

The final truth about parameters is stored in parameters.py — unfortunately the content in this chapter of the manual might be out of date (including default values). It might be easiest to read parameters.py directly. Python code is easy to read also for non-programmers. Other- wise you can run the following to see a listing:

/usr/bin/python3/home/vanosten/develop_vcs/osm2city/parameters.py-d

If you want to see a listing of the actual parameters used during scenery generation (i.e. a combination of the defaults with the overridden values in your params.py file, then you can run the following command:

/usr/bin/python3--file/home/pingu/development/osm2city/parameters.py-f LSZS/params.

˓→py

25 osm2city Documentation, Release 1.0

5.2 Important Parameters

5.2.1 Minimal Set

See also Setting a Minimal Set of Parameters.

Pa- Type De- Description / Example ram- fault eter PRE- String n/a Name of the scenery project. Do not use spaces in the name. FIX PATH_TO_SCENERYPath n/a Full path to the scenery folder without trailing slash. This is where we will probe elevation and check for overlap with static objects. Most likely you’ll want to use your TerraSync path here. PATH_TO_SCENERY_OPTList None Optional additional paths to scenery folders (e.g. for Project3000). Specified as a list of strings (e.g. [‘/foo/uno’, ‘/foo/due’]. Only used for overlap checking for buildings against static and shared objects. PATH_TO_OUTPUTPath n/a The generated scenery (.stg, .ac, .xml) will be written to this path. If empty then the correct location in PATH_TO_SCENERY is used. Note that if you use TerraSync for PATH_TO_SCENERY, you MUST choose a different path here. Otherwise, TerraSync will overwrite the generated scenery. Unless you know what you are doing, there is no reason not to specify a dedicated path here. While not absolutely needed it is good practice to name the output folder the same as PREFIX. PATH_TO_OSM2CITY_DATAPath n/a Full path to the folder with osm2city-data. See chapter Installation of osm2city (e.g. “/home/user/osm2city-data”). FG_ELEVString n/a Points to the full path of the fgelev executable. On Linux it could be something like . ../bin/fgfs_git/next/install/flightgear/bin/fgelev'. On Windows you might have to put quotes around the path due to whitespace e.g. '"D:/Program Files/FlightGear/bin/Win64/fgelev.exe"'. PROBE_FOR_WATERBooleanFalse Checks the scenery in PATH_TO_SCENERY whether points are in the water or not. The FlightGear scenery’s water boundaries might be different from OSM. E.g. removes build- ings if at least one corner is in the water. And removes or splits (parts of) roads/railways, if at least 1 point is in the water. Only possible with FGElev version after 9th of November 2016 / FG 2016.4.1.

26 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

5.2.2 Important Flags

Pa- Type De- Description / Example rame- fault ter FLAG_COLOUR_TEXBooleanFalse Experimental code. If True then the texture and OSM tags can use colouring. For later versions of FlightGear (2019.x?). FLAG_STG_BUILDING_LISTBooleanFalse If True then some buildings use the Random Building code in FlightGear instead of a building mesh, which reduces scenery size and can help with rendering performance. BUILD- BooleanFalse Use a shared model for worship buildings instead of OSM floor plan and heuristics. The ING_USE_SHARED_WORSHIPshared models will try to respect the type of building (e.g. church vs. mosque) and will in size (not height) respect the convex hull of the building floor plan in OSM. If the building is composed of several parts as in OSM 3D buildings, then no shared models are used - as it is assumed that the 3D modeling is more realistic (e.g number and height of towers) than a generic model, although the facade texture is more dumb than a typical shared model texture. NO_ELEVBooleanFalse The only reason to set this to True would be for scenery builders to check generated scenery objects a bit faster not caring about the vertical position in the scenery.

5.3 Buildings

5.3.1 Diverse Parameters

Parameters which influence the number of buildings from OSM taken to output.

Parameter Type De- Description / Example fault BUILD- Num- 0.0 Minimum height from bottom to top without roof height of a building to be included ING_MIN_HEIGHTber in output (does not include roof). Different from OSM tag “min_height”, which states that the bottom of the building hovers min_height over the ground. If set to 0.0, then not taken into consideration (default). BUILD- Num- 50.0 Minimum area for a building to be included in output (not used for buildings with ING_MIN_AREAber parent). BUILD- Num- 10.0 Minimum area for building:parts. ING_PART_MIN_AREAber BUILD- Num- 200.0 Threshold area of a building below which a rate of buildings gets reduced from ING_REDUCE_THRESHOLDber output. BUILD- Num- 0.5 Rate (between 0 and 1) of buildings below a threshold which get reduced randomly ING_REDUCE_RATEber in output. BUILD- BooleanFalse Before removing a building due to area, check whether it is touching another build- ING_REDUCE_CHECK_TOUCHing and therefore should be kept. BUILD- In- 6 Buildings that tall will never be removed in removing. ING_NEVER_REDUCE_LEVELSte- ger BUILD- In- 0 For BUILDING_LIST buildings, distance within which buildings will tend to have ING_TEXTURE_GROUP_RADIUS_Mte- the same texture (e.g. in the UK, Netherlands). Heuristics are only used if value > ger 0. A typical value would be around 2000.

In order to reduce the total number of nodes of the buildings mesh and thereby reducing both disk space volume and rendering demands as well as to simplify the rendering of roofs, the geometry of buildings is simplified as follows:

5.3. Buildings 27 osm2city Documentation, Release 1.0

• Only if not part of a building parent • Only if no inner circles • Only if a multiple of 4 nodes gets reduced and always 4 neighbouring points are removed at the same time (e.g. something that looks like a balcony from above, but can also point inwards into the building) • If points get removed, which are also part of a neighbour building, then the simplification is not accepted. • The tolerance of the below parameters is respected.

Parameter Type De- Description / Example fault BUILD- Num- 1.0 The point on the base line may at most be this value away from the straight line ING_SIMPLIFY_TOLERANCE_LINEber between the node before the balcony and the node after the balcony. This in order to prevent that e.g. a stair-case feature is removed. BUILD- Num- 2.5 The 2 points sticking out (or in) may not be more than this value away from the ING_SIMPLIFY_TOLERANCE_AWAYber straight line between the node before the balcony and the node after the balcony. This in order to prevent clearly visible “balconies” to be removed.

5.3.2 Level of Details of Buildings

The more buildings you have in LOD detailed, the less resources for rendering are used. However you might find it “irritating” the more buildings suddenly appear. Experiment with the settings in FlightGear, see also Adjusting Visibility of Scenery Objects.

Parameter Type De- Description / Example fault LOD_ALWAYS_DETAIL_BELOW_AREAInte- 150 Below this area, buildings will always be LOD detailed ger LOD_ALWAYS_ROUGH_ABOVE_AREAInte- 500 Above this area, buildings will always be LOD rough ger LOD_ALWAYS_ROUGH_ABOVE_LEVELSInte- 6 Above this number of levels, buildings will always be LOD ger rough LOD_ALWAYS_DETAIL_BELOW_LEVELSInte- 3 Below this number of levels, buildings will always be LOD ger detailed LOD_PERCENTAGE_DETAIL Deci- 0.5 Of the remaining buildings, this percentage will be LOD de- mal tailed, the rest will be LOD rough.

5.3.3 Building Levels and Height

In OSM the height of a building can be described using the following keys: • building:height • roof:height • height (the total of building_height and roof_height, but most often used alone) • building:levels • roof:levels (not used in osm2city) • levels

28 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

Most often none of these features are tagged and then the number of levels are determined based on the settlement type and the corresponding BUILDING_NUMBER_LEVELS_* parameter. The height is always calculated as the product of the number of levels times parameter BUILDING_LEVEL_HEIGHT_*. If only the height is given, then the levels are calculated by simple rounding — and this level value is then used for calculating the height. The reason for this is that some uniformity in building heights/values is normally observed in the real world — and because the generic textures used have a defined height per level. An exception to this is made for building parts in a relationship (Simple 3D buildings), as the heights in this case might be necessary to be correct (e.g. a dome on a church). There is some randomness about the number of levels within the same settlement type, which is determined by using a dictionary of level=ratio pairs, like:

BUILDING_NUMBER_LEVELS_CENTRE={4: 0.2,5: 0.7,6: 0.1} meaning that there is a ratio 0f 0.2 for 4 levels, a ratio of 0.7 for 5 levels and a ratio of 0.1 for 6 levels. I.e. the keys are integers for the number of levels and the values are the ratio, where the sum of ratios must be 1.

Param- Type De- Description / Example eter fault BUILD- Dict . A dictionary of level/ratio pairs per settlement type, which is used when a building ING_NUMBER_LEVELS_*does not contain information about the number of levels. If the building class is not residential or residential_small and the settlement type is not centre or block, then specific parameters are used for apartments, industrial/warehouse and oth- ers.

5.3.4 Visibility Underground Buildings

There seem to be challenges with consistency etc. in OSM in terms of deciding, whether something is under the ground and therefore osm2city should not render it. According to findings in the FG Forum and OSM there are different tags used, some of them better suited than others according to OSM documentation: • location=underground or location=indoor seems to be a correct way (key:location) • indoor has also some usage (key:indoor) • tunnel is according to taginfo (taginfo tunnel combinations) used max 1000 times together with buildings • level with negative values. NB: not to be confused with levels and building:levels (see chapter Building Levels and Height) • layer is not to be used to determine visibility (key:layer)

Parameter Type De- Description / Example fault BUILD- BooleanTrue Do not show buildings or building:parts if key location has value ING_UNDERGROUND_LOCATION underground or indoor. BUILD- BooleanTrue Do not show buildings or building:parts if key indoor is present and ING_UNDERGROUND_INDOOR its value is not no. BUILD- BooleanTrue Do not show buildings or building:parts if key tunnel is present and ING_UNDERGROUND_TUNNEL its value is not no. BUILD- BooleanTrue Do not show buildings or building:parts if key level has a negative ING_UNDERGROUND_LEVEL_NEGATIVEvalue and neither key levels or building:levels have a non- negative value.

5.3. Buildings 29 osm2city Documentation, Release 1.0

5.3.5 European Style Inner Cities (Experimental)

Given the available textures in osm2city-data and the in general limited tagging of buildings in OSM as of 201x, European cities look wrong, because there are too many modern facades used and too many flat roofs. The following parameters try to “fix” this by adding OSM-tags roof:colour=red and roof:shape=gabled to all those buildings, which do not have parents or pseudo-parents (i.e. nor relationships or parts in OSM), but which share node references with other buildings. So typically what is happening in blocks in inner cities in Europe.

Parameter Type De- Description / Example fault BUILD- BooleanFalse If True then some OSM tags are enforced to better simulate ING_FORCE_EUROPEAN_INNER_CITY_STYLEEuropean style buildings - especially in inner cities.

Example of using the flag set to True in a part of Prague:

vs. setting it to False (default):

30 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

5.3.6 Roofs on Buildings

Below you will find quite a lot of parameters deciding what type of roofs should be generated on buildings. To understand the basic concepts, you should understand OSM Simple 3D buildings. With complex roof below all those roof types, which are not flat/horizontal are meant. The following parameters decide whether a complex roof should be used on top of a building at all.

5.3. Buildings 31 osm2city Documentation, Release 1.0

Parameter Type De- Description / Example fault BUILD- Bool True Set this to false if only flat roofs should be used. Good for performance, but not so ING_COMPLEX_ROOFS nice for the eye. If this is set to False, all other parameters do not matter. BUILD- In- 1 Don’t put complex roof on buildings smaller than the specified value unless there ING_COMPLEX_ROOFS_MIN_LEVELSte- is an explicit roof:shape flag in OSM. ger BUILD- In- 5 Don’t put complex roofs on buildings taller than the specified value unless there is ING_COMPLEX_ROOFS_MAX_LEVELSte- an explicit roof:shape flag in OSM. ger BUILD- In- 1600 Don’t put complex roofs on buildings larger than this. ING_COMPLEX_ROOFS_MAX_AREAte- ger BUILD- In- 600 If a building is larger than this but smaller than ..._MAX_AREA, then it is com- ING_COMPLEX_ROOFS_MIN_RATIO_AREAte- pared whether the building tends to be small and long, because often on more ger square buildings, which at the same time are large, the roof tends to be flat. BUILD- In- 10 The maximum number of nodes for which a complex roof is generated. The higher ING_SKEL_MAX_NODESte- the number, the longer the execution time but the more houses actually get realistic ger roofs. BUILD- Dict . If the roof:shape tag is missing in OSM (which it most often is), then this ING_ROOF_SHAPE_RATIO parameter can help to make region specific decisions on what roof types are to be applied randomly with a given ratio. The sum of the ratios must give 1.0 and the values must be one of the values defined for RoofShapes in roof.py. BUILD- Num- 0.5 All points in the simplified roof will be within the tolerance distance of the original ING_ROOF_SIMPLIFY_TOLERANCEber geometry.

Finally the following parameters let you play around with how complex roofs are done.

Parameter Type Default Description / Example BUILDING_SKEL_ROOFS_MIN_ANGLEInteger 10 The minimum angle of the roof BUILDING_SKEL_ROOFS_MAX_ANGLEInteger 50 The max angle of the roof. Some randomness is ap- plied between MIN and MAX. BUILDING_SKILLION_ROOF_MAX_HEIGHTDecimal No matter the MIN and 2. MAX angles: a skillion will have at most this height difference. BUILDING_SKEL_ROOF_MAX_HEIGHTDecimal Skip skeleton roofs 6. (gabled, pyramidal, ..) if the roof height is larger than this value.

5.3.7 Overlap Check for Buildings and Roads

Overlap checks try to omit overlap of buildings generated based on OSM data with static object as well as shared objects (depending on parameter OVERLAP_CHECK_CONSIDER_SHARED) in the default scenery (defined by PATH_TO_SCENERY). If parameter PATH_TO_SCENERY_OPT is not None, then also object from that path are considered (e.g. for Project3000).

32 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

Parame- Type De- Description / Example ter fault OVER- Bool True Reads all points from static (or shared) objects and creates a convex hull around all LAP_CHECK_CONVEX_HULLpoints. This is a brute force algorithm only taking into account the firsts object’s ver- tices. OVER- Dec- 0.0 Buffer around static objects to extend the overlap area. In general convex hull is already LAP_CHECK_CH_BUFFER_STATICi- a conservative approach, so using 0 (zero) should be fine. mal OVER- Dec- 0.0 Same as above but for shared objects. LAP_CHECK_CH_BUFFER_SHAREDi- mal OVER- Bool True Whether only static objects (i.e. a unique representation of a real world thing) should LAP_CHECK_CONSIDER_SHAREDbe taken into account — or also shared objects (i.e. generic models reused in different places like a church model). For this to work PATH_TO_SCENERY must point to the TerraSync directory. OVER- List None At airports in list include overlap check with pavement for buildings. Pavements are LAP_CHECK_APT_PAVEMENT_BUILDINGS_INCLUDEe.g. APRON and taxiways. If the list is empty, then checks at all airports are done. If the value is None, then overlap check is done only against runways and helipads. OVER- List None Ditto for roads and railways. E.g. ['ENAT', 'LSZR'] LAP_CHECK_APT_PAVEMENT_ROADS_INCLUDE OVER- List [] Instead of data from apt.dat use FG scenery data in BTG files. This is a LAP_CHECK_APT_USE_BTG_ROADSbit slower, but might be more accurate than apt.dat data, especially if airports in the scenery used use additional data not in apt.dat. If this is None, then .._APT_PAVEMENT_ROADS_INCLUDE is used. Otherwise only BTG data is used if the list is empty ([] = default) or if the current airport is in the list - e.g. ['YSSY']. OVER- Bool False Add OSM data for APRONs to overlap check. Rarely necessary. LAP_CHECK_APT_USE_OSM_APRON_ROADS OVER- In- 10 When a static bridge model or other blocked area (e.g. airport object) intersect with a LAP_CHECK_ROAD_MIN_REMAININGte- way, how much must at least be left so the way is kept after intersection. ger OVER- List None Areas blocked for placing buildings. It is a list of polygons defining the areas to ex- LAP_CHECK_EXCLUDE_AREAS_BUILDINGSclude. Each polygon is a list of lon/lat coordinates, where the last element automati- cally connects to the first element to close the polygon. The coordinate points must be defined counter-clock wise. This is a last resort to handle situations, where the built in mechanism cannot handle especially static elements, because their geometry is not clearly handled when interpreting the corresponding ac-file. See example below the table for PHNL. OVER- List None Ditto for roads. Often they will be the same - but not always. LAP_CHECK_EXCLUDE_AREAS_ROADS

Examples of overlap objects based on static objects at LSZS (light grey structures at bottom of buildings):

5.3. Buildings 33 osm2city Documentation, Release 1.0

An example of difficult to handle situations is PHNL (Hawaii), where several objects inside the ac-file have rotations. The picture below shows the blocked areas (green) automatically detected. E.g. the large green area top left is a static object for the Admiral Bernard Chick Clarey Bridge. At the PHNL airport the green stripes parallel to the runway should actually be rather large areas covering most of the hangar areas of the airport.

34 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

The next image shows the blocked areas by parameter as well as the code to define these areas. There are at least two problems with this: (a) such issues cannot be detected automatically and (b) it is tedious and error prone to define these polygons. This is more a proof of concept and a “hack” for PHNL than anything else.

5.3. Buildings 35 osm2city Documentation, Release 1.0

Remark in the parameters below that for roads only the bridge has been excluded - that is because it has been tested visually (again: tedious and slow).

_admiral_clarey_bridge=[(-157.953, 21.3693), (-157.953, 21.3671), (-157.9356, 21.

˓→3690), (-157.9346, 21.3711)] _phnl_airport=[(-157.9015, 21.3354), (-157.9264, 21.3393), (-157.9272, 21.3347), (-

˓→157.9459, 21.3393), (-157.9516, 21.3331), (-157.9558, 21.3371), (-157.9589, 21.3373), (-

˓→157.9694, 21.3287), (-157.9503, 21.3038), (-157.9048, 21.3040)] OVERLAP_CHECK_EXCLUDE_AREAS_ROADS= [_admiral_clarey_bridge] OVERLAP_CHECK_EXCLUDE_AREAS_BUILDINGS= [_admiral_clarey_bridge, _phnl_airport]

5.3.8 Rectify Buildings

Rectifies angles of corners in buildings to 90 degrees as far as possible (configurable). This operation works on existing buildings as mapped in OSM. It corrects human errors during mapping, when angles are not straight 90 degrees (which they are in reality for the major part of corners). I.e. there is no new information added, only existing information corrected.

36 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

This operation is mainly used for eye-candy and to allow easier 3-D visualization. It can be left out if you feel that the OSM mappers have done a good job / used good tooling. On the other hand the processing time compared to other operations is negligible. The following picture shows an example of a rectified building with a more complex layout. The results are more difficult to predict the more corners there are. The red line is the original boundary, the green line the rectified boundary. Green circles are at corners, where the corner’s angle is different from 90 degrees but within a configurable deviation (typically between 5 and 10 degrees). Corners shared with other buildings are not changed by the rectify algorithm (not shown here).

Please note that if you are annoyed with angles in OSM, then you have to rectify them manually in OSM. One way to do that is to use JOSM and related plugins.

5.3. Buildings 37 osm2city Documentation, Release 1.0

Parameter Type De- Description / Example fault REC- BooleanTrue Toggle whether the rectify operation should be used. TIFY_ENABLED REC- Num- 0.1 Small tolerance from 90 degrees not leading to rectification of corner. TIFY_90_TOLERANCEber REC- Num- 7 By how much an angle can be smaller or larger than 90 to still be rectified. You might TIFY_MAX_90_DEVIATIONber need to experiment a bit and use plotting to determine a good value. REC- Num- 20 How many randomly chosen buildings having rectified corners shall be plotted. The TIFY_MAX_DRAW_SAMPLEber more buildings the better for comparison. However plotting can take quite some time and system resources. REC- BooleanTrue If set to True then the randomizer uses a different seed each time. In some situations TIFY_SEED_SAMPLE it might be better when the same set of random buildings are plotted each time - e.g. when experimenting with parameters and wanting to compare the outcomes.

5.3.9 Light Effects on Buildings

Parameters for some light effects.

Parameter Type Default Description / Example OBSTRUCTION_LIGHT_MIN_HEIGHTInteger 150 Puts red obstruction lights on buildings >= the speci- fied number levels. If you do not want this, then just set the value to 0. The official FAA source spec- ifies 499 feet (153 m) as a rule. BUILDING_FAKE_AMBIENT_OCCLUSIONBoolean True Fake ambient occlusion by darkening facade tex- tures towards the ground, using the formula 1 - VALUE * exp(- AGL / HEIGHT ) during texture atlas generation. BUILDING_FAKE_AMBIENT_OCCLUSION_HEIGHTNumber (see above) 6.

BUILDING_FAKE_AMBIENT_OCCLUSION_VALUENumber 0.6 (see above)

5.3.10 Generating Buildings Where OSM is Missing Buildings

It is possible to let osm2city generate buildings, where it is plausible that there in reality would be buildings, but buildings were not mapped in OSM. The following set of parameters make some customisation to specific areas possible. However parts of the processing is rather hard-coded (e.g. the available buildings are defined in code in module owbb/would_be_buildings.py in function _read_building_models_library(). Still the results are much better than an empty scene. No additional buildings are generated inside zones for aerodromes. A lot of processing is dependent on land-use information (see e.g. Land-use Handling and Land-use Parameters). For a short explanation of the process used see Generate Would-Be Buildings.

38 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

In settlement areas an attempt is made to have the same terrace houses or apartment buildings along both sides of a way. The first set of parameters determines the overall placement heuristics:

Parameter Type De- Description / Example fault OWBB_GENERATE_BUILDINGSBooleanFalse Set this to True to generate buildings. OWBB_USE_GENERATED_LANDUSE_FOR_B.._GENERATIONBooleanFalse Generated land use is based on existing OSM buildings but missing land-use information. Therefore there is a fair chance that no additional buildings are plausible. OWBB_USE_EXTERNAL_LANDUSE_FOR_B.._GENERATIONBooleanTrue External land-use is only added, where OSM is missing and no generated land-use is available. Currently this only land-use from FlightGear (param- eter OWBB_USE_BTG_LANDUSE), which is why most probably plausible buildings should be generated. OWBB_STEP_DISTANCEIn- 2 How many meters along the way to travel before trying to set a building te- again. Smaller values might be more accurate, but also increase processing ger time. OWBB_MIN_STREET_LENGTHIn- 10 How long a way needs to be at least to be considered for generating buildings te- along. ger OWBB_MIN_CITY_BLOCK_AREAIn- 200 The minimal area of a city block along a way to be considered for generating te- buildings. ger OWBB_RESIDENTIAL_HIGHWAY_MIN_GEN_SHAREDec- 0.3 If there are already buildings along the way: what is the minimal share of i- an uninterrupted length along the way to consider for terraces or apartments mal (detached houses might still be “built”). OWBB_ZONE_AREA_MAX_GENDec- 0.1 If the share of floor area of exiting OSM buildings compared to the whole i- area is above this value, then no extra buildings are placed. In the future this mal value might need to be specific per settlement type. OWBB_HIGHWAY_WIDTH_FACTORDec- 1.3 Factor applied to highway width in order to push buildings exponential more i- away from high level highways (highway.width ** factor) mal

The second set of parameters determines the type of residential buildings to use and the distances between the buildings and the street as well as what happens in the backyard. The width of a building is along the street, the depth of a building is away from the street (front door to back door).

5.3. Buildings 39 osm2city Documentation, Release 1.0

Parame- Type De- Description / Example ter fault OWBB_RESIDENTIAL_RURAL_TERRACE_SHAREDec- 0.1 The share of terraces / row houses in rural settlement areas. Most houses are detached, i- which is the default. mal OWBB_RESIDENTIAL_PERIPHERY_TERRACE_SHAREDec- 0.25 Ditto in periphery settlement areas. i- mal OWBB_RESIDENTIAL_RURAL_APARTMENT_SHAREDec- 0.1 The share of apartment buildings in rural settlement areas. i- mal OWBB_RESIDENTIAL_PERIPHERY_APARTMENT_SHAREDec- 0.3 Ditto in periphery settlement areas. i- mal OWBB_RESIDENTIAL_DENSE_TYPE_SHAREDict In dense areas not everything is attached like in block or centre settlement areas. It can be quite region specific. Therefore there is quite a choice for specifying the distribution. E.g. {'detached': 0.1, 'terraces': 0.1, 'apartments': 0. 3, 'attached': 0.5}. OWBB_RESIDENTIAL_TERRACE_MIN_NUMBERIn- 4 The minimum number of terrace houses to fit along a street before it is considered to te- build terraces along the way. ger OWBB_RESIDENTIAL_TERRACE_TYPICAL_NUMBERIn- 5 The typical number of terrace houses attached to each other before there will be a break. te- The actual number is randomized around this value. ger OWBB_RESIDENTIAL_SIDE_FACTOR_PERIPHERYDec- 1.0 The default buffer on the side of detached houses and apartment houses is the sqaure i- root of the house’s width. So the distance between two houses gets the square root mal of the one house’s width plus the square root of the other house’s width. This factor is multiplied to allow some linear correction for region specific adaptation. E.g. in Switzerland the houses tend to be farther apart along the street than in Denmark (the opposite is true for the backyard). This factor is used for rural and periphery settlement types. OWBB_RESIDENTIAL_SIDE_FACTOR_DENSEDec- 0.8 Ditto for dense settlement type. Attached houses and terrace houses have a distance of i- ca. 0 (it is not exactly 0 due to the way placements are made in the heuristics - but close mal enough; you can play with the step distance). OWBB_RESIDENTIAL_BACK_FACTOR_PERIPHERYDec- 2.0 Same as the ..SIDE_FACTOR.., but now for the back. Again the starting point is a i- square root - this time of the building’s depth. mal OWBB_RESIDENTIAL_FRONT_FACTOR_PERIPHERYDec- 1.0 Same as the ..SIDE_FACTOR.., but now for the back. The starting point is the square i- root of the building’s width. mal OWBB_FRONT_DENSEDec- 3.0 The distance in metres between the street and the front. Same for settlement types i- dense, block and centre. mal

Finally a set of parameters for industrial buildings:

40 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

Parameter Type De- Description / Example fault OWBB_INDUSTRIAL_LARGE_MIN_AREAIn- 500 The minimal number of square metres for an industrial building being consid- te- ered large. ger OWBB_INDUSTRIAL_LARGE_SHAREDec- 0.4 If the building zone type is industrial, then this share is used between large i- buildings and smaller buildings. mal OWBB_INDUSTRIAL_BUILDING_SIDE_MINDec- 2.0 The minimal buffer around a building - so the total distance between two in- i- dustrial buildings is at least twice this value. The actual value used is chosen mal randomly between the .._SIDE_MIN and .._SIDE_MAX. OWBB_INDUSTRIAL_BUILDING_SIDE_MAXDec- 5.0 See above. i- mal

5.4 Linear Objects (Roads, Railways)

Parameters for roads, railways and related bridges. One of the challenges to show specific textures based on OSM data is to fit the texture such that it drapes ok on top of the scenery. Therefore several parameters relate to enabling proper draping.

5.4. Linear Objects (Roads, Railways) 41 osm2city Documentation, Release 1.0

Parameter Type Default Description / Example BRIDGE_MIN_LENGTH Decimal Discard short bridges and 20. draw roads or railways in- stead. MIN_ABOVE_GROUND_LEVELDecimal 0.1 How much a highway / railway is at least hovering above ground DISTANCE_BETWEEN_LAYERSDecimal 0.2 How much different lay- ers of roads/railways at the same node are sepa- rated. MIN_EMBANKMENT_HEIGHTDecimal 0.4 How much extra eleva- tion compared to ground (v_add) there is, before an embankment is added at the side(s). This happens especially in bumpy areas and for roads along a steep hill side. MAX_TRANSVERSE_GRADIENTDecimal 0.1 If the difference between the elevation at the right edge of a road and the el- evation at the left edge of the road divided by the width of the road is larger than the gradient, then the road surface is levelled by adding v_add. Otherwise it is accepted that the road is a bit sloped from left to right. HIGHWAY_TYPE_MIN Integer 4 The lower the number, the smaller ways in the high- way hierarchy are added. Currently the numbers are as follows (see roads.py - > HighwayType). motor- way = 12 trunk = 11 pri- mary = 10 secondary = 9 tertiary = 8 unclassified = 7 road = 6 residential = 5 living_street = 4 service = 3 pedestrian = 2 slow = 1 (cycle ways, tracks, foot- paths etc). POINTS_ON_LINE_DISTANCE_MAXInteger 1000 The maximum distance between two points on a line. If longer, then new points are added. This parameter might need to get set to a smaller value in order to have enough elevation probing along a road/highway. Together with parameter 42 Chapter 5.MIN_ABOVE_GROUND_LEVEL Parameters [Builder] it makes sure that fewer residuals of ways are below the scenery ground. The more uneven a scenery ground is, the smaller this value should be chosen. The drawback of small values are that the number of faces gets bigger affecting frame rates. MAX_SLOPE_ROAD Decimal 0.15 The maximum allowed slope. It is used for ramps to bridges, but it is also used for other ramps. Es- pecially in mountainous areas you might want to set higher values. This leads to steeper ramps to bridges, but give much fewer residuals with em- bankments. MAX_SLOPE_MOTORWAYDecimal 0.07 (ditto) for motorways. It is seldom that motorways have lopes more than 0.04, but e.g. in Switzer- land there are places with over 6% - e.g. A12. MAX_SLOPE_RAILWAY Decimal 0.08 (ditto) for railways. With adhesion only railways are along motorways in terms of max slopes. MAX_SLOPE_TRAM Decimal 0.14 (ditto) for trams, which also use adhesion, but can be steeper. MAX_SLOPE_RACK Decimal 0.49 For railways with racks the steepest is Pila- tus Railway with 48% incline. USE_TRAM_LINE Boolean False Often tram lines are on top of existing roads or between. This can lead to roads being (partially) hidden etc. osm2city Documentation, Release 1.0

With residuals:

After adjusted MAX_SLOPE_* and POINTS_ON_LINE_DISTANCE_MAX parameters:

5.5 Land-Use

Land-use data is only used for built-up area in osm2city. All other land-use is per the scenery in FlightGear. The main use of the land-use information processed is to determine building types, building height etc. for those buildings (often the majority), where this information is lacking and therefore must be obtained by means of heuristics. See Land-use for an overall description.

Parameter Type De- Description / Example fault OWBB_LANDUSE_CACHEBooleanFalse Instead of calculating land-use related stuff including buildings from scratch each time, use cached (but possibly stale) data for speed-up.

5.5. Land-Use 43 osm2city Documentation, Release 1.0

5.5.1 Complement OSM Land-Use Information

These operations complement land-use information from OSM based on some simple heuristics, where there currently are no land-use zones for built-up areas in OSM: If there are clusters of buildings outside of registered OSM land-use zones, then zones are added based on clusters of buildings and buffers around them. The land-use type is based on information of building types, amenities etc. — if available.

Parameter Type De- Description / Example fault OWBB_USE_BTG_LANDUSEBooleanFalse Read FlightGear scenery (BTG-files from existing TerraSync scenery) for land-use data to complement (not replace) data from OSM. OWBB_GENERATE.. . _BUILDING_BUFFER_DISTANCENum- 30 The minimum buffering distance around a building. ber OWBB_GENERATE.. . _BUILDING_BUFFER_DISTANCE_MAXNum- 50 The maximum buffering distance around a building. The actual value is a ber function of the previous parameter and the building’s size (the larger the building the larger the buffering distance - up to this max value. OWBB_GENERATE_LANDUSE_LANDUSE_HOLES_MIN_AREANum- 20000 The minimum area for a hole within a generated land-use that is kept as a ber hole (square metres). OWBB_GENERATE.. . _SIMPLIFICATION_TOLERANCENum- 20 The tolerance in metres used for simplifying the geometry of the gener- ber ated land-use boundaries. Tolerance means that all points in the simplified land-use will be within the tolerance distance of the original geometry. OWBB_SPLIT_MADE_UP_LANDUSE_BY_MAJOR_LINESBooleanTrue Splits generated land-use by major lines, as typically land-use changes occur across larger boundaries. “Major lines” here are motorways, most railways (not trams) and waterways classified in OSM as rivers and canals.

On the left side of the picture below the original OSM-data is shown, where there only is one land-use zone (green), but areas with buildings outside of land-use zones as well as several streets without buildings (which from an arial picture actually have lots of buildings — they have just not been mapped in OSM. On the right side of the picture the pink areas are generated based on building clusters and the yellow zone is from CORINE data.

5.5.2 Generating Areas Where Roads are Lit

Land-use information is used to determine which roads are lit during the night (in addition to those roads which in OSM are explicitly tagged as being lit). The resulting built-up areas are also used for finding city and town areas — another reason why the values should be chosen conservative, i.e. large.

44 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

Parameter Type De- Description / Example fault OWBB_BUILT_UP_BUFFERNum- 50 The buffer distance around built-up land-use areas to be used for lighting of streets. ber The number is chosen pretty large such that as many building zone clusters as possible are connected. Also it is not unusual that the lighting of streets starts a bit outside of a built-up area. OWBB_BUILT_UP_AREA_HOLES_MIN_AREANum- 100000The minimum area in square metres a hole in a LIT_BUFFER needs to have to be ber not lit. In general this can be quite a large value and larger than e.g. parameter OWBB_GENERATE_LANDUSE_LANDUSE_HOLES_MIN_AREA. OWBB_BUILT_UP_MIN_LIT_AREANum- 100000The minimum area of a lit area, such that it is actually used for lighting of streets. ber Given buffering with OWBB_BUILT_UP_BUFFER alone is already a large area, this value must not be chosen too small.

5.5.3 Size of Concentric Settlement Type Rings

The formula for the radius of the outer border of the ring is: radius= population^OWBB_PLACE_RADIUS_EXPONENT * OWBB_PLACE_RADIUS_FACTOR

5.5. Land-Use 45 osm2city Documentation, Release 1.0

Parameter Type Default Description / Example OWBB_PLACE_POPULATION_DEFAULT_CITYInteger 200000 The default population for a settlement tagged with place=city, where the population size is not tagged. OWBB_PLACE_POPULATION_DEFAULT_TOWNInteger 20000 Ditto for place=town. OWBB_PLACE_POPULATION_MIN_BLOCKInteger 15000 The minimum amount of people living in a place=town for it to have a settlement type block (i.e. where all builings are attached). If the population is based on default, then no block will be assigned. OWBB_PLACE_RADIUS_EXPONENT_CENTRENumber 0.5 The exponent for calculat- ing the radius for settle- ment type centre, i.e. 1/2. OWBB_PLACE_RADIUS_EXPONENT_BLOCKNumber 0.6 Ditto for type block, i.e. 5/8. OWBB_PLACE_RADIUS_EXPONENT_DENSENumber 0.666 Ditto for type dense, i.e. 2/3. OWBB_PLACE_RADIUS_FACTOR_CITYNumber Linear correction factor 1. for radius when dealing with place=city. OWBB_PLACE_RADIUS_FACTOR_TOWNNumber Ditto for place=town. 1.

OWBB_PLACE_TILE_BORDER_EXTENSIONInteger 10000 Extension of the perimeter (tile borders) to read place information from, as e.g. a city might extend across til border areas. OWBB_PLACE_CHECK_DENSITYBoolean False Should only be used if majority of all buildings are mapped in OSM. Otherwise settlement type will be downgraded e.g. in areas based on BTG etc. Mostly for testing purposes and prrof of concept. OWBB_PLACE_SANITY_DENSITYNumber 0.15 Make sure that settlement type dense is assigned, if the density of a build- ing zone is larger than a given ratio and the set- tlement type is rural or periphery. The density is calculated as the to- tal of all buildings’ floor area (inner rings’ areas do also count) divided by 46 Chapter 5.the Parameters area of the [Builder] building zone. Likewise if the density is lower than the ratio, but the settlement type is dense or block (not centre), then the type is changed to periphery. osm2city Documentation, Release 1.0

5.6 Textures

Parameter Type De- Description / Example fault AT- String (empty)Add the the suffix to the texture atlas (also light-map) in osm2city-data including LAS_SUFFIX an underscore (e.g. ‘foo’ leads to atlas_facades_foo.png). TEX- List [] List of roof file names to exclude, e.g. [“roof_red3.png”, “roof_orange.png”]. TURES_ROOFS_NAME_EXCLUDEThe file names must be relative paths to the tex.src directory within PATH_TO_OSM2CITY_DATA. Be aware the excluding roofs can lead to indirectly excluding facade textures, which might be depending on provided roof types. An empty list means that no filtering is done. TEX- List [] Same as TEXTURES_ROOFS_EXCLUDE but for facades — e.g. TURES_FACADES_NAME_EXCLUDE[“de/commercial/facade_modern_21x42m.jpg”]. TEX- List [] List of provided features for roofs to exclude, e.g. [“colour:red”]. TURES_ROOFS_PROVIDE_EXCLUDE TEX- List [] Ditto for facades. TURES_FACADES_PROVIDE_EXCLUDE TEX- List [] Explicit list of regions to include. If list is empty, then all regions are accepted. There TURES_REGIONS_EXPLICITis also a special region “generic”, which corresponds to top directory structure. In many situations it might not make sense to include “generic”, as it provides a lot of colours etc. (which however could be filtered with the other parameters). TEX- In- 35 If a texture does not have an explicit light-map (i.e. same file name plus “_LM”, then TURES_EMPTY_LM_RGB_VALUEte- a default light-map is constructed with RGB(VALUE, VALUE, VALUE). ger

5.7 Other Parameters

5.7.1 Detailed Features

The following parameters determine, whether specific features for procedures pylons respectively details will be generated at all.

5.6. Textures 47 osm2city Documentation, Release 1.0

Parameter Type De- Description / Example fault C2P_PROCESS_POWERLINESBooleanTrue pylons: Generate electrical power lines (incl. cables) C2P_PROCESS_WIND_TURBINESBooleanTrue pylons: wind turbines C2P_PROCESS_STORAGE_TANKSBooleanTrue pylons: Storage tanks either mapped as nodes or ways in OSM C2P_PROCESS_CHIMNEYSBooleanTrue pylons: Chimneys either mapped as nodes or ways in OSM C2P_PROCESS_TREES BooleanFalse pylons: Trees as per OSM tagging or interpreted in parks, cemeter- ies etc. This works only in FlightGear Next. C2P_PROCESS_POWERLINES_MINORBooleanFalse details: Only considered if C2P_PROCESS_POWERLINES is True C2P_PROCESS_AERIALWAYSBooleanFalse details: Aerial ways is currently experimental and depends on local shared objects. C2P_PROCESS_OVERHEAD_LINESBooleanFalse details: Railway overhead lines (pylons and cables) C2P_PROCESS_STREETLAMPSBooleanFalse details: Always disabled. It would drain your resources in larger sceneries. DE- BooleanTrue details: Generate piers and boats TAILS_PROCESS_PIERS DE- BooleanTrue details: Generate railway platforms TAILS_PROCESS_PLATFORMS

5.7.2 Database

OSM data is read from a PostGIS database. See also OSM Data in Database.

Parameter Type De- Description / Example fault DB_HOST String n/a The host name of the computer running PostGIS (e.g. localhost). DB_PORT Inte- 5432 The port used to connect to the host (5433 for Postgres 9,x+) ger DB_NAME String n/a The name of the database (e.g osmogis). DB_USER String n/a The name of the user to be used to read from the database. Can be read-only. DB_USER_PASSWORD String n/a The password for the DB_USER.

5.7.3 Skipping Specific Buildings and Roads/Railways

There might be situations, when you need to skip certain buildings or roads/railways, because e.g. the overlap checking does not work or the OSM features simply do not fit with the FlightGear scenery. Often it should be checked, whether the OSM data really is correct (if not, then please directly update the source in OSM) or the FlightGear scenery data is not correct (if not, then please check, whether source data can be improved, such that future versions of the scenery are more in line with reality and thereby with OSM data). In order to temporarily exclude certain buildings or roads/railways, you can use parameter SKIP_LIST. For buildings you can either specify the OSM id or (if available) the value of the name tag. For roads/railways only the OSM id can be used. E.g. SKIP_LIST = ['St. Leodegar im Hof (Hofkirche)', 87220999] On the other hand side there might be situations, where certain STG-entries should not be checked for overlap check- ing. For that situation parameter SKIP_LIST_OVERLAP can be used as a list of *.ac or *.xml file names which should not be used for overlap tests

48 Chapter 5. Parameters [Builder] osm2city Documentation, Release 1.0

5.7.4 Clipping Region

The boundary of a scenery as specified by the parameters boundary command line argument is not necessarily sharp. As described in Getting OpenStreetMap Data it is recommended to use completeWays=yes, when manipulat- ing/getting OSM data - this happens also to be the case when using the OSM Extended API to retrieve data. However there are no parameters to influence the processing of OSM nodes and OSM ways depending on whether they are inside / outside the boundary or intersecting. The processing is as follows: • buildings.py: if the first node is inside the boundary, then the whole building is processed — otherwise not • roads.py: if not entirely inside then split at boundary, such that the first node is always inside and the last is either inside by default or the first node outside for splitting. • piers.py: as above for piers • platforms.py: as above for platforms • pylons.py – storage tanks: if the centroid is inside the boundary, then the whole storage tank is processed — otherwise not – wind turbines and chimneys: no checking because the source data for OSM should already be extracted correctly – aerial ways: if the first node is inside the boundary, then the whole aerial way is processed — otherwise not (assuming that aerial ways are short) – power lines and railway overhead lines: as for roads. If the last node was split, then no shared model is placed assuming it is continued in another tile (i.e. optimized for batch processing across tiles)

5.7. Other Parameters 49 osm2city Documentation, Release 1.0

50 Chapter 5. Parameters [Builder] CHAPTER 6

How osm2city Works

osm2city is a set of procedural programs, which together create plausible FlightGear scenery objects (buildings, roads, power lines, piers, platforms etc.) based on OpenStreetMap (OSM) data as well as data already existing in the default FlightGear World Scenery. Plausible means here that the generated scenery should look in a way that a person not knowing the details of a specific location could believe that reality actually looks like that. Or that a person knowing the location would find a fair representation of landmarks and dimensions to find her / his way around in the virtual world. This plausible world is achieved tried to be achieved by using heuristics to interpret the data input and combine it with a set of parameters as well as some randomness. FlightGear and its World Scenery represent almost any location in our world. osm2city attempts to support this. Instead of a set of artists and programmers developing a specific scenery in a confined part of the world, which often means putting a considerable amount of hand-made objects into the scenery and tweaking stuff manually, osm2city uses generic heuristics, models, textures etc. and applies them to any part of the world with some parametrisation. This makes the task to cover the world a bit easier, but of course can only mimic the real world so much. And then there are two twists to what is stated in the previous paragraph: • The scenery generated by osm2city respects the static objects put into the default scenery by diverse Flight- Gear scenery developers around the world — especially airports and landmarks like bridges, worship buildings etc. (see also the FlightGear Scenery Website and the Map over Scenery Models). I.e. the better the specific location is covered by manually created and placed static object, the closer to reality the combination with osm2city generated scenery objects might get. • osm2city generated scenery is only as good as the underlying data. The higher the density and quality of the mapping done in OpenStreetMap, the better the scenery gets. In many parts of the world only a minor share of buildings is mapped at all. Often the only information available are floor plans and generic land-use zones — although the available map features in OSM are abundant and would allow for extreme sophistication (to be fair: this would then again require quite some sophistication in osm2city to consume). In some cities (especially Europe) mappers are using Simple 3D Buildings, which results in nice representations in osm2city, which can come close to hand-crafted models. Remember: FlightGears default scenery is only using freely available (world-wide) data and related freely available scenery objects. And so is osm2city. This data is often not as detailed as commercial products can provide.

51 osm2city Documentation, Release 1.0

6.1 Specific Stuff

Many features are explained in the parameters section. The subchapters below give some additional details.

6.1.1 Elevation and Detection of Water osm2city generated scenery must play nicely with the default FlightGear scenery. This principle is also true if osm2city has access to better data in e.g. OSM. Height above sea level is taken from the FlightGear scenery through some built in functionality in FlightGear (fgelev). The FlightGear scenery is also used to determine, where there is water (the land-use information in FlightGear does sometimes deviate considerably from OSM — up to tens of meters). If PROBE_FOR_WATER is set to True, then buildings and roads are as far as possible not placed into water.

6.1.2 Land-use Handling

Land-use processing is a bit intricate, because OSM data is often insufficient or even lacking. Also for building heuristics it is necessary to have some idea about whether a built-up area is close to a centre and/or the type of area (e.g. village vs. town). To understand the following it is important to first read chapter about Land-use parameters. Once the land-use zone for built-up areas are read from OSM and/or generated (called “building_zones” in the code), lit areas are created by buffering all building zones and then merging as far as possible. These lit areas are not only used to determine, which streets should be lit, but are also used as a settlement clusters for cities and towns. Only settlement areas tagged in OSM with place=city or place=town are considered for further processing of built-up areas, where apartments etc. exist. This is because the rural types are used as default, place=farm is treated specially and values for place like quarter, suburb, neighbourhood do not provide extra information. For city and town feature types Node, Way and Relation are read from OSM, however Way and Relation are reduced to a node by using the area’s centroid. Note that a pre-requisite for this to work is that the mapping in OSM has been done as instructed in Key Place. In a first step all city or town places are linked to lit areas extended with specific water areas1. Then the zones are split into city_block objects, i.e. areas surrounded by streets — some of the polygons will be real city blocks, others will be border areas (the “city” part is not really true here - even a hamlet could in osm2city get divided into several city_blocks). The city blocks take over the land-use type (type can be non-osm if generated and therefore without real meaning). Finally depending on the place type and the distance to the centroid a given city block has, it is assigned one of the following settlement types: • centre: the centre of a city (not available for towns). Max distance = population^(1/2) • block: an area in the center of a city, where streets define blocks, and the buildings within the blocks most often are apartment like buildings, where the facades are aligned with the street and most often buildings are connected. Max distance = population^(5/8). • dense: an area with dense population mostly living in apartments, but the apartment houses are not necessarily connected. Max distance = population^(2/3). • periphery: an area with mostly (detached) houses. Outside of max distance for dense.

1 In cities like Copenhagen, Prague, Amsterdam, New York etc. larger water areas split the city. And that would make it look like the zones on the other side of the water area are not part of the city anymore. To make sure that this is still the case OSM data for water areas (river, canal, moat and riverbank) are added to the clustering to simulate continuous city areas.

52 Chapter 6. How osm2city Works osm2city Documentation, Release 1.0

There is also settlement type rural, which is the default for all those building zones, which re not within a lit area that is linked to a city or town place. In theory the main difference between periphery and rural is the ratio between a property’s lot size and the floor plan, where in rural regions the same family house size typically has more surrounding ground. Please be aware that there is no “science” behind the chosen concentric ring radii and the settlement types. It is just a heuristic / an observation that the farther away from the city centre you get, the less dense the area. Also the settlement area is “some” function of the population (and the commuting workers into a city/town from outside are neglected). Also in some areas of the world densities are higher. This can be corrected with a linear parameter. The population is taken as is from OSM - if missing a parametrised default population is used. The following table shows the resulting radii in metres for some example population sizes:

Place Population Centre Block Dense Town 10 000 n/a 316 464 Town 50 000 n/a 864 1357 City 100 000 316 1334 2154 City 200 000 447 2056 3419 City 1 000 000 1000 5623 10000

I.e. all city blocks linked to building zones are tested against these circles and if intersecting/within, then the most “centric” one is linked to the city block. The following plots illustrate this around tile with 3088986 LSZH, where in most plots the city centre of Zurich is in the lower left corner and the smaller city of Winterthur is in the upper right corner. Lit areas:

6.1. Specific Stuff 53 osm2city Documentation, Release 1.0

Settlement types (blue: centre, green: block, matenta: dense, yellow: periphery, grey: rural, brown: farmyard)

Pattern of city blocks:

54 Chapter 6. How osm2city Works osm2city Documentation, Release 1.0

6.1.3 Generate Would-Be Buildings

This is the core operation of the OWBB library. It generates buildings at probable places based on land-use zones, existing buildings and a set of parameters. At the core of the algorithm all streets within land-use zones are followed and to the left and right spots are searched for, where there would be place for an additional building — the building type being a function of the land-use zone, other buildings, street type and a set of parameters. As an example the following picture shows generated buildings (yellow) based on land-use zones as defined in the previous chapter.

6.1. Specific Stuff 55 osm2city Documentation, Release 1.0

6.1.4 Roofs

The following are some pointers to how roofs work, and in particular code in roofs.py.

Gambrel

Node numbering for gambrel roof type:

56 Chapter 6. How osm2city Works osm2city Documentation, Release 1.0

Gabled Around Edge

There are three situations, where a gabled roof around an edge is done. See also class RoofHints in roofs.py: • A 4-sided building with 4 nodes and 2 adjacent buildings share 1 common node with the building (if there is only one neighbour building or if the 2 neighbours are on each side, then a gabled roof is done). If more than 2 neighbours we would not know what to do. • A somewhat square-shaped building with 5 nodes and 5 sides, where the inner node is shared with a neighbour building. It is a requirement that the inner node is making an angle between 170 and 190 degrees with the previous/next node. Otherwise the roof just gets a skeleton roof. • A L-shaped building with 6 nodes and 6 sides where the inner node is not shared with a neighbour building. If is a requirement that the inner node is making an angle between 80 and 100 degrees with the previous/next node. Otherwise the roof just gets a skeleton roof.

6.1. Specific Stuff 57 osm2city Documentation, Release 1.0

6.1.5 Aerodromes

Data for runways and helipads are depending on parameters read from the apt.dat file in $FG_ROOT/ Airports/apt.dat.gz or directly from btg-files. This information is used to avoid having crossing OSM roads to be visible and potentially creating a considerable bump when a plane rolls over. Data for airport boundaries are also read from the apt.dat file (not all airports have information about boundaries). This data is then merged with OSM data for aeroway=aerodrome (again not all airports might be modelled with a zone). The resulting land-use is making sure that buildings within these zones will look more like airport buildings: using flat roofs (unless the roof type is explicitly modelled in OSM) and using a modern facade texture. Also: no buildings are generated inside zones for aerodromes.

58 Chapter 6. How osm2city Works CHAPTER 7

Appendix

7.1 OSM Data in a PostGIS Database [Builder]

The following chapters are dedicated to give some information and pointers to keeping OSM data in a database instead of files for processing in osm2city. This is not a complete guide and will concentrate on only one possible scenario: PostGIS on Ubuntu Linux. Some overall pointers: • PostGIS on OSM wiki: http://wiki.openstreetmap.org/wiki/PostGIS • Book PostGIS in Action, especially chapter 4.4 of the 2nd edition: http://www.postgis.us/ • PostgreSQL on Ubuntu: https://help.ubuntu.com/community/PostgreSQL • Volker Schatz’s online manual of OSM tools: http://www.volkerschatz.com/net/osm/osmman.html, e.g. osm2pgsql database format and usage. • HStore information in PostgreSQL: https://www.postgresql.org/docs/devel/static/hstore.html • HStore and minutely OSM planet dump info in German: http://wiki.openstreetmap.org/wiki/DE:HowTo_ minutely_hstore

7.2 Developer Information

7.2.1 Documentation

You need to install Sphinx. All documentation is written using reStructuredText and then made available on Read the Docs. Change into docs/manual and then run the following command to test on your local machine:

$ sphinx-build -b html . build

59 osm2city Documentation, Release 1.0

7.2.2 Developing

An unstructured list of stuff you might need to know as a developer: • The code has evolved over time by contributions from persons, who are not necessarily professional Python developers. Whenever you touch or even only read a piece of code, please leave the place in a better state by adding comments with your understanding, refactoring etc. • The level of unit testing is minimal and below what is achievable. There is no system testing. All system testing is done in a visual way - one of the reasons being that the scenery generation has randomising elements plus parametrisation, which means there is not deterministic right solution even from a regression point of view. • Apart from testing the results in FlightGear by flying around with e.g. the UFO, a few operations make use of a parameter DEBUG_PLOT_*, which plots results to a pdf-file: – DEBUG_PLOT_RECTIFY: Examples of rectified building floor plans – DEBUG_PLOT_GENBUILDINGS: Result of generating buildings – DEBUG_PLOT_LANDUSE: Different aspects of land-use – DEBUG_PLOT_ROADS: Different plots for aspects of roads processing – DEBUG_PLOT_OFFSETS: Showing offsets when placing rectangle (utility function) • Use an editor, which supports PEP 08. However the current main developer prefers a line length of 120 instead. You should be able to live with that. • Use Python type hints as far as possible — and help improve the current situation. It might make the code a bit harder to read, but it gets so much easier to understand. • Try to stick to the Python version as referenced in requirements.txt (cf. Python). • All code in utf-8. On Windows please make sure that line endings get correct in git (core.autocrlf) • Coordinate systems: – FlightGear uses a set of different coordinate systems. The most important for referencing models in stg- files is WGS84, which uses lon/lat. In the Cartesian coordinate system in a tile +X is North, +Y is East and +Z is up. – OSM references WGS84 as the datum. – The Ac3D format uses x-axis to the right, y-axis upwards and z-axis forward, meaning that the bottom of an object is in x-z space and the front is in x-y. I.e. a right-handed coordinate system. – osm2city uses a local cartesian coordinate system in meters close enough for measurements within a tile, where x is lon-direction and y is lat-direction. The object height is then in z-direction (see module utils/ coordinates.py). I.e. x pointing to the right and y pointing inwards in a right-handed coordinate system. Meaning the bottom of an object i in x-y space. Therefore a node in the local (cartographic) coordinate system gets translated as follows to a node in a AC3D object in osm2city: x_ac3d = - y_local, y_ac3d = height_above_ground, z_ac3d = - x_local Indices and tables: • genindex • modindex • search

60 Chapter 7. Appendix