What isgeolocation?
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: homin...
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!Lets join the party
Cool!Lets join the party      introducing: Stalk my Friends
1st step: display a map    Well use Google Maps    # app/views/layouts/application.html.slim    = javascript_include_tag h...
2nd step: geolocate    if (navigator.geolocation) {        navigator.geolocation.getCurrentPosition(            function(p...
Geolocation APIsupported by all current browerslocation sources:  1. GPS  2. WiFi/Bluetooth MAC address  3. GSM/CDMA cell ...
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 reques...
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[:qu...
Awesome! We have a user position.    Now to interact with other users we need:store lat/long (and address, eventually) in ...
1st approach: D.I.Y. I # migration class CreateUsers  ActiveRecord::Migration   def change     create_table :users do |t| ...
1st approach: D.I.Y. II # app/controllers/users_controller.rb class UsersController  ApplicationController   respond_to :j...
1st approach: D.I.Y. III # app/models/user.rb class User  ActiveRecord::Base   attr_accessible :address, :latitude, :longi...
Let’s do some math Earth is a sphere: coordinates are in degree, distance is in meters. Solve the second (inverse) geodeti...
Haversine formula  d = 2r arcsin   h(φ2 − φ1 ) + cos(φ1 ) cos(φ2 ) h(ψ2 − ψ1 )                   (1)    =2 r arcsin   sin2...
Geocoder to the rescue!    # app/models/user.rb    geocoded_by :address    reverse_geocoded_by :latitude, :longitude    af...
Geocoder goodies # Nearest point user = User.near(Firenze, 50, :order = distance).first # distance from arbitrary point to...
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 a...
PostGIS setup # install on a ubuntu box sudo apt-get install postgresql-9.1-postgis # prepare the db createdb template_pos...
PostGIS features PostGIS follows the OpenGIS Simple Features Specication for SQL [11]     data types for points, linestrin...
PostGIS with Ruby Well 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_friend...
PostGIS query     # app/models/user.rb     def nearbys(radius)       radius = radius.to_i*1000       User.where( ST_Distan...
Questions?
Thanks for watching! Francesco Disperati | @nebirhos                http://nebirhos.com Source code of the demo app availa...
Random stuff cited   Google Geocode API        https://developers.google.com/maps/documentation/geocoding/   Yahoo! PlaceF...
Geolocation on Rails
Geolocation on Rails
Geolocation on Rails
Nächste SlideShare
Wird geladen in ...5
×

Geolocation on Rails

13,148

Published on

Published in: Technologie, Business
0 Kommentare
31 Gefällt mir
Statistiken
Notizen
  • Hinterlassen Sie den ersten Kommentar

Keine Downloads
Views
Gesamtviews
13,148
Bei Slideshare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
31
Einbettungen 0
No embeds

No notes for slide

Transcript of "Geolocation on Rails"

  1. 1. What isgeolocation?
  2. 2. identication of a real-world geographic location
  3. 3. identication of a real-world geographic location = context
  4. 4. 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
  5. 5. Brief history: modern era early 1900s: radio triangulation 1960s: satellite GPS 1990s: automotive GPS navigation
  6. 6. Brief history: web era late 1990s: IP lookup mid 2000s: WiFi, GSM relevation 2004: A-GPS on smartphones
  7. 7. Brief history: web era late 1990s: IP lookup mid 2000s: WiFi, GSM relevation 2004: A-GPS on smartphones
  8. 8. Location-aware apps Later also Google, Facebook, and Twitter
  9. 9. Cool!Lets join the party
  10. 10. Cool!Lets join the party introducing: Stalk my Friends
  11. 11. 1st step: display a map Well 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
  12. 12. 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
  13. 13. Geolocation APIsupported by all current browerslocation sources: 1. GPS 2. WiFi/Bluetooth MAC address 3. GSM/CDMA cell IDs 4. IP addressone-shot vs continuous
  14. 14. Geocode New feature: set the position manually.
  15. 15. Geocode New feature: set the position manually. We need to geocode the address.
  16. 16. 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...
  17. 17. Gems for geocode Geokit (deprecated, still lacks support for Rails 3) [7] Graticule [6] Geocoder [8]
  18. 18. 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
  19. 19. Awesome! We have a user position. Now to interact with other users we need:store lat/long (and address, eventually) in a DBquery the DB for nearby points
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. 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: Vincentys formulae
  24. 24. 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
  25. 25. 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
  26. 26. 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]
  27. 27. Geocoder considerations Pros simple and easy to use Cons only circle areas SLOW (depends on the DBMS)
  28. 28. 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
  29. 29. 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’;
  30. 30. 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
  31. 31. PostGIS with Ruby Well use gem activerecord-postgis-adapter to integrate postgis data types in ActiveRecord.
  32. 32. 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
  33. 33. 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) endgit: master
  34. 34. Questions?
  35. 35. 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
  36. 36. 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

×