HEIGHTMAP

There are some publicly available height maps, probably best known is SRTM of Nasa. The problem with this map: the land areas are only covered between the 60th northern and 58th southern latitude.

So I looked for another source and found JAXA’s ALOS Global Digital Surface Model. Another advantage of this data, they are already available as 1° longitude and 1° latitude GEOTIF files on a public ftp server.

This way, we can download the heightmap using the tool “wget.exe”.

wget -O image_exports/N66W023/N66W023.tar.gz "ftp://ftp.eorc.jaxa.jp/pub/ALOS/ext1/AW3D30/release_v1903/N065W025/N066W023.tar.gz"

Don’t be afraid, you don’t have to piece together the source code yourself. In the finished program you select your desired Tiles and export the script: A simple batch file you just need to execute.

In the next step, we need to extract the *.tar.gz file with the “TaarTool.exe” and another command.

TarTool image_exports/N66W023/N66W023.tar.gz image_exports/N66W023/heightmap

The result is a *.tif file (GEOTIF format) with a resolution of 3600×3600 pixel. Because we need to modify the image a little bit, we convert it to a more usable file format: 16-bit png. When using an 8-bit png, we have 256 different grayscale colors. with 16-bit, we have 65536. The creator of WorldPainter suggest 16-bit images to avoid rounding errors while creating a world. For this operation the tool “gdal_translate.exe” is used. It is part of QGIS, a program that we need anyway. (more info in another blogpost). gdal_translate is a tool to convert raster data between different formats.

"C:\Program Files\QGIS 3.10\bin\gdal_translate.exe" -a_nodata none -outsize 1024 1024 -Of PNG -ot UInt16 -scale -512 15872 0 65535 "E:\osm\image_exports\N66W023\heightmap\N066W023\N066W023_AVE_DSM.tif" "E:\osm\image_exports\N66W023\heightmap\N66W023_exported.png"

Lets split this command into seperate parts for a better explenation.

  • “-a_nodata none” = ignores missing data (you can set a standard value, but we will solve this problem later)
  • -outsize 1024 1024 = the image resolution of the exported image. It is the number of blocks per tile.
  • -Of PNG -ot UInt16 = this part defines the file format and is fixed
  • -scale -512 15872 0 65535 = this part is a little tricky. The first to numbers represents the real life data in the heightmap in meter. The lowest point (without oceans) is around 420m below NHN, so -512 is enough. With the highest point at 15872 we have a lot of space for the Mount Everest with 8848m. The last two numbers are the full scale of the 16-bit png file. With this values, we get a 0.25m accuracy for our exported image. Way more then the initial accuracy of the elevation data.

Incomplete data

For higher degrees latitude we face some missing data. Take a look at the following example of the Tile N66W023 (it is part of Iceland).

The black spots represent areas without any heightmap information. If we generate a Minecraft world out of this image, we will get cut of terrain, which looks horrible.

For command-line image manipulation, imagemagick works just fine. At first, we remove the black spots and make them transparent using the following command:

convert "\N66W023\heightmap\N66W023_exported.png" -transparent black "\N66W023\heightmap\N66W023_removed_invalid.png"

In the next step, we use the EdgeIn function to get the outline of the invalid data:

convert "\N66W023\heightmap\N66W023_removed_invalid.png" -channel A -morphology EdgeIn Diamond "\N66W023\heightmap\N66W023_edges.png"

The next command looks horrifying at first, but does a great job. We use the “Large Blur using Resize” technique, take a look here for detailed explenation. It is a method to blur large images without using astronomical CPU power.

convert "\N66W023\heightmap\N66W023_edges.png" ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) ( +clone -resize 50%% ) -layers RemoveDups -filter Gaussian -resize 1024x1024! -reverse -background None -flatten -alpha off "\heightmap\N66W023_invalid_filled.png"

Again, this script is generated by the finished program. So no worries.

This looks not so great at first, but combined with the transparent image, we get a smooth transition in the areas of invalid data.

Take a look at the finished heightmap. It is still not perfect, but a really accaptable solution. It works best for small holes insode the data.