Localization
You’ve heard about GPS (Global Positioning System) and probably know that it has something to do with handheld gadgets and satellites that tell you where you’re located. That’s great for starters, but location-based services (localization services or for short LBS) are more than that.
We can define a LBS as an information and entertainment service accessible with mobile devices through the mobile network and utilising the ability to make use of the geographical position of the mobile device.
LBS services include services to identify a location of a person or object, such as discovering the nearest restaurant or the whereabouts of a friend or employee. This includes parcel tracking and vehicle tracking services. LBS can also include mobile commerce when taking the form of coupons or advertising directed at customers based on their current location. They include personalised weather services and even location-based games.
History
- Emergency medical services (EMS) In 1487, the first recorded use of ambulance was by the Spanish army
- Yellow Pages First produced in 1886 by Reuben Donnely
- Local weather and traffic broadcast Since 1960s, radio traffic report has been very popular in US and on May 2nd 1982 the weather channel (TWC) went on the air.
- Emergency phone services
- In 1968, AT&T and FCC came up with this nation-wide emergency phone number - 911 (112 across EU and 999 in UK)
- In 2001, FCC issued a mandate of E911 to wireless carriers.
- The first LBS services globally were launched commercially in Japan in first by DoCoMo based on triangulation for pre-GPS handsets in July 2001, and by KDDI for the first mobile phones equipped with GPS in December 2001. Mobile handset makers have tended to take 'upstream initiative' to embed LBS in their mobile equipment. Originally, LBS was developed by mobile carriers in partnership with mobile content providers.
- The main advantage is that mobile users don't have to manually specify ZIP codes or other location identifiers to use LBS, when they roam into a different location. GPS tracking is a major ingredient for making it possible, utilising access to mobile web.
Concepts
- Position appears to developers in the form of spatial coordinates. It can be represented as a single point in the Cartesian coordinate.
- Location is associated with a certain place in the real world. If positioning delivers a spatial location, it will be mapped onto a descriptive location in order to be interpretable by the LBS user.
- LoCation Service (LCS) should be distinguished from LBS as it exclusively deals with the localization of target, and also makes the resulting location data available to external actors. It is responsible for the generation and delivery of location data.
- Location Based Service (LBS) is the service that ads value to target locations provided by LCS. It uses knowledge of a mobile device's location to offer value to the mobile subscriber or to a third party.
Wireless Location Technologies
Satellite positioning systems
Global Positioning System (GPS)
GPS is the oldest one from the frameworks presented. It isn't the first positioning system, but it is the one with the most success and longevity. It started as a military project in 1957. Because of the cold war, once the Russians sent to space the first man-made satellite, a team of scientists started monitoring its radio transmissions. The crucial discovery was that, because of the Doppler Effect, the signal transmitted frequency increases as the satellite approached, and lowers as it continued moved away from them. This added to the fact that they knew their exact location on the globe, the logical conclusion was that one could pinpoint where the satellite was along its orbit by measuring the Doppler distortion.[1]
Since then lots of GPS signal emitting satellites were launched, now the entire surface of the Earth being covered by them. Since 1983, it became also available to civilians, but with lower precision (but still 50 m were quite good for that time) and higher times for getting the current position.
The mechanism of its functioning is simple: you need three satellites to get your precise position in the device line of sight, unobstructed for entire period of measurement, or four if you want also the elevation. The device receives high precision clock signals (atomic clock precision) in order to measure the delay of the wave between the satellites and earth. Then, using triangulation, the location can be pinpointed on the Earth surface by doing some math calculus. The entire process takes few minutes in a device start and less if the device is readjusting the location.
Since its creation, it was used in all domains: aviation for getting to the correct location, help and rescue for climbers and excursionists which missed their path in mountains, sea navigation and now more and more for city navigation. Since the receivers became so miniaturised that they can be easily fit into smart phones, one can use it to get to a newly recommended cafe or theatre without having to carry with it the map of the city.
The recording devices that use GPS can be split into three categories:
1. Data loggers – log data as it arrives and here we can include almost all devices with user interface, no matter that this device is a cell phone or a standalone device. They simply receive the GPS signal, record it and show it to the user.
2. Data pushers – the kind of devices using for tracking logistic fleet in real-time - they read the GPS data but instead of only show it to the user, they also send it via GSM connections or radio to a central location where it is processed. Then the data is analyzed and the merchandise path to the client can be optimized.
3. Data pullers – almost the same as the pushers, but instead of sending by their own at specific intervals data to the central location, these ones can be queried as needed. One of the most important usages is placing one of these devices inside of a valuable device and if stolen it can send its position once queried for it.[2]
The main drawback of this technology is the fact that it requires clear line of sight to at least three satellites. In crowded urban areas or in mountains, this is a luxury. New technologies help minimizing these facts, like Assisted GPS which relies also on GSM towers to get its location done.
Assisted GPS (A-GPS)
AGPS, the short form of Assisted Global Positioning System, is a method whereby another method of triangulation is used to augment traditional GPS location tracking. Typically when GPS receivers power on, they can take minutes to acquire the proper satellites for triangulation. AGPS speeds up the process by using another method of triangulation, typically cell phone towers or WiFi hotspots, to cut down the time from two or three minutes to 10-20 seconds maximum. Typically, AGPS is implemented in cell phones, since the phones already have another method for semi-accurate triangulation using two or more cell phone towers.
aGps was the natural evolution of GPS system.[3] In specific conditions, the GPS system has difficulty providing reliable positions in poor signal conditions. For example, when surrounded by tall buildings (resulting in multipath), or when the satellite signals are weakened when a GPS device is used indoors or under trees. Some newer receivers are better at handling these situations.
In addition, when first turned on in these conditions, some non-assisted GPS units may not be able to download the almanac and ephemeris information from the GPS satellites, rendering them unable to function until a clear signal can be received continuously for up to 40 seconds.[4]
An A-GPS receiver can address these problems in several ways, using network elements such as either an assistance server or other data from a network. That assistance generally falls into two categories: a) information used to more quickly acquire satellites, or b) calculations done remotely:
· The assistance server can locate the phone roughly by which cell site it is connected to on the cellular network.
· The assistance server has a good satellite signal, and lots of computation power, so it can compare fragmentary signals relayed to it by cell phones, with the satellite signal it receives directly, and then inform the cell phone or emergency services of the cell phone's position.
· It can supply orbital data and/or almanac for the GPS satellites to the cell phone, enabling the cell phone to lock to the satellites faster in some cases.
· The network can provide atomic time (Accurate Time Assistance)
· Simply capturing a brief snapshot of the GPS signal, with approximate time, for the server to later process into a position.
· By having accurate, surveyed coordinates for the cell site towers, it has better knowledge of ionosphere conditions and other errors affecting the GPS signal than the cell phone alone, enabling more precise calculation of position.
As an additional benefit, in certain types of A-GPS, both the amount of CPU and programming required for a GPS phone is reduced by offloading most of the work onto the assistance server. (This is not a large amount for a basic GPS – many early GPSs utilized Intel 80386-class 16 MHz CPUs or similar hardware.) Also most modern GPS chipsets embed ARM or similar processors which have enough computational power and offload the main phone CPU from GPS computations and free cell phone firmware developers from related programming, hence such advantage is questionable. Also the data sent to assistance servers opens the potential for high precision tracking of a cell phones location, raising privacy concerns.
A typical A-GPS-enabled cell phone will use a data connection (internet, or other) to contact the assistance server or a standard network connection for A-GPS information. If it also has functioning autonomous or standalone GPS, it may use standard GPS, which is sometimes slower on Time To First Fix, but does not lead to network dependent downsides, such as failure to work outside of network range, or charges for data traffic. Some A-GPS solutions do not have the option of falling back to standalone or autonomous GPS.
High Sensitivity GPS is an allied technology that addresses some of the same issues in a way that does not require additional infrastructure. However, unlike some forms of A-GPS, high sensitivity GPS cannot provide instant fixes when the phone has been off for some time.
Positioning in mobile networks
Finding the location of a mobile device in relation to its cell site is another way to find out the location of an object or a person. It relies on various means of multilateration of the signal strength from nearby cell sites serving a mobile phone. To locate the phone, it must emit at least the roaming signal to contact the next nearby antenna tower, but the process does not require an active call.
The geographical position of the device is found out through various techniques like time difference of arrival (TDOA) or Enhanced Observed Time Difference (E-OTD).
Mobile based solutions
- Positioning is carried out in mobile device and sent back to the network
- Requires the installation of client software on the handset to determine its location. This technique determines the location of the handset by computing its location by cell identification, signal strengths of the home and neighboring cells or the latitude and longitude, if the handset is equipped with a GPS module. The calculated location is then sent from the handset to a location server.
- The key disadvantage of this technique (from mobile operator's point of view) is the necessity of installing software on the handset. It requires the active cooperation of the mobile subscriber as well as software that must be able to handle the different operating systems of the handsets. Typically, only a smart phone, such as one based on Symbian or Windows Mobile or iPhone or Android, would be able to run such software.
- One of the proposed work-arounds is the installation of embedded hardware or software on the handset by the manufacturers. However, the obvious difficulty of convincing different manufacturers to cooperate on a common mechanism and to address the cost issue means that this avenue has not made any significant headway.
- Another difficulty would be to address the issue of foreign handsets that are roaming in the network.
Well, let us find an example to demonstrate the Network based location tracking algorithm: According to global GSM structure and ETSI, the GSM service providers information flows through the control channel and the control channel is free to access. Interestingly, all the present GSM modem/mobiles (Telit, SIMCOM, HTC, Nokia etc.) are coming with some extra feature to monitor the neighbouring cells and its RSSI value. Theoretically you should get 1+6=7 cell information (1 home cell ID, 7 BCCH info+ 7 RSSI). If you know the location of 7 cells, it is possible to get a mobile phone location with very high accuracy (<100 meters)
Network based solutions
- Utilize the service provider's network infrastructure to identify the location of the handset. The advantage of network-based techniques (from mobile operator's point of view) is that they can be implemented non-intrusively, without affecting the handsets.
- Accuracy varies, with cell identification as the least accurate and triangulation as the most accurate. It is closely dependent on the concentration of base station cells, with urban environments achieving the highest possible accuracy.
- One of the key challenges of network-based techniques is the requirement to work closely with the service provider, as it entails the installation of hardware and software within the operator's infrastructure. Often, a legislative framework, such as E911, would need to be in place to compel the cooperation of the service provider as well as to safeguard the privacy of the information.
Mobile-assisted solutions
- Use a combination of network-based and mobile-based technologies for location determination.
The mobile device makes the measurements, reports these to the network where the serving mobile location centre node calculates the handset position. Location information is not stored in the handset and remains in the network. Another example would be Assisted GPS, which uses both GPS and network information to compute the location.
| Cell ID | Cell-ID/TA | EFLT | AFLT | AOA | TDOA | EOTD | GPS | A-GPS | |
|---|---|---|---|---|---|---|---|---|---|
| Network-based | x | ||||||||
| Mobile-assisted | x | x | x | x | |||||
| Mobile-based | x | x | x | x | x |
Positioning in GSM
In 1997, TIA led the standardization activities fpr the positioning in GSM. Four positioning methods were included:
Cell identity and timing advance
Cell Identity (CI) is the signature and identity of a BTS. A CI-based approach assumes
- the mobile is at the serving cell's antenna coordinates in a omnidirectional cell, or
- the center point of a sector is a sector point
Time advance (TA) represents the round trip delay between the mobile and the serving BTS.
- Ta is used in a TDMA-linked system to avoid overlapping of bursts transmitted by multiple users
- It is represented by a 6-bit integer number in the unit of GSM bit period.
In addition, RXLEV is the measurement of strength of signals received by a mobile. With suitable propagation models, the distance between a mobile and the BTS can be estimated.
Uplink time of arrival (TOA)
The TOA of random access bursts in the random access channel from a mobile is measured by the BTS or LMU (location measurement unit). The location estimation schemes are similar to E-OTD:
- In TOA approaches, one TOA measurement by one BTS or LMU determines a circle.
- In TDOA approaches, the difference in TOA determined by two different BTS or LMUs determines a hyperbola.
The mobile is usually signaled to perform an asynchronous handover for sending out random access bursts.
Enhanced observed time difference (E-OTD)
Observed Time Difference (OTD) is the time difference measured by the mobile between the receptions of bursts transmitted from the reference BTS and each neighbouring BTS Enhanced OTD is the measurement for positioning purposes. It is essentially the sum of two components:
- Real-Time Difference (RTD): the synchronisation difference between two base stations.
- Geometric Time Difference (GTS): propagating time difference between two base stations.
Assisted GPS
The GSM network measures the difference between GSM time and GPS time. The GSM network informs the mobile about the data that the GPS satellites are sending. The GSM network sends the acquisition assistance data including the Doppler shift and code phase of the signal from a certain satellite and the real-time status of certain GPS satellites. High positioning positioning expectations
- High sensitivity: inside, urban canyons, etc.
- Rapid first fix: several seconds from cold start.
- Accuracy suitable for location services:5-50m.
WiFi positioning system (WPS)
A method for estimating position using WLAN access point radio propagation characteristics in a provided WLAN location based service. A location-based services system has a plurality of WiFi access points in a target area. The WiFi access points are positioned at geographic locations and have signal coverage areas. A method of characterising at least one of the WiFi access points comprises determining the geographic location of the WiFi access point, dividing the signal coverage area of the WiFi access point into at least one section, and determining radio propagation characteristics for each section. The radio propagation characteristics of each section characterise a radio channel of the WiFi access point, and the characterisation can be used in a location algorithm.
Rudimentary location services are available on every WiFi network, at least at the granularity of a single access point's coverage area. If you know the coverage pattern of an AP and you know a WiFi client is associated with that AP, you have a crude approximation of location.
Another method for finding hardware is referred to as “closest AP.” Its accuracy is directly related to the coverage footprint of your AP. A dense deployment of low-power APs will provide a more accurate view of location than a less-dense configuration of higher-power APs.
To get even higher accuracy, most vendors employ a system where location is tracked by multiple APs simultaneously. This technique is generically referred to as triangulation, in which the signal strength detected at three or more APs is used to predict the location of a device. More sophisticated techniques, such as RF fingerprinting, can be used to increase accuracy at the expense of somewhat higher installation and maintenance costs.
As the technology matures (see cnet news article) the precision and accuracy increases to the point when it outperforms dedicated techniques like GPS which performs poorly in urban areas where buildings block the view of satellites, and it doesn't provide any coverage inside of buildings.
Nearest sensor
This is the simplest method, though by itself, it is the least precise. This capability, supported by most wireless network vendors in their management systems, determines the 802.11 access point (AP) or cellular base station to which a client device is associated. It assumes that this sensor is the closest sensor to the device. It then computes how far the signal radiates.
The diameter of the 360-degree radiation “cell” surrounding the sensor (in three dimensions, mind you) is as precise as this method alone gets, even presuming that the client does indeed associate with the nearest sensor. If an 802.11b/g AP has approximately a 30-by-30-meter coverage area, for example, the nearest-sensor method tracks the client to within a 900-square-meter area. Note, though, that a client might associate with a sensor a bit farther away if the nearest one is overloaded or its signal strength is otherwise not as strong.
Triangulation/trilateration
The nearest-sensor measurement can be combined with others to pinpoint location more precisely. “Triangulation” measures the angles between three or more nearby sensors (or other reference points). Where they intersect is calculated as the client location. Precision within 50 metres is generally accepted for triangulation, according to Diana Kelley, senior analyst at Burton Group. Trilateration measures the distance between sensors or other reference points, rather than the angles between them.
RF fingerprinting
A more sophisticated category of location tracking used in 802.11-based WLANs is called RF fingerprinting. This technique uses intelligent algorithms to improve location-tracking precision by accounting for the environmental effects - such as an object, human, mirrors, windows, attenuation and multi-path - on the wireless signal. A “fingerprint” of the wireless environment is calculated by a physical walk-around using a handheld spectrum analysis device. These measurements are later compared to deviations in the real-time environment to locate the client device.
Supplier approaches
Some location-tracking technology suppliers are makers of wireless LAN communications systems that layer location services onto their systems. Others are third-party location specialists that provide overlay wireless tracking systems.
Several fall into the “RF fingerprinting” category, using intelligent algorithms to account for environmental effects on wireless signals. As described above, a wireless “fingerprint” of the radio environment is created by a physical walk-around using a handheld spectrum analyzer (or are auto-calibrated in some systems). They are then compared to deviations in the real-time environment to locate the client.
While the location services market is clearly drawing interest, it is best thought of as a value-added application for WiFi networks. To achieve granularity, you need a dense deployment of APs. And adding a location server, installing and maintaining WiFi tags and implementing applications that leverage this infrastructure can be an expensive and complex undertaking. In the future, it is likely that costs will decrease and functional location services will become a standard component of enterprise WLAN infrastructure.
Geocoding
Geocoding is the process of converting addresses (like “Bonn, North Rhine-Westphalia, Germany”) into geographic coordinates (like latitude 50.732704 and longitude 7.096311), which you can use to place markers or position the map.
Google Maps API
The Google Maps API includes a Geocoding service that can be accessed directly via an HTTP request or by using a
GClientGeocoder object. The Google Maps API provides a client geocoder for geocoding addresses dynamically from user input. If instead, you wish to geocode static, known addresses, see the Geocoding Service documentation.
The Geocoding Object
You can access the Google Maps API geocoding service via the GClientGeocoder object. Use GClientGeocoder.getLatLng() to convert a string address into a GLatLng. This method takes as parameters a string address to convert, and a callback function to execute upon retrieval of the address. The callback function is necessary since geocoding involves sending a request to Google's servers and can take some time.
var map = new GMap2(document.getElementById("map_canvas")); var geocoder = new GClientGeocoder(); function showAddress(address) { geocoder.getLatLng( address, function(point) { if (!point) { alert(address + " not found"); } else { map.setCenter(point, 13); var marker = new GMarker(point); map.addOverlay(marker); marker.openInfoWindowHtml(address); } } ); }
You can also modify the Maps API geocoder to prefer results within a given viewport (expressed as a bounding box of type GLatLngBounds) through the GClientGeocoder.setViewport() method. You can return results tailored to a particular domain (country) using the GClientGeocoder.setBaseCountryCode() method. Geocoding requests can be sent for every domain in which the main Google Maps application offers geocoding. For example, searches for “Toledo” will return different results within the domain of Spain (http://maps.google.es) specified by a country code of “es” than within the default domain within the United States (http://maps.google.com).
Reverse Geocoding
The term geocoding generally refers to translating a human-readable address into a point on the map. The process of doing the converse, translating a point into a human-readable address, is known as reverse geocoding.
The GClientGeocoder.getLocations() method supports both standard and reverse geocoding. If you pass this method a GLatLng object instead of a String address, the geocoder will perform a reverse lookup and return a structured JSON object of the closest addressable location. Note that the closest addressable location may be some distance from the original latitude and longitude values of the query, if the supplied GLatLng is not an exact match for any addressable locations.
var map; var geocoder; var address; function initialize() { map = new GMap2(document.getElementById("map_canvas")); map.setCenter(new GLatLng(40.730885,-73.997383), 15); map.addControl(new GLargeMapControl); GEvent.addListener(map, "click", getAddress); geocoder = new GClientGeocoder(); } function getAddress(overlay, latlng) { if (latlng != null) { address = latlng; geocoder.getLocations(latlng, showAddress); } } function showAddress(response) { // present the response information // visit the above link for a full description }
Geocoding via HTTP
Google provides a direct geocoding service via HTTP as well. This geocoding service is distinct from the JavaScript Google Maps API. Using the HTTP service is not recommended for dynamic or live retrieval of geocoding requests; instead use the JavaScript client-side geocoder documented within this chapter. However, the HTTP geocoder is useful for populating a static set of data, for debugging purposes, or for cases where a JavaScript GClientGeocoder object is not available.
To access the geocoder, send a request to http://maps.google.com/maps/geo? with the following parameters in the URL:
- q (required) — The address that you want to geocode.
- key (required) — Your API key.
- sensor (required) — Indicates whether or not the geocoding request comes from a device with a location sensor. This value must be either true or false. (Note that devices with sensors generally perform their own geocoding by definition; therefore, most geocoding requests to the Maps API Geocoding service should set sensor to false.)
- output (required) — The format in which the output should be generated. The options are xml, kml, csv, or json(default). (For more an example of JSON format, see below.)
- oe (optional but strongly encouraged) — The output encoding format of the response. It is recommended that you set this output encoding explicitly to utf8 unless you have specific requirements to handle other encoding types.
- ll (optional) — The {
latitude,longitude} of the viewport center expressed as a comma-separated string. This parameter only has meaning if the spn parameter is also passed to the geocoder. - spn (optional) — The “span” of the viewport expressed as a comma-separated string of {
latitude,longitude}. This parameter only has meaning if the ll parameter is also passed to the geocoder. - gl (optional) — The country code, specified as a ccTLD (“top-level domain”) two-character value.
Here is a sample querry:
http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&oe=utf8&sensor=true_or_false&key=your_api_key
Google Gears Geolocation API
Prerequisites: Visit gears.google.com to install Gears on your computer.
The Geolocation API enables a web application to:
- Obtain the user's current position, using the getCurrentPosition method
- Watch the user's position as it changes over time, using the watchPosition method
- Quickly and cheaply obtain the user's last known position, using the lastPosition property
The Geolocation API provides the best estimate of the user's position using a number of sources (location providers). These providers may be onboard (GPS for example) or server-based (a network location provider). The getCurrentPosition and watchPosition methods support an optional parameter of type PositionOptions which lets you specify which location providers to use.
Gears on mobile devices
Gears is now available for a number of mobile browsers and devices.
- IE Mobile on Windows Mobile 5 and 6 devices
- Opera Mobile (Presto build 2.1.0+) on Windows Mobile 6 touchscreen devices
- Android devices
Here is an example of how google gears can be used:
<script type="text/javascript" src="gears_init.js"></script> <script type="text/javascript"> var geo = google.gears.factory.create('beta.geolocation'); function updatePosition(position) { alert('Current lat/lon is: ' + position.latitude + ',' + position.longitude); } function handleError(positionError) { alert('Attempt to get location failed: ' + positionError.message); } geo.getCurrentPosition(updatePosition, handleError); </script>
The server determines the client's position using a set of data provided by the client. This data includes the client's IP address and information about any cell towers or WiFi nodes it can detect. This document describes the protocol used to send this data to the server and to return a response to the client.
Communication is done over HTTP, with Gears making the request using HTTP POST. Both request and response are formatted as JSON, and the content type of both is application/json.
{
"version": "1.1.0",
"host": "maps.google.com",
"access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe",
"home_mobile_country_code": 310,
"home_mobile_network_code": 410,
"radio_type": "gsm",
"carrier": "Vodafone",
"request_address": true,
"address_language": "en_GB",
"location": {
"latitude": 51.0,
"longitude": -0.1
},
"cell_towers": [
{
"cell_id": 42,
"location_area_code": 415,
"mobile_country_code": 310,
"mobile_network_code": 410,
"age": 0,
"signal_strength": -60,
"timing_advance": 5555
},
{
"cell_id": 88,
"location_area_code": 415,
"mobile_country_code": 310,
"mobile_network_code": 580,
"age": 0,
"signal_strength": -70,
"timing_advance": 7777
}
],
"wifi_towers": [
{
"mac_address": "01-23-45-67-89-ab",
"signal_strength": 8,
"age": 0
},
{
"mac_address": "01-23-45-67-89-ac",
"signal_strength": 4,
"age": 0
}
]
}And here is a typical server response:
{
"location": {
"latitude": 51.0,
"longitude": -0.1,
"altitude": 30.1,
"accuracy": 1200.4,
"altitude_accuracy": 10.6,
"address": {
"street_number": "100",
"street": "Amphibian Walkway",
"postal_code": "94043",
"city": "Mountain View",
"county": "Mountain View County",
"region": "California",
"country": "United States of America",
"country_code": "US"
}
},
"access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
}Integration with Ruby on Rails
Requirements
- Basic Ruby on Rails knowledge
- The GeoKit plug-in
- A database that supports trigonometric functions (SQLite is not supported)
Getting things done
To get started you first need a rails project. If you need to create a new one you can use a similar command to the one I used
rails -D postgresql geocoding
and replace postgresql with your database type.
Now that we have a new project, change the working directory to it and install the geokit plug-in
$ cd geocoding $ script/plugin install git://github.com/andre/geokit-rails.git
Also, install the geokit gem if it's not already installed and added to your config/environment.rb' configuration file:
config.gem "geokit"
And now tell Rails to add it to the project:
rake gems:install
This example uses Google's geolocation services. Assuming you got your key, depending on which version of the GeoKit plug-in you're using, you will have to add it to its default configuration file either in config/environment.rb or in the config/initializers/geokit.rb file.
GeoKit::Geocoders::google = 'YOUR_GOOGLE_KEY_GOES_HERE'
Before we begin developing on our new project you should set the correct database configuration which ca be found in the file config/database.yml. The development database connection should look similar to:
development: adapter: postgresql encoding: utf8 database: geocoding_development username:password: pool: 5
Once all three database connections are correct we can create them using the following rake task:
rake db:create:all
Now it’s time to populate the database with some geocoded data. We’ll use scaffolding to create a location resource for that:
$ script/generate scaffold location name:string address:string lat:float lng:float $ rake db:migrate
This gives everything needed to start creating location data. However, we don’t know the latitude and longitude for an address, and even if we did, we wouldn’t want to be typing them in. So, we’ll let the geocoding service handle that. We’ll just add the acts_as_mappable method with the auto_geocode option to our location model class in app/models/location.rb
class Location < ActiveRecord::Base validates_presence_of :lat, :lng acts_as_mappable :auto_geocode => true end
There are some defaults you can overwrite in the acts_as_mapable for geocoding:
acts_as_mappable :default_units => :miles, :default_formula => :sphere, :distance_field_name => :distance, :lat_column_name => :lat, :lng_column_name => :lng
OK, now let’s use the console to see whether we have everything wired together:
$ ruby script/console >> l = Location.create(:name => "B-IT", :address => "Dahlmannstraße 2, 53113 Bonn, Germany") => #<Location id: 1, name: "B-IT", address: "Dahlmannstraße 2, 53113 Bonn, Germany", lat: 50.7190794, lng: 7.1217552, created_at: "2009-08-21 23:31:27", updated_at: "2009-08-21 23:31:27"> >> l.lat => 50.7190794 >> l.lng => 7.1217552
We now have created a Location record and it got automatically saved with it's latitude and longitude values.
If we wanted to do the same thing manually (or we just wanted more fine-grained control), we could have left off the :auto_geocode⇒true option and written this code instead:
class Location < ActiveRecord::Base validates_presence_of :lat, :lng acts_as_mappable before_validation_on_create :geocode_address private def geocode_address geo = GeoKit::Geocoders::MultiGeocoder.geocode(address) errors.add(:address, "Could not geocode address" ) unless geo.success self.lat, self.lng = geo.lat, geo.lng if geo.success end end
When we create a new Location object, the value of the address attribute is transparently sent to whichever
geocoding service we`ve configured. It then sends back the latitude and longitude values for the address, pokes them into our model attributes, and then carries on creating the record.
Now let's try to find a nearby location. This turns out to be trivial thanks to location-based find method options added by the GeoKit plug-in. Assuming we’ve entered a few more locations, we’ll use the console to find them ordered by distance from a given location, but only up to 5 kilometers away:
places=Location.find(:all, :origin => "Zentrum Bonn, Germany", :within => 5, :order => "distance") >> places.size => 4 >> places.first.distance => "0.759217322837196"
$ rake db:migrate when you are finished.
What happens is that find sends off a request to our geocoding service to get the latitude and longitude values for the address string we used as our origin. Then, it computes the distance from the origin’s latitude/longitude to the latitude/longitude of each of our restaurants by running a SQL query representing a trigonometric formula.4 In the process of performing the query, a distance attribute is added to all the Restaurant objects returned by the find. The distance attribute represents the distance (in miles, by default) from the origin we used in the query.
The I’m Feeling Lucky of geocoding (get the closest location), could be implemented like this:
Location.find :closest, :origin => "Zentrum, Bonn, Germany"
All we need now is a form that asks for the two variables, the address and the radius, and a controller action that runs the query. In the search action we’ll use the find with the location-based options again. Add the following code to
app/controllers/locations_controller.rb
def search @address = params[:address] @within = params[:within] @locations = Location.find :all, :origin => @address, :within => @within, :order => 'distance' respond_to do |format| format.html # index.html.erb format.xml { render :xml => @locations } end end
On the search results page, we’ll list the locations and put them on a Google map
app/views/locations/search.html.erb
<h1><strong><%= pluralize(@locations.size, 'location') %></strong> within <strong><%= h pluralize(@within, 'kilometer') %></strong>:</h1> <ul> <% for location in @locations -%> <li> <p> <strong><%= link_to location.name, location %></strong> at <%= h location.address %><br/> <i>(<%= sprintf("%.2f" , location.distance) %> km away)</i> </p> </li> <% end -%> </ul> <div id="map_canvas" style="width:500px; height:300px;"></div>
The empty div at the bottom of the search results page is the place where we will put our map.
To do that, first we’ll add the following code to the <head> section of our layout file to include the Google Maps JavaScript code. Here the version 3(beta) maps API will be used and doesn not require a key. It also outputs @locations as JSON if @locations is available:
app/views/layouts/locations.html.erb
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
</script>
<% if @locations -%>
<script type="text/javascript">
var locations = <%= @locations.to_json %>;
</script>
<% end -%>
<%= javascript_include_tag :defaults %>
and in the body tag you should call a function to initialize our map like this:
<body style="margin:0px; padding:0px;" onload="initialize()">
Now we need to add some JavaScript to instantiate the map in our map_canvas div, loop through the locations (made available to the JavaScript code as JSON), and add the markers. We’ll just toss all this into our public/javascripts/application.js file:
function initialize() { var center = new google.maps.LatLng(50.732008, 7.097136); var myOptions = { zoom: 10, center: center, mapTypeId: google.maps.MapTypeId.HYBRID }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); // Clicking the marker will hide it function createMarker(latlng, location, map) { var marker = new google.maps.Marker({ position: latlng, map: map, title: location.name }); var infoContent="<strong>" +location.name+"</strong><br />" + location.address; var infowindow = new google.maps.InfoWindow({ content: infoContent }); google.maps.event.addListener(marker, 'click' , function() { if(marker.isOpen){ infowindow.close(); marker.isOpen = false; } else{ infowindow.open(map,marker); marker.isOpen = true; } }); return marker; } var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < locations.length; i++) { var location = locations[i].location; var latlng = new google.maps.LatLng(location.lat,location.lng); bounds.extend(latlng); createMarker(latlng, location, map); } map.fitBounds(bounds); }
Now, for the final touch build a form to call our search action and include the action in config/routes.rb
config/routes.rb
map.resources :locations, :collection => {:search => :get}
This is a possible form which you can add in your apps/views/locations/index.html.erb file
<h1>Find location near you!</h1> <% form_tag search_locations_path do -%> <p> <strong>Address</strong><br /> <%= text_field_tag :address, params[:address], :size => 35 %> </p> <p> <strong>Within</strong><br /> <%= select_tag :within, options_for_select([1, 5, 10, 25]) %> km </p> <p> <%= submit_tag "Find Locations" :disable_with => "Please wait..."%> </p> <% end -%>
Now when the search results page is rendered, we get a Google map with markers that shows the name and address of nearby locations.
Using W3C Geolocation API
The Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation, such as latitude and longitude. The API itself is agnostic of the underlying location information sources. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. No guarantee is given that the API returns the device's actual location.
Now, using this new toy, we want to get the users current position in our application. To do that, we will first add a new button on our main page to trigger automatic location detection and a place where to put that information:
<div id="messageLocation"></div><br> <button onClick="navigator.geolocation.getCurrentPosition(locationHandler, function(error){var message = document.getElementById('messageLocation'); message.innerHTML='Error Code: ' + error.code + '<br>Message: ' + error.message;}, {enableHighAccuracy:true});">Auto detect location</button>
We have a button to invoke the geolocation api, but now locationHandler. Let's define one in the public/javascript/application.js file:
function locationHandler(location) { var message = document.getElementById("messageLocation"); message.innerHTML="Longitude: " + location.coords.longitude + "<br>"; message.innerHTML+="Accuracy: " + location.coords.accuracy + "<br>"; message.innerHTML+="Latitude: " + location.coords.latitude; codeLatLng(location.coords) }
The last line is for calling a method to reverse geocode our location in order to find out an address. We will define such a method shortly, but first you can test your application to see how it goes so far. To reverse geocode the location we will use the Google Maps API from JavaScript. Of course we could use also the geokit plug-in from the Rails server, but that would imply performing an action which for now it is not necessay (as we do not store the result or interact with the database). Add the following function to the same file as before:
function codeLatLng(position) { var latlng = new google.maps.LatLng(position.latitude, position.longitude); if(!geocoder) geocoder = new google.maps.Geocoder(); if (geocoder) { geocoder.geocode({'latLng': latlng}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if (results[1]) { document.getElementById("address").value = results[1].formatted_address; } else { alert("No results found"); } } else { alert("Geocoder failed due to: " + status); } }); } }
The final task is to add a geocoder global variable to be shared by the whole application in your layaout file from app/view/layouts/locations.html.erb
<script type="text/javascript"> var geocoder; </script>
References
- Location based services on Wikipedia
- Geokit gem Readme
See Also
Skyhook Wireless’ Loki provides Javascript hooks to WiFi Geolocation


