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:
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.
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.
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.
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.
If you desire to create your own data sets, you need to have:
This document gives a few examples and a brief walkthrough of creating a usable terrain layer.
AltusTerrain can consume height data from a variety of sources including:
The source data may in the following formats:
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.
You can create a water data to go along with your terrain data using vector data from the Natural Earth project. Follow these steps:
convert -colorspace RGB \
-depth 2 \
-define png:color-type=2 \
-size 10x10 \
xc:white \
seed.png
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
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
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.
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.pngNext, 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.tifThen 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.txtCreate 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.
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 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.
gdalbuildvrt terrain15.vrt *.tif
AltusTerrain -i terrain15.vrt \
-wi water15.tif \
-of terrain_tiles \
-png \
-ml 5 \
-fa bilinear \
-imh
This command will:
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.
AltusPackage -o MyTerrain.sqlite \
-pt terrain_png
-if terrain_files
This package can be used in offline scenarios.
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.
You can speed up processing in several ways:
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.
#!/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
AltusTerrain v2.0.ut-2153-g60764257e
AltusTerrain - Terrain tile creator. Copyright (c) 2016 BA3, LLC. ALL RIGHTS RESERVED.
USAGE: AltusTerrain [OPTIONS]
OPTIONS:
-border, --border_size ARG Define a stitching border in pixels.
Defaults to 0.
-cot, --clip_ocean_tiles When using water data, if an entire tile is
at sea level and covered soley in water, do
not generate children of the tile.
-cs, --cache_size ARG Maximum amount of memory, in gigabytes, for
in-memory cache during processing. The
default is 2GB.
-cwt, --create_water_tiffs Create bitonal TIFF imagery from NASA SWBD
shape files.
-fa, --filtering_algorithm ARG Filtering algorithm. Default is bilinear.
Can be one of: nearest, bilinear, cubic,
cubicspline, lanczos, average.
-h, --help ARG Display usage instructions.
-i, --input_file ARG Height data input file (i.e. heights.tif or
heights.hgt or heights.vrt)
-if, --input_folder ARG When creating water TIFF imagery, the input
folder containing all SWBD shape files. If
using 3-arc HGT files as terrain data
sources, set the tile size option (-ts) to
1201.
-imh, --ignore_max_heights By default, maximum terrain height values
are propagated from the source data
throughout the sampling system to lower
levels of detail. The purpose of
propagating maximum heights is for terrain
profiling scenarios in which maintaining
the maximum height is required for terrain
avoidance. The side effect is that in some
cases, when zoomed out, terrain may appear
less smooth. If you are not doing height
profiling and desire smoother looking
terrain, use this option and maximum
heights will not be carried to lower levels
of detail.
-lk, --license_key ARG Commercial-use license key. (i.e.
"01234567-0123-0123-0123-012345678901")
-maxX, --maximum_x ARG East-most edge of output map data.
-maxY, --maximum_y ARG Northern-most edge of output map data.
-minX, --minimum_x ARG West-most edge of output map data.
-minY, --minimum_y ARG Southern-most edge of output map data.
-ml, --max_level ARG Maximum level to generate. If not
specified, the optimum level will be
computed automatically.
-mps, --meters_per_sample ARG An alternative way of controlling to what
'depth' data is created. This is especially
useful if you have over polar regions
coming from EPSG:4326 projections. Use this
instead of maximum level (-ml) when you
have data that covers the poles. For
example, if you have an image that spans
the planet, and you desire to go to the
maximum resolution of your source data,
divide the circumference of the Earth in
meters at the equator by the pixel width of
your image. If you have an image that is
40,008,000 pixels wide, the math would look
like this: 40,008,000 / 86,000 = 465. You
would therefore use a meters-per-sample
setting of 465 to ensure that the full
resolution of your data is used.
-of, --output_folder ARG Output folder (i.e. /maps/mapdata)
-png, --save_as_png Save the output as greyscale PNG images
instead of stream of short int values. This
can substantially reduce size but you are
trading size for loading speed.
-sl, --start_level ARG Starting level to begin at.
-ts, --tile_size ARG The width and height for tiles. Default is
256.
-us_bounds, --united_states_bounds Use continental United States bounds.
-wi, --water_input_file ARG Raster water input file (i.e. water.tif or
water.vrt). This is a raster data source
where non-white pixels represent water.
EXAMPLES:
Command line usage:
==================
AltusTerrain -i /Volumes/MacHD/Users/Bruce/develop/SkypackData/NASA/ResampledSRTM/SRTM_1km.tif \
-of /Users/Bruce/develop/SkypackData/NASA/SRTM_Resampled_1km/tiles \
-ml 6 \
-minX -180 \
-minY -60 \
-maxX 180 \
-maxY 60
AltusTerrain v2.0.ut-2153-g60764257e Copyright (c) 2016 BA3, LLC. ALL RIGHTS RESERVED.
Built from commit: 60764257e4ba51dd571dee9d649af206c6fe58ff
AltusMappingEngine Server v2.0.ut.2153.g60764257e master
COPYRIGHT (C) 2017, BA3, LLC ALL RIGHTS RESERVED