Using Linux to Build Custom Topo Maps and Load Them Into Your
by Reid Priedhorsky
These are my notes on building custom topographic maps under Linux and
loading them into my Garmin GPS unit. I run Debian Testing and I have a Garmin
Legend Cx, and I have used these steps to load a detailed topo map covering
2,500 square miles. I hope that you find them useful as well. I would
welcome any suggestions or other feedback. You can reach me at
This document is copyright © 2007 Reid Priedhorsky. Verbatim
distribution for noncommercial purposes is permitted, though I would prefer
for you to link to my copy if that meets your needs. For other uses, please
Table of Contents
The basic idea is: download some elevation data from USGS or other sources,
compute elevation lines, and convert the result into a format compatible with
Garmin GPS units. This is done with a mix of free-as-in-freedom and
free-as-in-beer software, all on Linux.
This process can take a long time, perhaps several days. A lot of that you
don’t have to be present for: waiting for the computer to process things
and for the USGS to prepare data. I would set aside several days for your
first time, to avoid risk of last-minute panic. Another thing to be aware of
is that your maps will not match the USGS quads. Only water
and elevation contours will be included, and the contours will look different.
You also need to be prepared to download tens or hundreds of megabytes of
data, depending on the size of the map you create.
Why would you put up with this? Several vendors, including
Garmin, are willing to sell you maps that you can upload into your GPS.
Detailed data is not available from Garmin except for national parks, and for
the others I know of, you get a limited amount free with your initial purchase
and then you have to pay, pay, pay. The process I describe here costs you
nothing. Also, vendor solutions only seem to work on Windows.
Much of the information here comes from Jack Luers’ directions on doing the
same thing, but this page is shorter (believe it or not),
better-organized, and directed to a Linux crowd.
For the Legend Cx, you need firmware version 2.50 or
higher to put the device into USB Mass Storage mode, necessary to complete
these steps. You can flash your device to a newer firmware, which I did,
though I did it under Windows - I wasn’t willing to risk bricking my brand-new
GPS unit by trying such a touchy operation using Wine. (The remainder of the
steps, however, are all possible under Linux.) Garmin has directions
on updating firmware. My unit, purchased in September 2006, had version 2.40,
and I updated it to 2.60.
If you have information on other units, please let me know.
The first step is to get water and elevation information into a vector
format. While USGS publishes vectorized versions of standard quads, called
DLGs, availability of them seems very spotty as of October 2006. USGS has a
website [dead link removed] which claims to tell which areas are available as
DLG, but it disagrees with what seems to be actually downloadable. I would love
enlightenment on this situation if you have any information.
This section explains how to download water data from the USGS’s
National Hydrography Dataset (which is already vector) and to convert the USGS
raster elevation data (DEM) into elevation contour lines.
You won’t actually use this until later, but it takes a while for the USGS
to package up your data.
- Browse to http://viewer.nationalmap.gov/nhd/.
- Set your popup blocker to allow popups from this site. (By default,
Firefox blocks the download window.)
- Use the web application to zoom to your area of interest. Be patient,
and do not do anything the app is not expecting. It is rather finicky. Zoom
in enough so that Subbasins appears under NHD High
- Under Hydrologic Units, tick both the checkbox and radio button
for Subbasins. Click Redraw Map to update the view.
- Observe that the map is divided into irregularly shaped areas labeled
with 8-digit numbers. These are “Subbasins”, and these are the
chunks in which you download water data. (I’d be curious on how to download
via rectangle rather than by subbasin.)
- At the bottom of the left side, click on Polygon Extract.
- Drag a box over your area of interest. This works, but it’s kind of
strange – Firefox thinks you are dragging a link. You may have to
click a second time to make it go. You can also click on each subbasin
invididually, in which case you’ll repeat the following steps for each.
- The subbasins you’ve intersected will turn blue, and a window will pop
up. Tick High Resolution and Shapefile. Enter your email
address. Click Extract.
- You should get a dialog saying your request has been submitted and to
expect an email. Click OK.
- You may or may not get an email immediately, but regardless, it’s not
the one you want.
- After some time (anywhere from a couple of hours to a few days), you’ll
get an email with a download link. When you do, download the linked files.
In this step, you will download raster elevation data, i.e. a grid of
elevations at approximately 10 meter resolution.
- Browse to http://seamless.usgs.gov and click
on View and Download United States Data.
- Zoom in to your area of interest. Again, be gentle with the web app.
- Click on Downloads on the right.
Click on Elevation. Untick 1" NED and tick
- Under Downloads on the left, click
on the Define Download Area tool (it’s first).
- Draw a rectangle around you area of interest. You are defining
the extent of your map in this step.
- A window will pop up. Click Modify Data Request.
- Ensure that only NED 1/3 Arc Second is checked, and choose
GeoTIFF and TGZ. I suggest that you leave the chunk size
at 100MB rather than increasing it. Click Save Changes and Return to
- Click Download for each chunk. The sizes listed are
uncompressed; what you download will be smaller. For each, another window
pops up. (The remainder of this document assumes that you downloaded only
one chunk, but it should be easy to adapt if you have more than one.)
- Be patient - the USGS stores this data in giant robotic tape libraries,
and it takes a couple of minutes to gather it all.
- Save and extract the resulting archive. It contains a pile of files;
what we are interested in is the one ending in .tif: this is the
file containing the DEM data.
Incidentally, all of this is your tax dollars at work. Taxes enable the
creation of great community resources like these.
To do this, you will need to install GDAL, which is beyond the scope of
this document. Under Debian, just install the gdal-bin package;
otherwise, see http://www.gdal.org/ for more info. (Many
thanks to Dylan Beaudette for pointing me to this tool. The old way involved
installing the IDL Virtual Machine, a gargantuan tool which is hard to
download and install, doesn’t play nicely in a UNIX filesystem, and
shows you advertisements.)
- Navigate to the directory containing your GeoTIFF DEM file.
- Convert the DEM elevation units from meters to feet (optional):
$ gdal_translate -scale 0 10000 0 32808.399 29901365.tif feet.tif
- Build major contours (200-foot interval, adjust to your preference):
$ gdal_contour -a elev -i 200 feet.tif major.shp
- Build intermediate contours (40-foot interval here):
$ gdal_contour -a elev -i 40 feet.tif inter.shp
For this step, you will need GPSMapEdit and Wine, the Windows
emulator. GPSMapEdit version 188.8.131.52 and Wine version 0.9.30 worked for me
(Wine 0.9.25 did not work). Installing and configuring Wine is beyond
the scope of these notes, but make sure that the files above are in a place
accessible from inside Wine.
Don’t forget to save frequently as you carry out the following steps.
Also, GPSMapEdit seems to crash during import for me if I am on a different
desktop while it is working.
- GPSMapEdit can’t create a new, blank map, so you’ll have to
create one by a roundabout way:
- Create a text file gmapsupp.mp containing the following:
- Change the coordinates in Data0 to something in your region
of interest. (You can get some by running gdalinfo on your .tif
file.) Note that latitude comes first.
- Fire up GPSMapEdit:
$ wine /path/to/mapedit.exe gmapsupp.mp
- Import major contours:
- Choose File => Import => ESRI Shape and select
- A dialog box will pop up. Choose 0x0022 Major land contour.
- The next tab supposedly offers labels, but I couldn’t get the
widget to allow me to select any field. Untick Select field for
labels and click Next.
- Choose Coordinate system of Latitude/Longitude (deg)
and Datum of NAD83. (You should verify this against the
metadata included in the download.) The two Bounding rectangles
should match. Click Next.
- Tick levels 0 and 1. Click Finish. Do not be alarmed if
nothing shows up - this is because the map zooms out far enough that
nothing in the map is shown. Choose View => Levels => Level
0 to make everything show up. (Also, do not be alarmed if you zoom in
and discover that the contours look terribly jaggy - this is a display
- Unpack the zip file you got from NHD. Inside is a directory
hydrography, and inside that are several files named .shp.
- Import streams from NHDFlowline.shp. Choose 0x0026
Intermittent stream/ditch or 0x0018 Stream and levels 0
- Import water bodies from NHDWaterbody.shp. Choose 0x0029
Blue-Unknown and levels 0, 1, and 2.
- Import rivers from NHDArea.shp. Choose 0x0029
Blue-Unknown and levels 0, 1, and 2.
- Examine your map carefully, to ensure that water and hypsography seem to
- Delete the water data which is outside your area of interest. Choose
View => Full Map and then View => Levels => Level
0. You’ll see a small brown square - your contour lines -
surrounded by a great deal of water data. Use the Select Objects
tool to select extra water and press Backspace to delete it. You may want to
zoom in as you trim closer to your area of interest. Be careful not to
delete things which extend into it, especially large water bodies, and
don’t worry too much if you don’t trim particularly neatly.
- Import the intermediate contours from inter.shp. Choose
0x0021 Interm. land contour and level 0 only.
- Choose Tools => Remove Object Duplicates.
- Quit GPSMapEdit.
This step requires an application called cGPSmapper . While the Linux version is
a few revisions behind, it worked fine for me. (I emailed the author a couple
of times, and he promised to upload a new Linux build, but I haven’t
seen anything yet.) You get an executable called cgpsmapper-static; if you run
it with no arguments, it prints help.
- Run cGPSmapper:
$ cgpsmapper-static -q gmapsupp.mp
- Wait. cGPSmapper will take a long time, perhaps hours, and it prints
very sparse progress information.
- You now have a file gmapsupp.img. This is the file your Garmin
GPS will like.
This step requires that your computer be configured to mount USB Mass
Storage devices, which is beyond the scope of these notes.
- On the GPS unit, go to Main Menu => Setup => Interface.
Choose USB Mass Storage. The usual GPS interface should disappear and be
replaced by a picture of a computer.
- Mount the unit as a USB Mass Storage device. For me, that’s:
$ mount /mnt/garmin
- Ensure that a directory called garmin exists at the top level of
the GPS’s filesystem. You may have to create it.
- Place gmapsupp.img in that directory. Do not rename it or put
it anywhere else, or the GPS won’t see it.
- Check that it worked, e.g.:
$ ls -l /mnt/garmin/garmin/
-rwxr-xr-x 1 reid reid 734208 Oct 5 18:19 gmapsupp.img
- Unmount the GPS and disconnect it. It will reboot back into normal mode.
- Verify on the GPS that your map displays OK.
You’re done. Enjoy your new map.
I’d love feedback on these notes. Were they useful to you? How can
they be improved?
- October 4, 2009. Convert back to plain HTML.
- March 4, 2007. Update Wine version; fix a couple of minor errors.
- December 9, 2006. LATEX-ify,
drop DEM2TOPO in favor of GDAL.
- October 30, 2006. Initial publication.