Libraries and Web Services for Outdoor Pursuits Mashups

This page describes some useful services and libraries for outdoor pursuits map mashers. All are free for any use.

Bill Chadwick February 2009


A Javascript Sunrise and Sunset calculator

Mouseover the map below to display Sunrise and Sunset times in UTC , at the mouse location, for today's date. You will find the javascript source for this at SunRiseSunSet.js. This Google map uses a Lat+Lon graticule which you will find here LatLonGraticule.js.

Times go here


A Javascript implementation of the World Magnetic Model

This is a port of USGS C code. Updated Jan 3rd 2010 for the new 5 year epoch 2010-2015. The map below uses arrows to plot declination at 10 degree intervals around the world. You will find the javascript source for this at WorldMagneticModel.js This Google map uses an Arrow overlay which you will find here BDCCArrow.js.

Declination go here


A UK Gradient Server and a UKOS Grid for Google Maps

Powered by Google App Engine

My REST/JSON UK gradient web-service will return the ascent, descent, min and max gradients, profile (as sparkline data for the Google Chart API) and surface distance between two points in Great Britain (below 60 North, not Northern Ireland). The source data is SRTM which has approximately 90m horizontal sample spacing. This has been interpolated (bi-linearly) on to a 50m matrix for this service.

Click two points on the map below to get details of the terrain between them. When the service returns its data, the link between the points is coloured according to its maximum gradient. If the link has more ascent then descent, then the link is coloured thus: <1:10 , <1:6 , <1:3 , >1:3 . If the link has more descent then ascent, then the link is coloured thus: <1:10 , <1:6 , <1:3 , >1:3 . If the link has equal ascent, descent and gradients or is horizontal it is coloured . If the gradient of the link has not been determined or is < 50m long, then it is coloured .

Using this service it is easy to estimate hiking times using Naismith's rule.

This map uses a WGS84 Lat+Lon to UKOS co-ordinate conversion libray which you will find here, LatLngToOSGB.js and a UKOS grid overlay which is here OGBGraticule.js.

Gradient details go here

A simple spot height look up goes like this http://ukterrain.appspot.com/?e=275000&n=084000&m=1 The response looks like this

{"e":275000,"n":84000,"z":222}

e and n are in UK grid metres east and north, z is in metres. Add &callback=yourJsScriptFunc to use with a dynamic script tag. Remove the &m=1 to get a MIME type of JavaScript rather than text - its just good for testing in a browser.

Add e2 and n2 like this http://ukterrain.appspot.com/?e=275000&n=084000&e2=295000&n2=095000&m=1 to get a profile (max 100 points). In the return for this, the sparkline is ready for use with the Google Charts API. If you add &fp=1 thus http://ukterrain.appspot.com/?e=275000&n=084000&e2=275500&n2=084500&fp=1&m=1 you get a full profile array with x(e),y(n),z(alt) for each point, something like this

{"ascent":19,"descent":3,"maxGradient":0.1,"minGradient":-0.0,"surfaceDistance":708, "sparkline":"DAKlososv25595", "coords":[[275000,84000,222],[275040,84040,221],[275080,84080,224],[275120,84120,232],[275160,84160,233],[275200,84200,234],[275240,84240,233],[275280,84280,234],[275320,84320,235],[275360,84360,237],[275400,84400,238],[275440,84440,238],[275480,84480,239],[275500,84500,238]] }

I reserve the right to take this service down if it gets overused. You should find it fairly quick. Its not suitable for showing altitude under the mousepointer. That would require terrain tile download in parallel with the map tiles.


GPX to GeoJson converter

If you want to fetch a GPX file from a different domain to your GMaps page you will need a proxy of some sort to bypass browser cross-domain restrictions on XML files. My GPX to GeoJson converter is similar to a proxy but goes one step further in that it converts a GPX file to GeoJson script that can be loaded by any web page without any cross-domain restrictions.

I have used a FeatureCollection to represent the set of waypoints, routes and tracks in the GPX file. The FeatureCollection's 'properties' include the gpxversion and creator elements from the GPX file. Then I have used:

1) 'Point's for way-points with a set of 'properties' corresponding to the waypoint's descriptive elements (name etc)

2) 'MultiLineString' for a track (one string of points per track segment) with a set of 'properties' corresponding to the track's descriptive elements

3) 'GeometryCollection' for a route (the collection holds the set of route points as 'Point's) with a set of properties corresponding to the route's descriptive elements.

The Route presents a bit of a problem. I have put individual route- node properties on each GeometryCollection child - good JSON but outside the GeoJson spec. These properties are key for a route e.g. "cmt":"turn left for the pub". I had to use a GeometryCollection for the Route as a FeatureCollection can't contain a FeatureCollection.

You can see example track+waypoint output here http://gpx2geojson.appspot.com/?gpxurl=http://wtp2.appspot.com/SwinleyForest.gpx&mime=text/plain and example route output here http://gpx2geojson.appspot.com/?gpxurl=http://www.bdcc.co.uk/Gmaps/route.gpx&mime=text/plain other parameters are ele=1 to make 3D coords from 3D input (not compatible withOpenLayers) mime=text/plain to set the mime type for the reponse, default is 'application/json' callback= the name of your callback function. If you have a more complex GPX url you will have to 'escape' it using the javascript escape function ending up with something like this.


Java Script Douglas-Peucker

If you try and load big GPX tracklogs they may well contain too much detail (too many short legs) for display as a GMaps GPolyline. To work around this, the point set needs to be thinned. The classic algorithm for this is known as the Douglas Peucker algorithm.

You will find a client side javascript implementation of the algorithm here GDouglasPeuker.js

Given an array of GLatLng objects in trkPointsRaw, the call trkPointsReduced = GDouglasPeucker(trkPointsRaw,20); will reduce the points to a set with kink depth no more than 20 metres.

The map below shows the GPX file http://wtp2.appspot.com/SwinleyForest.gpx after thinning to kink depths of 20m (yellow) and 100m (magenta). The original track had around 2400 points.



For more of my Google Maps API demos please visit http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

To see all these libraries and services in action together go to http://wtp2.appspot.com/wheresthepath.htm