Terrain and Water Data

From BA3 Mapping Engine Wiki
Jump to: navigation, search
TerrainAndWater.png
This Section Under Construction

The Altus Mapping Engine is one of the most advanced cross-platform terrain visualization engines for large-scale world-wide terrain datasets. With Altus you can:

  • Render terrain and water using a configurable color bar.
  • Render terrain at varied resolutions in different regions.
  • Use real-time, dynamic terrain coloring to call attention to areas based on altitude.
  • Create terrain profiles (aka cross-sections) through a region, around a point, or along an arbitrary path.

You can use pre-packaged terrain and water datasets provided by BA3, a third party provider, or you can create your own. This document discusses how to create your own terrain data sets using AltusTerrain and GDAL tools.

Contents

Fundamental Concepts

Dynamic Coloring

In Altus, terrain layers are treated as tile trees of varying levels where each tile is composed of a series of unsigned short values. Each value represents a height in meters above (or below) sea level. Data is dynamically color based on a height color bar. In this way you can render the terrain using a variety of styles at run-time.

Height and Water Encoding

The lowest point on earth is -424 M and the highest point is about 8850M. Water bodies may be present at any of these altitudes. Water will be encoded by negating the height and subtracting 1000. So any time Altus sees a height value that is less than -424 meters it assumes it is an encoded water height so it will add 1000 and negate it to get back to the original height (and will subsequently draw the area using the water color of the terrain color bar). All terrain tiles have a single-pixel border that is used at run-time for "stitching" terrain tiles together.

Height Sampling

A portion of the Altus SDK is dedicated to sampling height values from terrain data sets for rendering profile views. In some scenarios it is important that the 'maximum' height in an area is carried 'up' the sampling chain as levels of terrain are down-sampled. The AltusServer pipeline is aware of this requirement.

Creating Terrain Layers

If you desire to create your own data sets, you need to have

  • A source of height data
  • A source of water data

This document gives a few examples and a brief walkthrough of creating a usable terrain layer.

Input Height and Water Data

AltusTerrain can consume height data from a variety of sources including:

  • NASA
  • USGS
  • Local municipalities or governments

The source data may in the following formats:

  • Grayscale GeoTIFF
  • HGT
  • ESRI
  • GDAL VRT

Any data format can be made to work if the data resolves to a 16-bit unsigned sample and the container format is in a projection that can be parsed with the GDAL library. Areas that are covered with water are represented by bitonal GeoTIFF imagery, or a collection of them represented by a VRT. AltusTerrain expects water data to be bitonal, in other words, black and white. Black pixels represent water, white pixels represent land.

This document will walk you through one way to create a low-resolution terrain data package for Altus using publicly available data sources.

Natural Earth Water Data

You can create a water data to go along with your terrain data using vector data from the Natural Earth project. Follow these steps:

  • Visit this page and get relevant water shape files.
  • Create a 'seed' image using this ImageMagick command:
convert -colorspace RGB \
    -depth 2 \
    -define png:color-type=2 \
    -size 10x10 \
    xc:white \
    seed.png
  • Turn your seed image into a GeoTIFF using this GDAL command:
IMAGEWIDTH=108090
IMAGEHEIGHT=35429
gdal_translate -of GTiff \
    -b 1 \
    -a_ullr -180 90 180 -90 \
    -a_srs EPSG:4326 \
    -outsize $IMAGEWIDTH $IMAGEHEIGHT \
    -co "NBITS=1" \
    -co "COMPRESS=CCITTFAX4" \
    seed.png water.tif
  • 'Burn' the water data into the GeoTIFF using this command:
gdal_rasterize -b 1 -burn 0 -l ne_10m_ocean ne_10m_ocean.shp water.tif

You can change the width and the height based on your needs and/or burn additional water shape files into the target image. The following script performs this operation using several 10m water shape sets from Natural Earth:

#!/bin/bash
# Copyright (c) 2014 BA3, LLC
# Demonstrates how to use ImageMagick, GDAL, and NaturalEarth data to create
# a bitonal water layer
set -u
set -e

#Use image size that matches 15 arc-second data
IMAGEWIDTH=86401
IMAGEHEIGHT=43201
OUTPUTFILENAME="water15.tif"

