TerraGear Documentation

From FlightGear wiki
Jump to: navigation, search

There has been a lot of questions relating to scenery generation tools. This page is an attempt to document each of the tools I use. I will also document the design, and what each tool is actually doing.

My hope is to attract more developers to work on the tools to make it easier to create better scenery for FlightGear.


If you just want see every options/arguments available for each tool you can use this command line in the terragear/bin directory : (only for linux user)

 for file in *; do echo "" && echo "###################################" && echo $file && echo "###################################" && ./$file --help; done

or alternatively

 find * -exec bash './{}' '--help' \;


gdalchop is a tool responsible for cropping height data files into SimGear buckets (or tiles).

Most height data is published in fairly large data files that cover 1 square degree. For SRTM-1 data, there are 3601 x 3601 data points per file. For SRTM-3 data, there are 1201 x 1201 data points per file. SRTM datafiles are named by their southwestern most point.

When TerraGear tools need to query elevation data, they do so expecting the data to be located in a standard SimGear folder structure as follows:

Format Example
10 deg x 10 deg folder w070n10
1 degree by 1 degree subfolder w065n17
—— bucket file —— 1891048.arr.gz

gdalchop will create this directory structure in the work folder, and create sgbucket.arr.gz files within.

command options

gdalchop <work dir> <height data dir>/*hgt

This is where gdalchop will generate the elevation directory structure described above.

<height data dir>
This is the directory your height data resides in. (i.e. .hgt files for SRTM)

<height data dir>/*hgt
Points to all the hgt files in the data directory


  1. remember to use gdalchop on directories, rather than individual files. It handles height data stitching for you. Using individual files will produce data with missing elevation data where stitching could not be performed.

For example, this command will process all the .hgt file from the folder "SRTM-source" and the result will go in the folder "work/SRTM3"

gdalchop work/SRTM3 SRTM-source/*hgt

hgtchop (deprecated)

hgtchop is also a too responsible for cropping height data files into SimGear buckets (or tiles). This tool only work with data in the .hgt format (SRTM, viewfinder).

Reasons for using gdalchop:

  • handles heightdata in many more formats
  • is based on gdal, an actively maintained open source GIS library

command options

hgtchop <resolution> <hgt_file> <work_dir>

Each file created contains ALL of the data points for the simgear tile. For SRTM-1 data, the resultant grid (for tiles near the equator) is 450 x 450 points. For SRTM-3 data, the grid is 150 x 150 points. The resolution parameter tells hgtcop the distance between sampled points. Note that tile width varies with latitude. So 'square' tiles really only exist between 22 degrees N - 22 degrees S. The tile widths are explained here: Tile Index Scheme

The source file. Usually, the source files are 1 degree by 1 degree, and have enough data to create 64 simgear buckets (near the equator).

This is where hgt-chop will generate the elevation directory structure described above.


  1. zip files : In TGHgt::open, if the file extension is '.zip', then unzip executable is executed through system(). If the host system doesn't have unzip, then hgtchop will fail. The unzip should be performed via SimGear - Investigation needed


terrafit is responsible for taking the raw heightfield data for one bucket, and picking the most important points to generate a triangle mesh. It uses Terra to perform the work. The output is not a triangulation, but rather a list of nodes that can be fed to a triangulation routine. The quality of FlightGear's terrain is directly related to what parameters are fed into terrafit.

command options

terrafit [options] <file | path>

Option Default Description
-m or --minnodes 50 smallest number of nodes to produce. For a mostly flat tile, more nodes are wasteful.
-x or --maxnodes 1000 largest number of nodes to produce.

For a very complex tile, limiting this will reduce the detail of the resulting mesh.

-e or --maxerror 40 While picking points, and we have at least minnodes, but not yet maxnodes, the mesh will be completed

if any of the remaining points maximum elevation error drops below this value.

-f or --force If you have an already fitted work directory, and want to regenerate with different parameters, be sure to use force.

Otherwise, the work directory is checked for updated height data and merged with current data

As you can see, the default parameters are pretty conservative. At most, we will output 1,000 nodes. The input data for SRTM-1 contains 202,500 nodes, so we are only keeping 0.5% of the source data (or for SRTM-3, with 22,500 nodes, we keep ~5% of the source data)

For my experiments, I've increased maxnodes to 20,000, and decreased max error to 10 meters, and didn't see a major frame rate hit).

If you consider the number of nodes added when using detailed landclass, it's unfortunate that the height lookup for these points will be based on such an inaccurate mesh.

For example, this command will process all the *.arr.gz file (previously generated with gdalchop) from the folder "work/SRTM3", the result will go among .arr.gz files

terrafit -f -m 50 -x 20000 -e 10 work/SRTM3


ogrdecode is responsible for decoding landclass and line vector data into terragears internal textured polygon format. It also performs the 'chop' operation, so the output is structured in the same directory format as described in gdalchop. ogr-decode is capable of decoding shapefiles stored on disk, or retrieving the data from a PosGIS database.

command options

ogr-decode [options...] <work dir> <datasource> [<layername>...]

Option Default Description
--line-width 50 for line data, this is the width in meters the generated polygons will be.
--line-width-column none for line data, this optional field can be used to retrieve the width from the database row, under the given column.

If data is present in the row, it overrides the line-width parameter.

--point-width 500 for point data, this is the 'width' of the square generated. Both width and height will be this large.
--point-width-column none for point data, this optional field can be used to retrieve the width from the database row, under the given column.

If data is present in the row, it overrides the point-width parameter.

--area-type Default This string is used to define the type of landclass the generated polygons will be saved under.

In tgconstruct, the landclass priorities file is used to determine the priority of each landclass. higher priorities are 'on top' of lower.
The name given here must match a landclass type in your priorities configuration file.

genapts / genapts850

The general approach that genapts uses this. Start with a simple square polygon representing the airport area. As we proceed and add shapes to the airport, they are subtracted from this initial polygon. Also start with an empty polygon representing the airport shapes. As we proceed, objects are "added" to this polygon. Then we iterate through all the runways and taxiways for the airport. For each 8.10 taxiway we draw the corresponding box. We "intersect" that box with the accumulated shape polygon, so we can only cover areas that haven't been covered already. Then we add this "intersected" shape to the airport shape polygon and subtract it from the enclosing polygon. We get to pick the order we process the airport surface objects, so we pick the runways first, and probably the biggest runways before the smaller runways. Then the bigger taxiways before the littler taxiways, etc. Biggest/most important to smallest, least important. In the end we have a jigsaw puzle of all the individual shapes (so we can texture them properly individually) as well as a master surrounding polygon with holes cut out for all the shapes, plus a master polygon of all the shapes. Then in the end we can cover the whole area perfectly with no overlaps and no seams. In addition, there is a fairly sophisticated (and I think cool) step where we fit a natural curved surface across the airport elevation and used the curved surface instead of raw SRTM points. This eliminates the "noise" in the raw data and gives the airport surface a natural looking slope and correct hills and valleys (in most cases.) After that we generate all the light points and adjust their height based on the fitted curved surface. I think this approach could be updated for the 8.5 format by just generating different polygon shapes instead of the older collection of rectangles. The down side to the current approach is that it's hard to add markings over the surface. Without getting into all the technical details, if you cut in the markings into the surface structure you end up with an incredibly complex shape with an incredible number of triangles. Bad for load speeds and rendering speeds. If you lay the runway / taxiway markings and skid marks over the top of the base surface, then you have a lot of issues with z-buffer fighting and other odd graphics artifacts. Because our runway surface is curved/sloped we just use a simple draw order trick like other sims might use. But maybe in the past few years people have developed better tricks and techniques for handling this difficult problem of adding complex / arbitrary markings to a surface in a way that looks good mostly edge on (when landing or taxiing) and doesn't blow up your polygon count or encounter z-buffer problems, or require odd hacks of lifting the markings high enough above the runway that you can start to see that they are actually floating and not attached. [1]

  1. Curtis Olson (Sep 9th, 2011). Re: [Flightgear-devel] New experimental mapserver.


Step 1 : Parse
Step 2 : Clip
Step 3 : Clean
Step 4 : Elevation
Step 5 : Output


Related content