Evangelism/Firefox3.5/35Days/Articles/geolocationDemo
Geolocation API and free data providers
Geolocation API Demo with OpenLayers, OpenStreetMap and GeoNames
The demo draws a map center on the position given by the navigator, it determines the map's precision by defining an accuracy extent, and load geo-information inside the accuracy.
The map is drawn with OpenLayers, a JavaScript library to draw dynamic map inside web page. The base layer is provided by OpenStreetMap (OSM). OSM is a project to construct a free world map based on contribution. The geo-information inside the accuracy is provided by GeoNames, a free database of geolocalised places. GeoNames provides a way to query geolocalised wikipedia's articles.
The main operation is to calculate an extent based on the position and its accuracy.
function getAccuracyExtent(aLatitude, aLongitude, aAccuracy) { var R = 6371000; // Earth radius in meters var lat1 = aLatitude*Math.PI/180; var lon1 = aLongitude*Math.PI/180; // Point at 45° North East var brng = 45*Math.PI/180; var lat2 = Math.asin( Math.sin(lat1)*Math.cos(aAccuracy/R) + Math.cos(lat1)*Math.sin(aAccuracy/R)*Math.cos(brng) ); var lon2 = lon1 + Math.atan2( Math.sin(brng)*Math.sin(aAccuracy/R)*Math.cos(lat1), Math.cos(aAccuracy/R)-Math.sin(lat1)*Math.sin(lat2)); lon2 = (lon2+Math.PI)%(2*Math.PI) - Math.PI; lat2 =lat2*180/Math.PI; lon2 =lon2*180/Math.PI; // Point at 45° South West var brng = 225*Math.PI/180; var lat3 = Math.asin( Math.sin(lat1)*Math.cos(aAccuracy/R) + Math.cos(lat1)*Math.sin(aAccuracy/R)*Math.cos(brng) ); var lon3 = lon1 + Math.atan2( Math.sin(brng)*Math.sin(aAccuracy/R)*Math.cos(lat1), Math.cos(aAccuracy/R)-Math.sin(lat1)*Math.sin(lat3)); lon3 = (lon3+Math.PI)%(2*Math.PI) - Math.PI; lat3 =lat3*180/Math.PI; lon3 =lon3*180/Math.PI; // return the extent return {north:lat2,south:lat3,east:lon2,west:lon3}; }
When we have this extent, the map is zoom to extent (center to the position with a precision reflecting the accuracy) and we query GeoNames to know geolocalised wikipedia's article and places inside the accuracy extent. If the accuracy is less than 1000 meters, we used to query GeoNames an accuracy extent based on an accuracy of 1000 meters.