15

I'd like to get a reasonably accurate elevation profile for a track recorded with a GPS (which often has very unreliable altitude data and occasionally none at all, depending on the model.)

Does anyone have any hints on the easiest way to do this. The two techniques I am considering so far are:

  • Using the Google Elevation API

    This API is relatively easy to use, but still requires a few steps that aren't trivial due to it's usage restrictions: max 512 samples returned per request, and the number of points along the path is limited (by URL length) as well.

    I expect a gpsbabel simplify filter can be concocted to reduce the track to a suitable number of points (no point in them being closer than 100m or so together due to the resolution of the altitude data), but then the problem remains of how to map this simplified track back onto the original path, since the lengths will differ.

    Or, if this isn't suitable for automation the best approach may be to let the user select the transect points on a map manually.

  • Downloading the Shuttle Radar Topography Mission (SRTM) data and doing the query locally.

    This is something I have no experience with, so any suggestions on how feasible this is are welcome. How big is the data set? What GIS software is required, and can it be scripted in a suitable manner? I'd prefer not to have to write an sampling and interpolation algorithm, that sounds like a pain. What is the likely performance of such an approach? (I need it to be pretty quick and run on a memory-limited VPS webserver...)


Some further details to flesh out @MerseyViking's answer re downloading the data from http://srtm.csi.cgiar.org/SELECTION/inputCoord.asp:

There are 72 x 24 tiles, each about a 20mb zip file that decompresses to a 72.1mb 16bit TIF file (6001x6001 pixels).

That's ~120 gb, which is more than I can store. Leaving it compressed and ignoring the oceans will reduce it to maybe 10gb, which is still a bit too large. Loading the data on-demand would dramatically reduce the needed storage space, but the source site is slow (I was only getting 10kb/s) making that pretty impractical.

4
  • So you actually need world-wide coverage?
    – underdark
    Commented Nov 25, 2011 at 7:34
  • No, I don't need oceans, and am happy with excluding areas outside the SRTM (or similar) datasets. There are going to be large chunks of africa, china and south america that don't need to be covered, but I don't know what they are in advance, so unless getting the data on-demand is fast enough, it's better to have it all locally or just outsource all queries to a 3rd party (e.g. Google).
    – Tom
    Commented Nov 26, 2011 at 7:35
  • How long are these tracks? What sort of resolution do you need for the track points and the elevation?
    – Simbamangu
    Commented Nov 26, 2011 at 8:30
  • The tracks are mostly from running and cycling, so say between 5km and 100km. Typical gradients are less than 5-10% so I think anything with much less resolution than the SRTM dataset is just going to be too uninteresting... Aside from displaying the elevation profile, I also want to calculate elevation gained/lost, max/min altitudes etc.
    – Tom
    Commented Nov 26, 2011 at 9:55

5 Answers 5

9

For a local solution, GRASS can be scripted to do this:

# extract raster values at our points
# use cubic convolution for interpolation between DEM locations
v.drape in=my_pts out=pts_srtm_elev type=point rast=srtm_dem method=cubic

I ran an extended version of this for one of my use cases and performance of v.drape was no issue at all.

5

gpsvisualizer.com will do this for you. I believe it is using GPSBabel and Google API in the background.

5

It sounds like you need this as a generic solution, i.e. having all the world's elevation data available to you for any track you want to process, hence not wanting to store all the CGIAR data locally; the gpsvisualizer.com mentioned above (@Llaves) may be your best bet.

If you don't need high resolution, the GTOPO data set (1km grid) is only ~300MB for the whole planet; otherwise, the ASTER GDEM (30m) and original SRTM (90m) datasets are available but, as you point out, a lot of data. (The size of the ASTER data can be reduced after download by removing the bundled PDFs which are often larger than the actual elevation data - the Africa dataset was reduced by 40% when I did this!).

In R you can extract the elevation profile from any of these datasets fairly quickly - though loading the raster may take the majority of the time. This uses a small custom readGPX function and gpsbabel to process GPX data:

#Load elevation model and process track:
dem <- raster("E020N40.DEM")
track <- readGPXt("trackfile.gpx")
coordinates(track) <- ~Longitude+Latitude
proj4string(track) <- "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs"
#Overlay (extract) the elevation data for the track points:
track$profile <- extract(dem, track)
track <- as.data.frame(track)

'track' is now a table of GPS points with lat/lon, other standard GPX data (speed, gps elevation, etc), and a 'profile' column which indicates the elevation at that point.

4

SRTM data is easy to download for a given area, I've use this site in the past. The files aren't huge, and you can get them as georeferenced TIFFs. Downloading the whole world might take a while, but a couple of tiles covers a pretty large area. The issue you might have is with horizontal resolution, which is about 90 metres for most of the world, and the vertical error can be quite large, with spikes and areas of missing data.

The ASTER GDEM dataset is a more recent, higher resolution survey at ~30m horizontal resolution, but the quality is often lower than the corresponding SRTM data.

I don't know what resolution the Google elevation data is at, but I wouldn't be surprised if it was based on SRTM, so using the Google API may give you similar results to using a local process.

Following on from the answer by @underdark, if this is to be a simple web-based system, GRASS GIS is probably the way to go. I've used r.profile for doing simple intervisibility plots with some success but I'm not sure what interpolation method it uses; it might possibly be just nearest neighbour. Edit: Looking at the source code, r.profile does use nearest neighbour, so you might get some stair-stepping artefacts.

Another option might be to write a Python script, using GDAL and NumPy, which may be a bit more work, but would make a nice custom solution.

3

First you should specify what kind of horizontal/vertical precision you would be satisfied with.

But let's look at this from a practical perspective:

  • Each SRTM3 tile has 1200x1200 cells, each cell is a two-byte integer value representing the elevation in meters. That's around 2.75 MB of raw uncompressed data.
  • There are 14042 SRTM3 tiles. That's cca. 38 GB of raw data.
  • Do you really need to cover the whole world? I imagine there's not much interest for displaying the elevation profile of a GPS track in the middle of Sahara, Gobi Desert or Siberia, so it's not economically feasible for you to cover it if you are cash-strapped (BTW: SRTM3 doesn't cover the whole world, so you don't need to worry about places like Greenland and Antarctica ;)).
  • With some clever compression and data encoding you could reduce the dataset size dramatically. Elevation values are from 0 to 8848 so the two remaining bits are not used. You could also encode elevations through the delta compression to reduce it even further. You could also relinquish some of the vertical precision (to, say, 2m which then saves you one extra bit for each cell.
  • Depending on what kinds of GPS tracks this will be used for (walking, cycling, driving...) you should store the data into smaller tiles (say 0.25x0.25 degrees) as files on the disk or rows in a database table.
  • Use some clever memory cache for tiles so you don't need to reload often used ones.
  • Calculating the elevation from cells is the easy part of this whole business.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.