#Create a black and white seed image
convert -colorspace RGB \
    -depth 2 \
    -define png:color-type=2 \
    -size 10x10 \
    xc:white \
    seed.png

#Convert the see image to a world-wide geo-tif
gdal_translate -of GTiff \
    -b 1 \
    -a_ullr -180 90 180 -90 \
    -a_srs EPSG:4326 \
    -outsize $IMAGEWIDTH $IMAGEHEIGHT \
    -co "NBITS=1" \
    -co "COMPRESS=CCITTFAX4" \
    seed.png $OUTPUTFILENAME

function BurnWater {
    echo Burning $1
    gdal_rasterize -b 1 -burn 0 -l $1 $1/$1.shp $2
}

#Burn water data
BurnWater ne_10m_ocean $OUTPUTFILENAME
BurnWater ne_10m_lakes $OUTPUTFILENAME
BurnWater ne_10m_rivers_lake_centerlines $OUTPUTFILENAME
BurnWater ne_10m_lakes_europe $OUTPUTFILENAME
BurnWater ne_10m_lakes_north_america $OUTPUTFILENAME
BurnWater ne_10m_rivers_europe $OUTPUTFILENAME
BurnWater ne_10m_rivers_north_america $OUTPUTFILENAME

SRTM Water Body Data

Background information on SRTM Water body data is available here.

This data is a collection of shape files that define water around and through continents.

This data can be used to create input files for AltusTerrain such that it may add water area information to terrain data output. The data provided as a series of ESRI shape files which must first be rasterized.

Rasterizing SRTM Water Body Data

AltusTerrain has an option (-cwt option) that is specifically created for scanning and converting a directory of NASA's SWBD files into bitonal GeoTIFFs. This feature requires that you have ImageMagick and GDAL installed on your machine.

Here is an example of using that command:

AltusTerrain -cwt -if /MyFiles/NASA/SWBD/waterdata -of /MyFiles/water_tiffs -ts 1201

Here we are telling AltusTerrain to create a set of water tif files from the NASA SWBD shape files and use a resolution of 1201x1201 pixels for each image that covers a 1x1 degree area. This size is chosen because we will later use 3 arc-second SRTM height data which is also 1201x1201 samples per file.

This command tells AltusTerrain to do the following set of operations:

First it creates a 'seed' image using ImageMagick's convert commmand:

convert -colorspace RGB -depth 2 -define png:color-type=2 -size 10x10 xc:white seed.png

Next, it uses gdal_translate to create a bitonal, compressed, GeoTIFF image from the seed image using a command like this:

gdal_translate -of GTiff -b 1 -a_ullr -80 34 -79 33 -a_srs EPSG:4326 -outsize 1201 1201 -co "NBITS=1" -co "COMPRESS=CCITTFAX4" seed.png  W098N95.tif

Then it determines all of the SWBD shape files that intersect this GeoTIFF and it rasterizes the vector data from each intersecting shape file into the GeoTIFF with a command like this:

gdal_rasterize -b 1 -burn 0 -l w080n33n w080n33n.shp W098N95.tif

It does this for every 1 degree by 1 degree section of the planet where SWBD shape files are found to intersect.

This will generate several thousand small bitonal GeoTIF images that we can then make into a GDAL vrt with these commands.

Generate a list of TIF files:

find /MyFiles/water_tiffs -type f | grep "\.tif" > water_tiff_files.txt

Create a GDAL virtual map from the file list:

gdalbuildvrt -input_file_list water_tiff_files.txt water_tiff.vrt

Now we have a relatively detailed set of water data we can use for burning water information into terrain data sets we create.

Roll Your Own Water Data

You are not required to use the method described here to create water information. If you have another data source, you simply need to convert it to either a GDAL VRT or GeoTIFF that can be used as input to AltusTerrain when it is generating terrain tiles and you need to make sure the data is in a format that is compatible. AltusTerrain will ignore any NODATA pixels, will consider non-black pixels to be terrain, and black pixels to be water. It will only look at the first raster band of a water data set and expect that band's data type to be GDT_Byte.

Height Data

Height value input data for AltusTerrain is expected to be a 2-byte short values. In GDAL terms, this would be a GDAL data set with 1 raster band whose data type is GDT_Int16.

You can create a data set that is compatible with AltusTerrain by getting the SRTM data form NASA and using the gdalbuildvrt program on whatever set of .HGT files you get.

