SRTM & Ordnance Survey Elevation Data in PHP

This page is about how to use PHP code to read elevation data from two freely-available data sources:

Download the code here (latest bugfix version 22-Oct-2011)

Elevation data is already available from a number of online sources, so why bother rolling your own code? The answer is that most (all?) online elevation resources restrict the number of data requests you can make. So to get the flexibility to do whatever you like with the data as often as you like you will need to read the raw data files yourself.

Demo

I expect the main use for the code will be to generate spot elevation data or profile charts for hiking or cycling. So here's a demo:

Data type (choose either): CGIAR-CSI SRTM
Ordnance Survey
Mouseover demo Elevation (m)
Mouse click demo Lat / Northing Long / Easting
Location 1
Location 2
chart

Elevation Data

Which data set to use? For most cases probably the SRTM data is the best bet. SRTM data was obtained using the NASA Space Shuttle and provides a 90m data grid data for most of the world. My code expects to see Version 4 data files in the 5x5 degree GeoTIFF format. This means that the UK is covered using just 6 files (around 412MB in total). Or 5 files if you don't mind chopping off a very small chunk of Cornwall!

You can get the data from CGIAR-CSI. However, if you have Google Earth, then an easier and faster way to get the data is to use Dr. Mark Mulligan's KML file. Just tick the 'elevation' checkbox in the 'Places' panel to see the tile grids then zoom in and download the five degree GeoTIFF files you need.

UK users may prefer the OS Land-Forma PANORAMA NTF data available from the Ordnance Survey. This data (around 570MB in total) provides a 50m data grid for the UK and is the same data as used for OS maps. Be warned that there are occasional gaps in the data on incomplete contour lines or sheer cliffs. This can be seen in the demo above where the graph occasionally drops to zero over certain areas. This only seems to occur in exceptionally sheer locations so is unlikely to be an issue for a typical hike or bike ride.

Requirements

You will need:

Code Notes

The code can:

JavaScript/jQuery displays the map, obtains the mouse position and gets the underlying coordinates. For SRTM data, the units are latitude and longitude. For OS data, the units are eastings & northings. These values are then passed as parameters via an asynchronous request to the appropriate PHP data reader class.

Both classes automatically work out which data file to read and then use file pointer arithmetic to jump to the data offset address. This means that - unlike ASCII file parsing or reading from a database - the code uses hardly any system resources and is very fast.

If you try the demo at silly small scales, it will be slow but will work eventually. The slowness is mostly the graph library - the elevation data itself is returned pretty much instantly for anything under a thousand or so coordinate pairs.

The mouseover demo will produce lots of very small hits on your server. A less "chatty" approach might be to work out the current map size and do a one-off grab of all the elevation points for the current map and thus create an on-the-fly elevation data tile in JavaScript. I suspect this would only be feasible for small area maps but that's left as an exercise for others!

Using the code

It's pretty straightforward:

SRTM code

    require_once 'SRTMGeoTIFFReader.php';
    $dataReader = new SRTMGeoTIFFReader("/path/to/GeoData");     
    // where GeoData is the directory containing your SRTM data files

    // get single elevation
    $lat = 53.073997;
    $lon = -4.095965; 
    $elevation = $dataReader->getElevation($lat, $lon);

    // get an array of elevations for each of the supplied coordinate pairs 
    $locations = array($lat0, $lon0, ... $latN, $lonN);   
    $elevations = $dataReader->getMultipleElevations(
        $locations, 
        $addIntermediateLatLons, 
        $interpolate
    );     
 
    // - $addIntermediateLatLons is a bool which will fill in the gaps 
    //   between two given points as per the demo   
    // - $interpolate is a bool which if set to true gives smoother graphs
    //   but may be noticeably slower for large numbers of coordinate pairs	
    

Ordnance Survey code

   
    require_once 'OSNTFReader.php';
    $dataReader = new OSNTFReader("path/to/OSNTFdata");  
    // where OSNTFdata is the directory containing the directories
    // holding the .ntf data files in the default structure
	// exactly as downloaded from OS

    // get single elevation 
    $e = 261550; // an OS easting value
    $n = 354515; // an OS northing value
    $elevation = $dataReader->getElevation($e, $n);

    // get an array of elevations for each of the supplied coordinate pairs     
    $locations = array($e0, $n0,  ... $eN, $nN);
    $elevations = $dataReader->getMultipleElevations(
        $locations, 
        $addIntermediateLatLons, 
        $interpolate
    );	
    

There are also some common useful utility methods and properties:

    // get ascent and descent in meters
    $hills = $dataReader->getAscentDescent();
    $ascent = $hills["ascent"];
    $descent = $hills["descent"]; 

    // get the total distance between the points in kilometers
    $distance = $dataReader->getTotalDistance();

    // optionally show verbose errors for debugging purposes (default: false)
    $dataReader->showErrors = true; 
	  
    // optionally change max number of allowed input locations (default: 5000)    
    $dataReader->maxPoints = 20000;
	

There's some other test stuff in there if you dig around - it's fairly liberally commented mainly so that I can work out how it all works again in 6 months time. You might need to allow a few nights to fully grok the data structures and pointer arithmetic :-)

Useful Links

If you want to hack the GeoTIFF files, then the TIFF section of the AWare Systems site is a great resource. Their free TIFF Tag Viewer (Windows only) will also help you to dig around in the data files.

If you want to hack the OS data then the excellent OS PDF entitled Land-Form PANORAMA User guide and technical specification is a must-have resource.

License

This code is given as public domain freeware. There is no licence of any kind - use it as you like. An acknowledgement or an email would be nice but it isn't required.

Feedback

Any bugs reports, suggestions or code improvements would be very welcome - please email me at bobosola@gmail.com.

22-Oct-2011 - Thanks are due to Bert Hulsmans who reported a bug in the SRTM code, now fixed.