SlideShare a Scribd company logo
1 of 39
What is
geolocation?
identication of a real-world geographic
                location
identication of a real-world geographic
                location
                    =

        context
Brief history: early days


   many 1000s BC: smoke signals
   as early as 3200 BC: celestial navigation
   from 1000 BC: homing pigeons
   between 1100-1200 AD: the magnetic compass
Brief history: modern era


   early 1900s: radio triangulation
   1960s: satellite GPS
   1990s: automotive GPS navigation
Brief history: web era
   late 1990s: IP lookup
   mid 2000s: WiFi, GSM relevation
   2004: A-GPS on smartphones
Brief history: web era
   late 1990s: IP lookup
   mid 2000s: WiFi, GSM relevation
   2004: A-GPS on smartphones
Location-aware apps




 Later also Google, Facebook, and Twitter
Cool!
Let's join the party
Cool!
Let's join the party

      introducing:
 Stalk my Friends
1st step: display a map
    We'll use Google Maps

    # app/views/layouts/application.html.slim
    = javascript_include_tag https://maps.googleapis.com/maps/api/js


    // app/assets/javascripts/maps.js
    $(document).ready(function() {
        var mapOptions = {
            zoom: 8,
            center: new google.maps.LatLng(43.7710332, 11.2480006),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map($(’#map’)[0], mapOptions);
    });

git: google maps
2nd step: geolocate
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            function(p) {
                var latlng = new google.maps.LatLng(p.coords.latitude,
                                                    p.coords.longitude);
                $(’span#position’).text(latlng);
                if (myMarker) myMarker.setMap(null);
                myMarker = new google.maps.Marker(
                    {position: latlng, map: map, title: This is me}
                );
            },
            function(error) {
                alert(error.message);
            },
            {maximumAge: 600000}
        );
    }
    else { console.error(No HTML5? What are you using, IE6?); }
git: HTML5 geolocation
Geolocation API
supported by all current browers
location sources:
  1. GPS
  2. WiFi/Bluetooth MAC address
  3. GSM/CDMA cell IDs
  4. IP address
one-shot vs continuous
Geocode
 New feature: set the position manually.
Geocode
 New feature: set the position manually.
 We need to geocode the address.
Geocode
 New feature: set the position manually.
 We need to geocode the address.
 Several services:
     Google: 2.500 requests/day [1]
     Yahoo!: 50.000 requests/day [2]
     Bing: 50.000 requests/day [3]
     Nominatim: 1 request/second [4]
     FreeGeoIP: 1000 requests/hour [5]
     Geocoder.ca and Geocoder.us: ?
     many others...
Gems for geocode


   Geokit (deprecated, still lacks support for Rails 3) [7]
   Graticule [6]
   Geocoder [8]
Geocoder gem in action
 # Gemfile
 gem geocoder


 # map_controller.rb
 def geocode
   position = Geocoder.coordinates(params[:query])
   respond_to do |wants|
     wants.json { render :json = position }
   end
 end


 // applications.js
 $(’[data-action=cheat]’).click(function() {
     $.getJSON(’/geocode/’, {query: $(’#address’).val()}, map.cheat);
 });    git: geocoding
Awesome! We have a user position.
    Now to interact with other users we need:
store lat/long (and address, eventually) in a DB
query the DB for nearby points
1st approach: D.I.Y. I
 # migration
 class CreateUsers  ActiveRecord::Migration
   def change
     create_table :users do |t|
       t.string :name
       t.float :latitude
       t.float :longitude
       t.string :address

       t.timestamps
     end
   end
 end
1st approach: D.I.Y. II

 # app/controllers/users_controller.rb
 class UsersController  ApplicationController
   respond_to :json

   def index
     @users = @user.nearbys(params[:radius])
     respond_with @users
   end
 end
1st approach: D.I.Y. III

 # app/models/user.rb
 class User  ActiveRecord::Base
   attr_accessible :address, :latitude, :longitude, :name

   def nearbys(radius)
   # ... oh s@#!t
   end
 end
Let’s do some math

 Earth is a sphere: coordinates are in degree, distance is in
 meters.
 Solve the second (inverse) geodetic problem
 Given two points, determine the azimuth and length of the
 line (straight line, arc or geodesic) that connects them. [9]

     spherical model: Haversine formula (approximation)
     oblate spheroid model: Vincenty's formulae
Haversine formula

  d = 2r arcsin   h(φ2 − φ1 ) + cos(φ1 ) cos(φ2 ) h(ψ2 − ψ1 )                   (1)


    =2 r arcsin   sin2
                         φ2 − φ1
                            2
                                    + cos(φ1 ) cos(φ2 ) sin2
                                                                ψ2 − ψ1
                                                                   2
                                                                                (2)



 where:
     h() is the haversine function: h(θ) = sin(θ/2)              2
                                                                     =   1−cos(θ)
                                                                            2

     d distance
     r radius of the sphere (6371.0 km)
     φ1 , φ2 latitude of point 1 and latitude of point 2
     ψ1 , ψ2 longitude of point 1 and longitude of point 2
Geocoder to the rescue!
    # app/models/user.rb
    geocoded_by :address
    reverse_geocoded_by :latitude, :longitude
    after_validation :reverse_geocode


    # app/controllers/users_controller.rb
    def index
      @users = @user.nearbys(params[:radius])
      respond_with @users
    end

    Geocoder implements the Haversine formula
    directly in the SQL query.
git: Geocoder backend
Geocoder goodies
 # Nearest point
 user = User.near(Firenze, 50, :order = distance).first

 # distance from arbitrary point to user
 user.distance_from([40.714, 11.234])

 # Find the bearing (direction) between places
 bearing = user.bearing_to(Paris, France)
 Geocoder::Calculations.compass_point(bearing)
   = NW

 # find the geographic center (aka center of gravity)
 polygon = [user1, user2, [40.22,-73.99], user4]
 Geocoder::Calculations.geographic_center(polygon)
   = [35.14968, -90.048929]
Geocoder considerations

 Pros
   simple and easy to use

 Cons
   only circle areas
   SLOW (depends on the DBMS)
2nd approach: PostGIS




 PostGIS [10] is an extention for PostgreSQL that adds
 support for geographic objects.
 Alternatives are:
     MySQL: implements the datatype geometry
     Sqlite: with SpatiaLite extension
PostGIS setup
 # install on a ubuntu box
 sudo apt-get install postgresql-9.1-postgis


 # prepare the db
 createdb template_postgis
 createlang plpgsql template_postigs
 psql -Upostgres -d template_postgis -f   [...]/postgis.sql
 psql -Upostgres -d template_postgis -f   [...]/spatial_ref_sys.sql
 psql -Upostgres -d template_postgis -f   [...]/postgis_comments.sql
 # inside postgres console
 UPDATE pg_database SET datistemplate =   TRUE
 WHERE datname = ’template_postgis’;
PostGIS features

 PostGIS follows the OpenGIS Simple Features
 Specication for SQL [11]
     data types for points, linestrings, polygons, multipoints,
     multilinestrings, multipolygons and geometrycollections
     functions for measurement like area, distance, length
     and perimeter
     spatial indexes for high speed spatial querying
PostGIS with Ruby


 We'll use gem activerecord-postgis-adapter
 to integrate postgis data types in ActiveRecord.
ActiveRecord PostGIS
 # config/database.yml
 development:
   adapter: postgis
   encoding: unicode
   database: stalk_my_friends
   pool: 5
   username: nebirhos
   template: template_postgis


 # migration
 add_column :users, :position, :point, :geographic = true
 add_index :users, :position, :spatial = true


 # app/models/user.rb
 self.rgeo_factory_generator = RGeo::Geographic.simple_mercator_factory
 # SRID 4326, used by Google Maps
PostGIS query


     # app/models/user.rb
     def nearbys(radius)
       radius = radius.to_i*1000
       User.where( ST_Distance(position, ?, false) = ? ,
                   position, radius ).where(id  ?, id)
     end




git: master
Questions?
Thanks for watching!

 Francesco Disperati | @nebirhos
                http://nebirhos.com

 Source code of the demo app available at
 https://github.com/nebirhos/stalk-my-friends


    Special thanks to Cantiere Creativo and Silvia Shell
Random stuff cited
   Google Geocode API        https://developers.google.com/maps/documentation/geocoding/

   Yahoo! PlaceFinder      http://developer.yahoo.com/geo/placefinder/guide/responses.html

   Bing API    http://msdn.microsoft.com/en-us/library/ff701715.aspx

   Nominatim     http://wiki.openstreetmap.org/wiki/Nominatim

   FreeGeoIP    http://github.com/fiorix/freegeoip/blob/master/README.rst

   Graticule   http://graticule.rubyforge.org/

   Geokit   http://geokit.rubyforge.org/

   Geocoder    http://www.rubygeocoder.com/

   Geodesy on Wikipedia       http://en.wikipedia.org/wiki/Geodesy

   PostGIS   http://postgis.refractions.net/

   OpenGIS     http://www.opengeospatial.org/standards/sfs

   PostGIS ActiveRecord Adapter            https://github.com/dazuma/activerecord-postgis-adapter

More Related Content

What's hot

Material geometria 6º ano
Material geometria   6º anoMaterial geometria   6º ano
Material geometria 6º ano
Marcia MMs
 
Mat funcoes 002 exercicios
Mat funcoes  002 exerciciosMat funcoes  002 exercicios
Mat funcoes 002 exercicios
trigono_metrico
 
Introduction au webmapping au-dela de google maps
Introduction au webmapping  au-dela de google mapsIntroduction au webmapping  au-dela de google maps
Introduction au webmapping au-dela de google maps
VisionGÉOMATIQUE2012
 
Sólidos geométricos
Sólidos geométricosSólidos geométricos
Sólidos geométricos
reinecke.reis
 
Fração e porcentagem (lista de exercício)
Fração e porcentagem (lista de exercício)Fração e porcentagem (lista de exercício)
Fração e porcentagem (lista de exercício)
Prof. Leandro
 

What's hot (20)

Exercícios sobre as aplicações das leis de newton
Exercícios sobre as aplicações das leis de newtonExercícios sobre as aplicações das leis de newton
Exercícios sobre as aplicações das leis de newton
 
Material geometria 6º ano
Material geometria   6º anoMaterial geometria   6º ano
Material geometria 6º ano
 
NDGeospatialSummit2019 - ArcGIS Pro – Next-Generation Desktop GIS
NDGeospatialSummit2019 - ArcGIS Pro – Next-Generation Desktop GISNDGeospatialSummit2019 - ArcGIS Pro – Next-Generation Desktop GIS
NDGeospatialSummit2019 - ArcGIS Pro – Next-Generation Desktop GIS
 
Introduction and Overview of BigData, Hadoop, Distributed Computing - BigData...
Introduction and Overview of BigData, Hadoop, Distributed Computing - BigData...Introduction and Overview of BigData, Hadoop, Distributed Computing - BigData...
Introduction and Overview of BigData, Hadoop, Distributed Computing - BigData...
 
Mat funcoes 002 exercicios
Mat funcoes  002 exerciciosMat funcoes  002 exercicios
Mat funcoes 002 exercicios
 
How to Easily Read and Write CityGML Data (Without Coding)
How to Easily Read and Write CityGML Data (Without Coding)How to Easily Read and Write CityGML Data (Without Coding)
How to Easily Read and Write CityGML Data (Without Coding)
 
Introduction au webmapping au-dela de google maps
Introduction au webmapping  au-dela de google mapsIntroduction au webmapping  au-dela de google maps
Introduction au webmapping au-dela de google maps
 
Hadoop Internals
Hadoop InternalsHadoop Internals
Hadoop Internals
 
Cartographie - Introduction générale
Cartographie - Introduction généraleCartographie - Introduction générale
Cartographie - Introduction générale
 
Sólidos geométricos
Sólidos geométricosSólidos geométricos
Sólidos geométricos
 
Hadoop Oozie
Hadoop OozieHadoop Oozie
Hadoop Oozie
 
Gabarito Prova Física 1 ano Ensino Médio Colégio Pedro II - Centro
Gabarito Prova Física 1 ano Ensino Médio Colégio Pedro II - CentroGabarito Prova Física 1 ano Ensino Médio Colégio Pedro II - Centro
Gabarito Prova Física 1 ano Ensino Médio Colégio Pedro II - Centro
 
6º ano 3º bimestre
6º ano 3º bimestre6º ano 3º bimestre
6º ano 3º bimestre
 
지리정보체계(GIS) - [2] 좌표계 이해하기
지리정보체계(GIS) - [2] 좌표계 이해하기지리정보체계(GIS) - [2] 좌표계 이해하기
지리정보체계(GIS) - [2] 좌표계 이해하기
 
Future Directions for Compute-for-Graphics
Future Directions for Compute-for-GraphicsFuture Directions for Compute-for-Graphics
Future Directions for Compute-for-Graphics
 
Geopandas.pptx
Geopandas.pptxGeopandas.pptx
Geopandas.pptx
 
GINCANA MATEMÁTICA(ÁREA DE FIGURAS PLANAS) 6º ao 9º ano)
GINCANA MATEMÁTICA(ÁREA DE FIGURAS PLANAS) 6º ao 9º ano)GINCANA MATEMÁTICA(ÁREA DE FIGURAS PLANAS) 6º ao 9º ano)
GINCANA MATEMÁTICA(ÁREA DE FIGURAS PLANAS) 6º ao 9º ano)
 
QGIS 실습 (총 7차시)
QGIS 실습 (총 7차시)QGIS 실습 (총 7차시)
QGIS 실습 (총 7차시)
 
Fração e porcentagem (lista de exercício)
Fração e porcentagem (lista de exercício)Fração e porcentagem (lista de exercício)
Fração e porcentagem (lista de exercício)
 
[공간정보시스템 개론] L05 우리나라의 수치지도
[공간정보시스템 개론] L05 우리나라의 수치지도[공간정보시스템 개론] L05 우리나라의 수치지도
[공간정보시스템 개론] L05 우리나라의 수치지도
 

Similar to Geolocation on Rails

OSCON july 2011
OSCON july 2011OSCON july 2011
OSCON july 2011
chelm
 
Geo distance search with my sql presentation
Geo distance search with my sql presentationGeo distance search with my sql presentation
Geo distance search with my sql presentation
GSMboy
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4
MongoDB
 
Python en la Plataforma ArcGIS
Python en la Plataforma ArcGISPython en la Plataforma ArcGIS
Python en la Plataforma ArcGIS
Xander Bakker
 
Mashup caravan android-talks
Mashup caravan android-talksMashup caravan android-talks
Mashup caravan android-talks
honjo2
 

Similar to Geolocation on Rails (20)

Geopy module in python
Geopy module in pythonGeopy module in python
Geopy module in python
 
Geo search introduction
Geo search introductionGeo search introduction
Geo search introduction
 
OSCON july 2011
OSCON july 2011OSCON july 2011
OSCON july 2011
 
Sample document
Sample documentSample document
Sample document
 
Geo distance search with my sql presentation
Geo distance search with my sql presentationGeo distance search with my sql presentation
Geo distance search with my sql presentation
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4
 
2017 RM-URISA Track: Spatial SQL - The Best Kept Secret in the Geospatial World
2017 RM-URISA Track:  Spatial SQL - The Best Kept Secret in the Geospatial World2017 RM-URISA Track:  Spatial SQL - The Best Kept Secret in the Geospatial World
2017 RM-URISA Track: Spatial SQL - The Best Kept Secret in the Geospatial World
 
Gmaps Railscamp2008
Gmaps Railscamp2008Gmaps Railscamp2008
Gmaps Railscamp2008
 
Geolocation
GeolocationGeolocation
Geolocation
 
Python en la Plataforma ArcGIS
Python en la Plataforma ArcGISPython en la Plataforma ArcGIS
Python en la Plataforma ArcGIS
 
Geopy Module in Python
Geopy Module in PythonGeopy Module in Python
Geopy Module in Python
 
Mashup caravan android-talks
Mashup caravan android-talksMashup caravan android-talks
Mashup caravan android-talks
 
GeoDjango & HTML5 Geolocation
GeoDjango & HTML5 GeolocationGeoDjango & HTML5 Geolocation
GeoDjango & HTML5 Geolocation
 
Geolocation and Mapping
Geolocation and MappingGeolocation and Mapping
Geolocation and Mapping
 
Pycon2011
Pycon2011Pycon2011
Pycon2011
 
GeoAdmin API & Mobile API, 2012
GeoAdmin API & Mobile API, 2012GeoAdmin API & Mobile API, 2012
GeoAdmin API & Mobile API, 2012
 
Saving Gaia with GeoDjango
Saving Gaia with GeoDjangoSaving Gaia with GeoDjango
Saving Gaia with GeoDjango
 
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
 
Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone...
Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone...Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone...
Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone...
 
Opensource gis development - part 2
Opensource gis development - part 2Opensource gis development - part 2
Opensource gis development - part 2
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Recently uploaded (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 

Geolocation on Rails

  • 1.
  • 3. identication of a real-world geographic location
  • 4. identication of a real-world geographic location = context
  • 5. Brief history: early days many 1000s BC: smoke signals as early as 3200 BC: celestial navigation from 1000 BC: homing pigeons between 1100-1200 AD: the magnetic compass
  • 6. Brief history: modern era early 1900s: radio triangulation 1960s: satellite GPS 1990s: automotive GPS navigation
  • 7. Brief history: web era late 1990s: IP lookup mid 2000s: WiFi, GSM relevation 2004: A-GPS on smartphones
  • 8. Brief history: web era late 1990s: IP lookup mid 2000s: WiFi, GSM relevation 2004: A-GPS on smartphones
  • 9. Location-aware apps Later also Google, Facebook, and Twitter
  • 11. Cool! Let's join the party introducing: Stalk my Friends
  • 12.
  • 13. 1st step: display a map We'll use Google Maps # app/views/layouts/application.html.slim = javascript_include_tag https://maps.googleapis.com/maps/api/js // app/assets/javascripts/maps.js $(document).ready(function() { var mapOptions = { zoom: 8, center: new google.maps.LatLng(43.7710332, 11.2480006), mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map($(’#map’)[0], mapOptions); }); git: google maps
  • 14. 2nd step: geolocate if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function(p) { var latlng = new google.maps.LatLng(p.coords.latitude, p.coords.longitude); $(’span#position’).text(latlng); if (myMarker) myMarker.setMap(null); myMarker = new google.maps.Marker( {position: latlng, map: map, title: This is me} ); }, function(error) { alert(error.message); }, {maximumAge: 600000} ); } else { console.error(No HTML5? What are you using, IE6?); } git: HTML5 geolocation
  • 15. Geolocation API supported by all current browers location sources: 1. GPS 2. WiFi/Bluetooth MAC address 3. GSM/CDMA cell IDs 4. IP address one-shot vs continuous
  • 16.
  • 17. Geocode New feature: set the position manually.
  • 18. Geocode New feature: set the position manually. We need to geocode the address.
  • 19. Geocode New feature: set the position manually. We need to geocode the address. Several services: Google: 2.500 requests/day [1] Yahoo!: 50.000 requests/day [2] Bing: 50.000 requests/day [3] Nominatim: 1 request/second [4] FreeGeoIP: 1000 requests/hour [5] Geocoder.ca and Geocoder.us: ? many others...
  • 20. Gems for geocode Geokit (deprecated, still lacks support for Rails 3) [7] Graticule [6] Geocoder [8]
  • 21. Geocoder gem in action # Gemfile gem geocoder # map_controller.rb def geocode position = Geocoder.coordinates(params[:query]) respond_to do |wants| wants.json { render :json = position } end end // applications.js $(’[data-action=cheat]’).click(function() { $.getJSON(’/geocode/’, {query: $(’#address’).val()}, map.cheat); }); git: geocoding
  • 22. Awesome! We have a user position. Now to interact with other users we need: store lat/long (and address, eventually) in a DB query the DB for nearby points
  • 23. 1st approach: D.I.Y. I # migration class CreateUsers ActiveRecord::Migration def change create_table :users do |t| t.string :name t.float :latitude t.float :longitude t.string :address t.timestamps end end end
  • 24. 1st approach: D.I.Y. II # app/controllers/users_controller.rb class UsersController ApplicationController respond_to :json def index @users = @user.nearbys(params[:radius]) respond_with @users end end
  • 25. 1st approach: D.I.Y. III # app/models/user.rb class User ActiveRecord::Base attr_accessible :address, :latitude, :longitude, :name def nearbys(radius) # ... oh s@#!t end end
  • 26. Let’s do some math Earth is a sphere: coordinates are in degree, distance is in meters. Solve the second (inverse) geodetic problem Given two points, determine the azimuth and length of the line (straight line, arc or geodesic) that connects them. [9] spherical model: Haversine formula (approximation) oblate spheroid model: Vincenty's formulae
  • 27. Haversine formula d = 2r arcsin h(φ2 − φ1 ) + cos(φ1 ) cos(φ2 ) h(ψ2 − ψ1 ) (1) =2 r arcsin sin2 φ2 − φ1 2 + cos(φ1 ) cos(φ2 ) sin2 ψ2 − ψ1 2 (2) where: h() is the haversine function: h(θ) = sin(θ/2) 2 = 1−cos(θ) 2 d distance r radius of the sphere (6371.0 km) φ1 , φ2 latitude of point 1 and latitude of point 2 ψ1 , ψ2 longitude of point 1 and longitude of point 2
  • 28. Geocoder to the rescue! # app/models/user.rb geocoded_by :address reverse_geocoded_by :latitude, :longitude after_validation :reverse_geocode # app/controllers/users_controller.rb def index @users = @user.nearbys(params[:radius]) respond_with @users end Geocoder implements the Haversine formula directly in the SQL query. git: Geocoder backend
  • 29. Geocoder goodies # Nearest point user = User.near(Firenze, 50, :order = distance).first # distance from arbitrary point to user user.distance_from([40.714, 11.234]) # Find the bearing (direction) between places bearing = user.bearing_to(Paris, France) Geocoder::Calculations.compass_point(bearing) = NW # find the geographic center (aka center of gravity) polygon = [user1, user2, [40.22,-73.99], user4] Geocoder::Calculations.geographic_center(polygon) = [35.14968, -90.048929]
  • 30. Geocoder considerations Pros simple and easy to use Cons only circle areas SLOW (depends on the DBMS)
  • 31. 2nd approach: PostGIS PostGIS [10] is an extention for PostgreSQL that adds support for geographic objects. Alternatives are: MySQL: implements the datatype geometry Sqlite: with SpatiaLite extension
  • 32. PostGIS setup # install on a ubuntu box sudo apt-get install postgresql-9.1-postgis # prepare the db createdb template_postgis createlang plpgsql template_postigs psql -Upostgres -d template_postgis -f [...]/postgis.sql psql -Upostgres -d template_postgis -f [...]/spatial_ref_sys.sql psql -Upostgres -d template_postgis -f [...]/postgis_comments.sql # inside postgres console UPDATE pg_database SET datistemplate = TRUE WHERE datname = ’template_postgis’;
  • 33. PostGIS features PostGIS follows the OpenGIS Simple Features Specication for SQL [11] data types for points, linestrings, polygons, multipoints, multilinestrings, multipolygons and geometrycollections functions for measurement like area, distance, length and perimeter spatial indexes for high speed spatial querying
  • 34. PostGIS with Ruby We'll use gem activerecord-postgis-adapter to integrate postgis data types in ActiveRecord.
  • 35. ActiveRecord PostGIS # config/database.yml development: adapter: postgis encoding: unicode database: stalk_my_friends pool: 5 username: nebirhos template: template_postgis # migration add_column :users, :position, :point, :geographic = true add_index :users, :position, :spatial = true # app/models/user.rb self.rgeo_factory_generator = RGeo::Geographic.simple_mercator_factory # SRID 4326, used by Google Maps
  • 36. PostGIS query # app/models/user.rb def nearbys(radius) radius = radius.to_i*1000 User.where( ST_Distance(position, ?, false) = ? , position, radius ).where(id ?, id) end git: master
  • 38. Thanks for watching! Francesco Disperati | @nebirhos http://nebirhos.com Source code of the demo app available at https://github.com/nebirhos/stalk-my-friends Special thanks to Cantiere Creativo and Silvia Shell
  • 39. Random stuff cited Google Geocode API https://developers.google.com/maps/documentation/geocoding/ Yahoo! PlaceFinder http://developer.yahoo.com/geo/placefinder/guide/responses.html Bing API http://msdn.microsoft.com/en-us/library/ff701715.aspx Nominatim http://wiki.openstreetmap.org/wiki/Nominatim FreeGeoIP http://github.com/fiorix/freegeoip/blob/master/README.rst Graticule http://graticule.rubyforge.org/ Geokit http://geokit.rubyforge.org/ Geocoder http://www.rubygeocoder.com/ Geodesy on Wikipedia http://en.wikipedia.org/wiki/Geodesy PostGIS http://postgis.refractions.net/ OpenGIS http://www.opengeospatial.org/standards/sfs PostGIS ActiveRecord Adapter https://github.com/dazuma/activerecord-postgis-adapter