Using the Custom Scenery TerraGear Toolset

From FlightGear wiki
Revision as of 19:15, 8 October 2008 by Fg (talk | contribs)
Jump to navigation Jump to search

See also TerraGear

Using TerraGear with the Custom Scenery Project Toolset

This document describes the most efficient way to generate new scenery for FlightGear, using some of the tools that the FlightGear Custom Scenery Project (http://www.custom-scenery.org/) have developed. These tools are used to generate the official scenery for each release. As such, they represent the easiest, and best way to generate new scenery for FlightGear, and make TerraGear much less of a TerrorGear!

This document assumes that you are running some form of Unix (cywin might work, but I haven't tried it, coLinux is another option to run linux easily in a Win32 environment), have installed TerraGear CVS, and applied the Custom Scenery Project patch set to TerraGear (http://www.custom-scenery.org/TerraGear-Tools.342.0.html), which fixes a number of bugs and adds some enhancements. You'll also need quite a bit of disk space - 5GB should be enough to generate somewhere the size of Scotland.

Setup

Before you start, you need to decide which area of scenery you want to build, as a rectangle defined in terms of latitute and longitude. The smaller the area of scenery you generate, the smaller the amount of data you will need, and the less CPU time it will take. For example, if you are just interested in generating a new airport layou at 12.3W 34.4N, then simply generating the scenery between 12W 34N and 11W 35N would be sufficient.

Write down the bounding box (minimum and maximum longitude and latitude) for the scenery you want to generate. Remember that West and South are negative - i.e. 4W 10S would be -4, -10. Try not to get mixed up, otherwise you'll end up generating scenery or airports on the other side of the planet!

You'll be dealing with multiple different types of data in various formats. Create a new directory for your scenery work. Underneath this, create the following sub-directories:

  • data for raw and pre-processed data
  • work for data that has been processed (typically by shape-decode) and is ready to be munged into scenery
  • output for the scenery files you will create.

Terragear needs three different pieces of information to generate scenery.

  • The elevation of the land (provided by SRTM)
  • The location and layout of airports (provided by apt.dat)
  • Whether a given lat/lon is sea, land, city, forest, town, road, railway (provided by VMAP0)

We'll deal with each of these data types in turn, from how to get hold of the data, through pre-processing. Finally, we'll describe how to bring it together into data that FlightGear can use.

The order in which we complete these steps is important- for example the airport data relies on the elevation data to determine the elevation of the airports.

Elevation

The best elevation data currently available is from the Shuttle Radar Topography Mission (SRTM). There are two types of SRTM data:

  • Highly accurate 1-arcsecond resolution data, known as SRTM-1, for the USA
  • Less accurate 3-arcsecond data, known as SRTM-3, for the rest of the world.

From now on, we'll assume you are using SRTM-3 data. Unless otherwise noted, the process for SRTM-1 is identical.

You can get download the appropriate data from ftp://e0srp01u.ecs.nasa.gov/srtm. You want all .hgt.zip files covering your region of interest. Depending on the size of your scenery, there may be quite a few. Download them to data/SRTM-3.

Now we've got the data, we need to convert it into something of use to TerraGear. First, you need to unzip each of the .hgt files. Use a shell script like the following to unzip all the files:

 for i in *.zip
 do
   unzip $i
 done

Now we've unzipped the data, we need to convert it into TerraGear format files in our work directory. The command to use for this is hgtchop. First create a work/SRTM-30 directory. Again, use a shell script to convert each of the files in turn:

 for i in *.hgt
 do
   hgtchop 3 <scenery>/data/SRTM-3/$i <scenery>/work/SRTM-30
 done

where <scenery> is the full path to the scenery directory - for some reason hgtchop doesn't like relative paths.

If you're using 1-degree data, replace the hgtchop command with "hgtchop 1 $i work/SRTM-1".

If you have a look in your work/SRTM-30 directory, you will see what looks like the familiar scenery tree, with a directory for each 10x10 degree square, each containing 1x1 degree sub-directories. Each of these contains a number of .arr.gz files.

We're not yet finished with the elevation data. Currently it is in a very inefficient form, with data points evenly spread across lon/lat. This is inefficient, as large tracts of land have the same elevation. We will use the terrafit.py Python script to make this more efficient.

Change directory to work/SRTM-30 and run

 terrafit.py .

This will recurse into each of the directories and create .fit.gz files with fitted elevation data.

That's the elevation done.

Airports

Now we've got elevation data, we can generate our airports. First, create a data/airports directory and copy in your apt.dat file. This may be direct from your FlightGear data package (though you'll need to unzip it), or it may be one that you've modified with TaxiDraw.

The command to create airports is "genapts". Run it without any arguments to see the various command-line options.

If it is simply run with a specified apt.dat and work directory, it will generate airport layouts for every airport in the file, which can take a long time.

If you are just creating a single airport and you know the ICAO ID (e.g. KSFO, EGPH, EG32), use is as follows from your root scenery directory (i.e. the directory above your data, work and output directories).

 genapts --input=data/airports/apt.dat --work=./work --airport=<AIRPORT_ID>

If you are generating a larger set of scenery, then you can specify the minimum and maximum longitude and latitude.

genapts will create two sub-directories in your work directory - AirportArea and AirportObj. These define the definitions of the airport layout and any objects present (e.g. windsocks).

Right, that's the airports sorted out.

Land Use

The final piece of data we need to generate is the land-use data. In general, this is taken from the VMAP0 dataset as shapefiles from the scenery database mapserver, but other source can be used.

The landuse data can be split into a number of different types:

  • Landmass. This separates the land from the sea. It is used as a mask for all other data. The most commonly used is the VMAP0 Landmass, but GSHHS can also be used.
  • Land use data. This defines whether a piece of land is forest, urban, sand, lava, glacier etc. These are usually VMAP0 data, defined as polygons.
  • Line data. This includes railroads, streams, roads. Typically VMAP0, but also Open Street Map for roads.
  • Point data. This is currently only used for defining towns.

By far the easiest way to get this data is to download shape-files from the wonderful http://mapserver.flightgear.org. This provides access to a database of information, and allows you to download the specifi shapefiles for your scenery area. Click on the Download Shapefiles link (or go direct: http://mapserver.flightgear.org/download.psp). Enter in the bounding box of the scenery you want to generate, select the shapefiles you want, and click download. For your first scenery generation, you want all of the ones listed under VMap0 (with prefix v0_).

Download each of them into a data/shapefiles directory.

You can load these shapefiles into a GIS editor such as QGIS or GRASS to view and edit. This is a good idea to verify you have the correct files!

Later on, you can experiment with replacing various shapefiles with other versions (GSHHS for coastline, OSM for roads etc.).

You now need to decode these into TerraGear format. This is done with the shape-decode command.

There are three important command-line arguments to shape-decode:

  • the filename of the shapefile (without the .shp extension) you want to decode
  • the directory you want to write the data to
  • the material type to use.

Each of the shapefiles maps onto one of the material types defined in your materials.xml files. The mapping is pretty obvious, e.g. v0_mixedcroppasturecover maps to MixedCropPastureCover. Note that the material types are case-sensitive, so it is a good idea to have your materials.xml file to hand so you can check. The exception is v0_landmass, which MUST be mapped onto the type Default.

Additionally, there are a number of optional arguments, to indicate the width of line data (for roads, streams, railways), how large to make point data (for towns) and how long the longest straight line is allowed to be.

For example, to decode the v0_landmass shapefile, you use the following command:

 shape-decode --max-segment 500 data/shapefiles/v0_landmass work/Landmass Default

To create streams of width 10 metres

 shape-decode --max-segment 500 --line-width 10 data/shapefiles/v0_stream work/Stream Stream

To generate some towns about 1km across

 shape-decode --point-width 500 data/shapefiles/v0_town work/Town Town

Run this command for each shapefile in the set.

Putting It All Together

You will now have a work directory looking something like this:

 AirportArea           SRTM-30
 AirportObj            Stream
 Bog                   IrrCropPastureCover    Town
 Lake                  Urban                  Landmass
 Railroad              DryCropPastureCover   Road
 EvergreenBroadCover   Marsh                  Sand
 MixedCropPastureCover ScrubCover
 GrassCover            MixedForestCover       Shared

Now we can actually generate the scenery. This is done by the fgfs-construct command. Run the command with "--help" to get usage information.

We need to define:

  • the work (--work-dir) and output (--output-dir) directories
  • the center of the scenery we want to generate (--lat, --lon)
  • the radius (--xdist, --ydist) from which to generate
  • All the work directories to include in the scenery.

For example:

 fgfs-construct --work-dir=./work --output-dir=./output --lon=55 --lat=60 --xdist=3 --ydist=3 \
 AirportArea SRTM-30 AirportObj Stream Bog IrrCropPastureCover Town Lake Urban Landmass Railroad \
 DryCropPastureCover Road EvergreenBroadCover Marsh Sand MixedCropPastureCover ScrubCover GrassCover \
 MixedForestCover

When this finishes, the output directory will contain a scenery sub-tree.

Point to it by setting either $FG_SCENERY or by using the --fg-scenery command-line option to fgfs, and give your new scenery a try!

Modifying the Scenery

One of the interesting things that you can do with TerraGear is try out new scenery data source, or modify the scenery data yourself. Here are some pointers:

  • The vmap0 landmass information is not very accurate. There is a more accurate coastline dataset called GSHHS. However, this doesn't match our scenery at the moment, so is not used. Using a GIS editor, you can modify the VMAP data to match the GSHHS coastline to create a more accurate landmass. Because the coastline (Default scenery type) is used as a mask for all the other scenery types, it doesn't matter if your modifications are completely accurate.
  • The mapserver includes information form the Open Streetmap project. You can use these shapefiles directly instead of the v0_road shapefile. They are quite neat, as they should roundabouts and freeways very clearly.
  • You can use a GIS editor such as QGIS or GRASS to edit the shapefiles, for example to add missing roads or villages.

Troubleshooting

Below is a list of common problems and solutions. If in doubt - google it. Many problems (particularly when compiling TerraGear) have been hit before:

  • Crashes in genapts. Sometimes genapts will crash when dealing with a particular airport. In that case, try running it again with the --start-id argument to start at the airport it failed on, and the --nudge argument which tries to nudge the calculations in the right direction.
  • fgfs-construct Killed. The fgfs-construct process may kill itself if it is using too many system resources. Increasing the values for setrlimit in src/BuildTiles/Main/main.cxx is the best solution.
  • Airports appear in the bottom of holes, or there are spaces between the airports and the scenery. This typically happens when genapts is unable to find the correct elevation data, or the elevation data changed between running genapts and shape-decode. Try generating a single airport in your scenery area using genapts, and look at the output. In particular, make sure there is a work/SRTM-30 directory.
  • Only the airports appear in the scenery. There are three typical causes for this:
    • You didn't download the correct shapefiles for the area.
    • You haven't run shape-decode on the v0_landmass shapefile as Default
    • You didn't include the correct directories in fgfs-construct.
  • Generate scenery includes data removed from the shapefiles. If you are editing shapefiles, you need to delete the appropriate work subdirectory before running shape-decode. Otherwise your changes will be in addition to those already present.