A topographical map

So my son had a project where he had to write a journal as a “spy” in ancient Egypt. As part of his project, he could create a topographical map for extra credit. My wife had the idea (why didn’t I????) to use my MakerBot to print it out. Off to Thingiverse for help! Read more if you’d like to learn how to do this.

I needed to find a way to obtain and then massage topographical data. I found this excellent guide and started from there. Here’s the detailed process.

Get Some Software

First, you’ll need to install some software. I’m doing this on a Mac, so your installation set up may vary slightly. You will need:

  • GDAL or Geospatial Data Abstraction Libary, to convert the data into something we can use with OpenSCAD
  • OpenSCAD to take the data from GDAL and turn it into an .STL file
  • MeshLab to simplify the .STL
  • ReplicatorG to generate the GCode and run the MakerBot

So basically the process is: Obtain data -> Extract to an ASCII format -> Convert to STL -> Reduce STL complexity ->Generate GCode.

Get Some Data and Massage It

So, where do we get data? CGIAR Consortium for Spatial Information (doesn’t that sound cool). The data comes from SRTM, the Shuttle Radar Topography Mission. Basically, a good portion of the world was sectioned up and topographical data generated with the Space Shuttle.

IMPORTANT: Note where your data is coming from and the resolution. Data for the US could be as high as 30m resolution, but for the rest of the world, it’s 90m. This is important for scaling later.

So, download the data you want. Now, let’s massage it with GDAL. Assuming you’ve installed GDAL correctly, pull up a terminal window, change to the directory for your data, and modify the GeoTiff file with this command:

gdal_translate -of AAIGrid -outsize 100 100 name_of_data_file.tif output_name.tmp

where “name_of_data_file.tif” is the data you got from the SRTM website. “output_name.tmp” is whatever you want to call it. Don’t use quotations. Now cut off some data we don’t need:

tail -n +7 output_name.tmp > output_name.sed

And remove any bogus data by forcing it to zero. (Some data is interpolated and may give weird numbers.)

sed 's/-32768/0/g' output_name.sed > output_name.dat

Use the strong (single quotes).

If you’ve got a lot, you can use this shell script:

#!/bin/bash
echo "Here we go!"
for f in *.tif
do
echo "Processing $f file..."
base=`basename $f .tif`
gdal_translate -of AAIGrid -outsize 100 100 $f $base.tmp
tail -n +7 $base.tmp > $base.sed
sed 's/-32768/0/g' $base.sed > $base.dat
done
rm *.sed
rm *.tmp
rm *.prj
rm *.xml

So, what does all this mean? “-of AAIGrid” tells GDAL to spit out ASCII data, basically a matrix of number representing the altitude measurements. “outsize” says scale it to 100 x 100 pixels. Most of the chunks of data are 6000 x 6000 pixels, with each pixel representing 90 m in real life. There are lots of command line options if you want to get real specific. I’m using 100 x 100 since the MakerBot has a 100 mm x 100 mm print bed (but I’m using 90 mm x 90 mm to give some room).

Create an STL

So, we’ve got our data. Fire up OpenSCAD and enter the following code. Save it in the same directory as your freshly minted topography data:

//
// 90m SRTM data
// 100 x 100 pixels -> 540 km x 540 km because it was originally 6000 x 6000 pixels at 90 m resolution
pixelsize=90;
scale=1/100; // Scale it down
// Mirror because OpenSCAD's surface() interprets data differently
mirror([0,1,0])
scale([scale*pixelsize,scale*pixelsize,scale])
surface(file="output_name.dat",center=true);

Mad props to Ben Diedrich for the original code on his Thingiverse post for Mt. Everest. I used it as a starting point.

Okay, here’s the scaling bit I warned you about. We really can’t create a simple topography map by scaling everything equally in all 3 axes unless altitude changes are on the same scale as the map. For example, if I try to scale down a 540 km x 540 km map to 90 mm x 90 mm and do the same with the height, I’ll end up with a flat map. Basically, we’re “fudging” the scale here to make an exaggerated map. In other words, if your map is 90 mm x 90 mm, a 5 mm difference in height would correspond to a 30 km altitude change if you used the same scale in the z axis as the x and y axes. Confused? Good. Me, too. And I’m an engineer.

Basically, play with the scale factors to get something you like. It’ll take some experimentation.

When you’re ready, hit FN-F5 (on a Mac) to compile. DON’T hit F6 to compile and render as that will take a while and is the last step we want. After playing around and getting it to something you like, then hit “Compile and Render.” Get a frosty beverage; it may take a while.

When it’s done, go to “Design” and select “Export as STL”. Export that puppy.

Simplify the Data

Ok, so you’ve got an STL with a ton of polygons. This is far too detailed for our purposes and would make ReplicatorG take a long time to slice it and generate GCode. We’re going to simplify with Meshlab.

Open Meshlab and under “File” select “Import Mesh”. Find and select your STL file. Click “OK” on any notices.

Now, click on “Filters” and then “Remeshing, simplification, reconstruction” and then “Quadratic Edge Collapse Decimation.” That would make an awesome name for a thrash metal band founded by computer science PhDs, wouldn’t it?

Now we’re going to simplify the data. You’ll probably see something like 20000 for a value for “Target number of faces”. Try inputting 7000 and clicking “Apply.” Meshlab will simply the STL. It’s kind of a touch and feel thing. If you’ve used your 3D printer a while, imagine it trying to trace out those contours. Simplify to make its life easier.

Now export that data with “Export Mesh” under “File.” You’re almost done.

Print!

Fire up ReplicatorG, open the STL, and generate/upload the GCode. Print and enjoy. Print multiple sections and glue together for topographical fun.

Author: Tinkering Engineer

Any day you don't end up in the ER needing stitches is a good day.