Alternatively, you can use LIDAR data in ESRI format, or you can use some other format.

So long as heights can be read by GDAL and are short values representing meters above sea level for each sample it should work.

Here are some links to data sets online that you can use as input for AltusTerrain:

As you look at a data source, ensure you are satisfied that it meets your requirements. Some of the data that is in the public domain, for example, may not be accurate, or have holes. If you would like a accurate and commercially maintained set of height data there are several choices for that as well.

Step-By-Step Global Terrain Layer

  • Visit Viewfinder Panoramas and download the 15 arc-second data set that they provide. It comes as a set of 25 zip files. Download and uncompress each file into a folder.
  • Generate a VRT from the terrain data using this command:
gdalbuildvrt terrain15.vrt *.tif
  • Next, create a source of water data. You can do this by downloading the Natural Earth shape files and burning them to a GeoTIFF. Those steps are outlined above.
  • Now run AltusTerrain to create a set of terrain tiles. You can use a command like this:
AltusTerrain -i terrain15.vrt \
    -wi water15.tif \
    -of terrain_tiles \
    -png \
    -ml 5 \
    -fa bilinear \
    -imh

This command will:

  • Generate terrain tiles from terrain.vrt to level pseudo-mercator level 5
  • Use water data from water.tif to encode water information
  • Store the tiles in 16-bit grayscale PNG format
  • Use bilinear filtering for down-sampling
  • Ignore max height values.

NOTE: The -ihm flag is for data sets that do not require propagating the maximum height in a given sample up the LOD chain. If your application uses height profiling and you need the most accurate information, do not use this flag. Otherwise, you can use this flag to speed up data processing.

  • You can package up these files as an Altus map package using this command:
AltusPackage -o MyTerrain.sqlite \
    -pt terrain_png
    -if terrain_files

This package can be used in offline scenarios.

  • You can also place the entire folder on a web server and serve them up to Altus as a streamable terrain layer.

Once you understand the process you can explore creating higher detail terrain data sets, or sets that mix-and-match different detail levels in the same data set.

For Advanced Users

You can speed up processing in several ways:

  • Create down-sampled terrain and water data sets using a command like this for terrain:
gdal_translate -outsize 25% 25% \
    -of GTiff \
    terrain15.vrt \
    terrrain15_25.tif

Or this for water imagery:

gdal_translate -outsize 25% 25% \
    -of GTiff \
    -b 1 \
    -co "NBITS=1" \
    -co "COMPRESS=CCITTFAX4" \
    water15.tif \
    water15_25.tif

This will make a data-set for each that is 25% of the original size. These can be used for the lower levels. You could then have a bash script that looks something like this:

#!/bin/bash
set -u
set -e

#Generate to level 5 using 1/4 sized 15-arc second data
AltusTerrain -i terrain15_25.tif \
    -wi water15_25.tif \
    -of tiles \
    -ihm \
    -fa bilinear \
    -ml 5 \
    -png

#Generate to level 9 using 15-arc second
AltusTerrain -i terrain15.vrt \
    -wi water15.tif \
    -of tiles \
    -ihm \
    -fa bilinear \
    -ml 9 \
    -png

Here is a even more advanced script that mixes several different data sets and creates world-wide data set with the continental United States at a higher level of detail.

  • 15 arc-second data down-sampled to 25% size using gdal_translate
  • 15 arc-second full resolution data
  • 3 arc-second full resolution data
#!/bin/bash
set -u
set -e

#Generate to level 4 using 1/4 sized 15-arc second data
AltusTerrain \
    -i terrain15_25.tif \
    -wi water_50m_21600x10800.tif \
    -of tiles \
    -imh \
    -fa bilinear \
    -ml 5 \
    -png

#Generate to level 9 using 15-arc second
AltusTerrain \
    -i terrain15.vrt \
    -wi water_50m_86401x43201.tif \
    -of tiles \
    -imh \
    -fa bilinear \
    -ml 9 \
    -png \
    -us_bounds

#Generate to level 10 using 3-arc second
AltusTerrain \
    -i terrain3.vrt \
    -wi water_10m_us_86401x43201.tif \
    -of tiles \
    -imh \
    -fa bilinear \
    -ml 10 \
    -png \
    -us_bounds
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox