I've been thinking for a while about a location-aware page for the Gloucester Road Story. I've now knocked up a simple page using the W3C Geolocation API with jQuery. I've been guided by the Opera help page.
When the home page is loaded, the API is initialised. If no location is available, fall back to a default location in the road:
$(document).ready(function() { if (navigator.geolocation) { navigator.geolocation.watchPosition(get_premise_latlong, errorFunction,{maximumAge:100000}); } else { get_premise_number(200); } });
get_premise_latlong uses AJAX to request the page for the nearest premise from the server:
function get_premise_latlong(position) { var lat = position.coords.latitude; var long = position.coords.longitude; var url = "xq/mobile.xq?lat="+lat+"&long="+long; // alert (url); $('#info').load(url); }
and the mobile.xq script finds the nearest premise using the following function:
declare variable $glm:range := xs:double(0.00001); declare function glm:nearest-premise($lat as xs:double,$long as xs:double) as element(premise)? { (for $premise in $gl:premises[latitude][longitude] (:only geo-coded premises :) let $dlat := xs:double($premise/latitude) - $lat let $dlong := xs:double($premise/longitude) - $long let $distance := $dlat * $dlat + $dlong * $dlong (:not correct since $dlong size depends on $lat but good enough :) where $distance < $glm:range (: only if within range of user :) order by $distance return $premise )[1] (:get the first i.e. nearest if any :) };
If no location is found, the script selects a default premise. The premise data is then rendered as an HTML fragment and returned to the client where it replaces the #info div on the page.
Testing was done using the Opera Mini Simulator but now I'm a bit stuck. I'm ashamed to admit that I don't have a location-aware phone so I can't actually test it on the ground. If anyone suitable equiped happens to be walking down Gloucester Road (and where better to shop is there), I'd love to know if it works. Better still, pop in for a cuppa and we can test it together.