(For more resources on PHP and MongoDB, see here.)
The term geolocation refers to the act of locating the geographic position of a person, a place, or any place of interest. The geographic position of the object is determined mainly by the latitude and longitude of the object, sometimes its height from sea level is also taken into account. In this section, we are going to learn about different techniques that location- based applications use to determine a user’s location. You may skip this section if you are already familiar with them, or if you just cannot wait to get started coding!
There are several ways to locate the geographic position of a computing device. Let’s briefly learn about the most effective ones among them:
If you are curious to learn more about how geolocation works, How Stuff Works has a comprehensive article on it available at http://electronics.howstuffworks.com/ everyday-tech/location-tracking.htm.
When building a location-aware web application, the first part of the problem to be solved is to get the location of the user visiting the web page. We have covered geolocation techniques in the previous section, now it is time to see them in action.
We are going to use the W3C Geolocation API for locating the visitors to our web page. The W3C Geolocation API provides a high-level interface for web developers to implement geolocation features in an application. The API takes care of detecting the location using one or more methods (GPS, Cell ID, IP address). The developers do not have to worry about what is going on under the hood; they only need to focus on the geographic information returned by the API! You can read the whole specification online at http://www.w3.org/TR/ geolocation-API/.
The following table lists the browsers that support the W3C Geolocation API:
Browser | Version |
Google Chrome | 5.0+ |
Mozilla Firefox | 3.5+ |
Internet Explorer | 9.0+ |
Safari | 5.0+ |
Opera | 10.6+ |
iPhone | 3.1+ |
Android | 2.0+ |
Blackberry | 6.0+ |
Make sure you use one of these browsers when you try the practical examples in this article.
In this section, we are going to build a web page that detects the location of a visitor using the Geolocation API. The API will detect the latitude and longitude of the user who loads the page in his browser. We are going use that information on a map, rendered dynamically using the Google Maps API:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml_lang="en"
lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8"/>
<link rel="stylesheet" href="styles.css"/>
<style type="text/css" media="screen">
div#map {
width:450px;
height: 400px;
}
</style>
<title>Locating your position</title>
</head>
<body>
<div id="contentarea">
<div id="innercontentarea">
<h2>Locating your position</h2>
<div id="map"></div>
</div>
</div>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript" src="geolocation.js">
</script>
</body>
</html>
var mapContainer = document.getElementById('map');
var map;
function init() {
//Google map settings (zoom level, map type etc.)
var mapOptions = {zoom: 16,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP};
//map will be drawn inside the mapContainer
map = new google.maps.Map(mapContainer, mapOptions);
detectLocation();
}
function detectLocation(){
var options = { enableHighAccuracy: true,
maximumAge: 1000, timeout: 30000};
//check if the browser supports geolocation
if (window.navigator.geolocation) {
//get current position
window.navigator.geolocation.getCurrentPosition(
drawLocationOnMap,
handleGeoloacteError,
options);
} else {
alert("Sorry, your browser doesn't seem to support
geolocation :-(");
}
}
//callback function of getCurrentPosition(), pinpoints location
//on Google map
function drawLocationOnMap(position) {
//get latitude/longitude from Position object
var lat = position.coords.latitude;
var lon = position.coords.longitude;
var msg = "You are here: Latitude "+lat+", Longitude "+lon;
//mark current location on Google map
var pos = new google.maps.LatLng(lat, lon);
var infoBox = new google.maps.InfoWindow({map: map,
position:pos,
content: msg});
map.setCenter(pos);
return;
}
function handleGeoloacteError() {
alert("Sorry, couldn't get your geolocation :-(");
}
window.onload = init;
(Move the mouse over the image to enlarge.)
We built a web page and added JavaScript code that detects the latitude and longitude of the user who loads the page in his browser. The API needs the user’s permission to get his geographic information. So when the page loads, it prompts the user to specify whether or not he will allow the page to get his location. If the user agrees, the JavaScript code executes and gets his geographic coordinates using the W3C Geolocation API. Then it renders a small map using the Google Maps API, and highlights the user’s location on the map.
The Geolocation object implements the W3C Geolocation API. The JavaScript engine uses this object to obtain geographic information of the computer or phone on which the browser is running. Geolocation is a property of the Browser object (window.navigator), accessed as window.navigator.geolocation. In our example, we detect if the browser has geolocation capabilities by accessing this object, and notify the user if the browser fails the test:
//check if the browser supports geolocation
if (window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(
drawLocationOnMap,
handleGeoloacteError,
options);
} else {
alert("Sorry, your browser doesn't seem to support geolocation.");
}
The location information is obtained invoking the getCurrentPosition() method on the Geolocation object.
getCurrentPostition(callbackOnSuccess, [callbackOnFailure, options])
The argument callbackOnSuccess is a reference to a callback function. It is executed when the getCurrentPosition() method successfully determines the geolocation. This is a mandatory argument. callbackOnFailure is an optional argument, a callback function for handling failure to get the geolocation. options represents the PositionOptions object, which specifies optional configuration parameters to the method. The PositionOptions object has the following properties:
In our example, we used the drawLocationOnMap() method as a callbackOnSuccess function , which draws a map and pinpoints the location on it (we will walkthrough it shortly). The handleGeoloacteError() method notifies the user of any error while getting the position:
window.navigator.geolocation.getCurrentPosition(
drawLocationOnMap,
handleGeoloacteError,
options);
The Google Maps APTIis a popular JavaScript API for drawing maps on a web page. This API has methods to highlight objects on the rendered map. We can access the API methods by adding the following script tag in the web page (as we did in the location.html file):
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
If you are on a GPS-enabled device, set the sensor parameter to true, as follows:
When the script is loaded, we can initiate the map drawing by instantinating the google. maps.Map object . The Map object takes a DOM object as its first parameter; the map will be rendered inside this DOM. It also takes an optional JSON object that specifies configurations for the map (zoom level, map type, and so on):
var mapContainer = document.getElementById('map');
var mapOptions = {zoom: 16,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP};
map = new google.maps.Map(mapContainer, mapOptions);
Now, let’s focus on the drawLocationOnMap() function in the geolocation.js file, which is the callback function of the getCurrentPosition() method . As we know, this method gets called when the W3C API successfully locates the position; it receives a Position object as its argument. This object holds all the geolocation data returned by the API. The Position object holds a reference to the Coordinates object (accessed by the property coords). The Coordinates object contains geographical coordinates such as latitude, longitude, altitude, and so on of the location:
function drawLocationOnMap(position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
var msg = "You are here: Latitude "+lat+", Longitude "+lon;
……………………………………………………………………………………………………………………………………………………………
}
After we get the latitude and longitude values of the coordinate, we set it as the center of the map. We also display an information box with a message saying, You are here on the map!
function drawLocationOnMap(position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
var msg = "You are here: Latitude "+lat+", Longitude "+lon;
var pos = new google.maps.LatLng(lat, lon);
var infoBox = new google.maps.InfoWindow({map: map,
position:pos,
content: msg});
map.setCenter(pos);
return;
}
Get to know Google Maps API
We are going to use the Google Maps API in the upcoming examples as well. You might consider familiarizing yourself with it by reading some of its online documentation at http://code.google.com/apis/maps/ documentation/javascript/basics.html.
We can now turn our attention to the main topic of this article—geospatial indexing . A geospatial index is a special kind of index, designed specifically with location queries in mind, so you can perform queries like “Give me the closest n objects to my location”. Geospatial indexing essentially turns your collection into a two-dimensional map. Each point of interest on that map (each document in the collection) is assigned a special value named geohash. Geohashing divides the coordinate system into hierarchical buckets of grids; the whole map gets divided into smaller quadrants. When you look for objects nearest to a point (x,y) on the map, MongoDB calculates the geohash of (x,y) and returns the points with the same geohash. I am not going to delve into much detail here on how it works, but if you are interested, I recommend you read MongoDB in Flatland (found at http://www.snailinaturtleneck.com/blog/2011/06/08/mongo-in-flatland/), an elaborate yet simple demonstration of how geospatial indexing works in MongoDB.
Indexes are generally applied on fields to make field lookups faster.
Let’s see how we can build the geospatial index on a MongoDB collection:
$ ./mongodb/bin/mongo
MongoDB shell version: 1.8.1
connecting to: test
> use geolocation
switched to db geolocation
>
> db.map.insert({coordinate: {latitude:23.2342987,
longitude:90.20348}})
> db.map.insert({coordinate: {latitude:23.3459835,
longitude:90.92348}})
> db.map.insert({coordinate: {latitude:23.6743521,
longitude:90.30458}})
>db.map.ensureIndex({coordinate: '2d'})
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "geolocation.map", "key" : { "_id" : 1
}, "v" : 0 }
{ "_id" : ObjectId("4e46af48ffd7d5fd0a4d1e41"), "ns" :
"geolocation.map", "key" : { "coordinate" : "2d" }, "name" : "
coordinate _" }
We created a MongoDB collection named geocollection in a database named map. We manually inserted documents into the collection, each document contains some random latitude and longitude values in an embedded document named coordinate:
> db.map.findOne()
{
"_id" : ObjectId("4e46ae9bffd7d5fd0a4d1e3e"),
"coordinate" : {
"latitude" : 23.2342987,
"longitude" : 90.20348
}
}
After that, we built the geospatial index on the latitude/longitude pairs by calling the ensureIndex() method on the collection:
db.map.ensureIndex({coordinate: "2d"})
Next, we invoked the system.indexes.find() method that lists the indexes in the database. The index we created should be in that list:
> db.system.indexes.find()
{ "name" : "_id_", "ns" : "geolocation.map", "key" : { "_id" : 1 }, "v" :
0 }
{ "_id" : ObjectId("4e46af48ffd7d5fd0a4d1e41"), "ns" : "geolocation.map",
"key" : { "coordinate" : "2d" }, "name" : " coordinate _" }
There are a few of things you must know about geospatial indexing:
>db.map.insert({coordinate: [23.3459835, 90.92348]})
>db.map.ensureIndex({coordinate: "2d"})
Use arrays to store coordinates
When storing coordinates in a geospatially indexed field, arrays are preferable to embedded objects. This is because an array preserves the order of items in it. No matter what programming language you are using to interact with MongoDB, this comes in very handy when you do queries.
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…