Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OSCON july 2011

1,262 views

Published on

Published in: Technology
  • Be the first to comment

OSCON july 2011

  1. 1. +OPEN GEOSPATIAL RUBY LIBRARIES Christopher Helm - GeoIQ http://geocommons.com
  2. 2. The Plan• Keep it simple• Introduce you to geospatial• Dive into a few example libs• Demo some code!
  3. 3. THIS TALK......is for (~Ruby) geospatial newcomers
  4. 4. STAYING SIMPLE GeoSpatial is a deep subjectwe’re barely skimming the surface
  5. 5. WHAT IS GEOSPATIAL?
  6. 6. LOCATION
  7. 7. DATA
  8. 8. ANALYSIS
  9. 9. VISUALIZATION
  10. 10. WHY DOES THIS MATTER? location is everywhere :)
  11. 11. GEOGRAPHY LESSON 1: Vector Data TypesPoints Lines Polygons
  12. 12. GEOGRAPHY LESSON 1: OGC’s Simple Features POINT(30, 40) LINESTRING(30 10, 10 30, 40 40)POLYGON(30 10, 10 20, 20 40, 40 40, 30 10) MULTI*
  13. 13. GEOGRAPHY LESSON 2: Spatial Relationships Buffers Intersections Clips Dissolves Unions Aggregation etc...
  14. 14. GEOGRAPHY LESSON 2: Spatial Relationships Buffers
  15. 15. GEOGRAPHY LESSON 2: Spatial Relationships Dissolves
  16. 16. GEOGRAPHY LESSON 2: Spatial Relationships Clips Intersections
  17. 17. GEOGRAPHY LESSON 2: Spatial Relationships Spatial Aggregation
  18. 18. GEOGRAPHY LESSON 3: Spatial Reference Systems http://www.cartogrammar.com/blog/accidental-map-projections/
  19. 19. GEOGRAPHY LESSON 3: Spatial Reference Systems Plate Carrée, Geographic, or un-projected
  20. 20. GEOGRAPHY LESSON 3: Spatial Reference Systems Spherical Mercator (Web Mercator)
  21. 21. SOME GEOSPATIAL LIBS•2 categories of libraries • 1. Ruby based GeoSpatial Data Libraries • 2. Ruby bindings location-aware APIs & services
  22. 22. GEOS http://trac.osgeo.org/geos/Geometry Engine - Open Source (GEOS) A C++ port of the Java Topology Suite Simple Features and spatial operators
  23. 23. GEOSrequire geos@reader = Geos::WktReader.new()# Create pointsp1 = @reader.read(‘POINT(1, 2)’)p2 = @reader.read(‘POINT(3, 4)’)p3 = @reader.read(‘POINT(5, 2)’) p2 y p1 p3 x
  24. 24. GEOS# Create a more complex shapesline1 = @reader.read(‘LINESTRING(1 2, 3 4, 5 2)’)polygon = @reader.read(‘POLYGON(1 2, 3 4, 5 2, 1 2)’)line2 = @reader.read(LINESTRING(1 4, 4 1)) line1 Polygon line2
  25. 25. GEOS# Perform geometric operations and calculationsline3 = polygon.intersection(line2)dist = line3.distance(p3) line2 dist line3 p3 line3
  26. 26. GEOS# new pointp4 = @reader.read(‘POINT(2.5, 3.5)’)# create a buffer on p4buffer = p4.buffer(2)# now test against the bufferbuffer.contains?(p1) # falsebuffer.contains?(p2) # truebuffer.touches?(p3.buffer(1)) # true p2 p4 p1 p3 buffer
  27. 27. GEORUBY http://rubyforge.org/projects/georuby/A Library for working with geometric data types in Ruby follows the OGC’s Simple Features Spec Think: Point, Lines, and Polygons Also data formatters / parsers (KML to Well Known Text)
  28. 28. SPATIAL ADAPTER https://github.com/fragility/spatial_adapterxt Adapter for ActiveRecordHandles spatial datatypes coming from: PostGreSQL (via PostGIS) & MySQL (via its spatial ext.)
  29. 29. RGEO http://virtuoso.rubyforge.org/rgeo/ Geospatial datatypes in Ruby Standard Spatial analysis operations: (buffers, intersections, distances, etc) Data format conversionsFlexible - gem and active-record adapter
  30. 30. RUBY GEOCODER http://www.rubygeocoder.com/ Full featured geocoder for Ruby Gem and Rails PluginConverts addresses and IPs in lat/lon coordinates configurable to work with any service Also checkout geokit: http://geokit.rubyforge.org/
  31. 31. RUBY GEOCODER http://www.rubygeocoder.com/require ‘geocoder’# look up coordinates of some locationGeocoder.coordinates("25 Main St, Cooperstown, NY")=> [42.700149, -74.922767]# distance between Eiffel Tower and Empire State BuildingGeocoder::Calculations.distance_between([47.858205,2.294359],[40.748433,-73.985655])=> 3619.77359999382# find the geographic coordinates for an IP addressGeocoder.coordinates("71.166.236.36")=> [38.6485, -77.3108]
  32. 32. DATABASES PostgreSQL / Postgis MySQL MongoDBCouch...DB....base (via GeoCouch)
  33. 33. POSTGRESQL PostGIS - spatial extensionUses GEOS for spatial operations
  34. 34. ACTIVERECORD POSTGIS https://github.com/dazuma/activerecord-postgis-adaptercreate_table :my_spatial_table do |t| t.column :shape, :geometry # or t.geometry :shape t.line_string :path, :srid => 3785 t.point :latlon, :geographic => trueendchange_table :my_spatial_table do |t| t.index :latlon, :spatial => trueend# queryingrec = MySpatialTable.where(:latlon => POINT(-122 47)).first
  35. 35. MONGODBrequire mongodb = Mongo::Connection.new("localhost", 27017).db("mydb")auth = db.authenticate(my_user_name, my_password)coll = db.collection("testCollection")coll.find("i" => 71).each { |row| puts row.inspect }
  36. 36. MONGODB# Spatial indexes / queriescoll.create_index([["loc", Mongo::GEO2D]])coll.find({"loc" => {"$near" => [50, 50]}}, {:limit => 20}).eachdo |p| puts p.inspectend
  37. 37. MONGODBbox = [[40.73083, -73.99756], [40.741404, -73.988135]]coll.find({"loc" : {"$within" : {"$box" : box}}})center = [50, 50]radius = 10coll.find({"loc" : {"$within" : {"$center" : [center, radius]}}})
  38. 38. SOCIAL MEDIA APIS
  39. 39. TWEETSTREAM https://github.com/intridea/tweetstreamSimple wrapper to the Twitter Streaming API Can search via tags or locations (via bboxes)Good way to generate geospatial data/content
  40. 40. TWEETSTREAMrequire rubygemsrequire tweetstream# Use track to track a list of single-word keywordsTweetStream::Client.new(username,password).track(term1,term2) do |status| puts "#{status.text}"end# track tweets within a bboxTweetStream::Client.new(username,password).locations(‘-122.75,36.8,-121.75,37.8’) do |status| puts "#{status.text}"end
  41. 41. INSTAGRAM https://github.com/Instagram/instagram-ruby-gemWrapper to the Instragram’s photo sharing API Allows for spatial searching via lat/lon very similar to the Flick’r API
  42. 42. CARTAGR.AM bloom.io
  43. 43. INSTAGRAMrequire "instagram"# All methods require authenticationInstagram.configure do |config| config.client_id = YOUR_CLIENT_KEY config.access_token = YOUR_ACCESS_TOKENend# Get a list of media at a given locationputs Instagram.location_recent_media(514276)# Get a list of media close to a given latitude and longitudeputs Instagram.media_search("37.7808851,-122.3948632")
  44. 44. YELP! http://github.com/shaper/yelp Location based lookup for business reviewsHighly local listing accessed in variety of geospatial ways another way to create some geospatial data/content
  45. 45. YELP!
  46. 46. YELP!# create a new client client = Yelp::Client.new# do an address-based search for cream puffs nearbyrequest = Yelp::Review::Request::Location.new( :address => 650 Mission St, :city => San Francisco, :state => CA, :radius => 2, :term => cream puffs, :yws_id => YOUR_YWSID_HERE)response = client.search(request)
  47. 47. YELP!# a location-based search for ice cream or donut shops in SFrequest = Yelp::Review::Request::Location.new( :city => San Francisco, :state => CA, :category => [ donuts, icecream ], :yws_id => YOUR_YWSID_HERE)response = client.search(request)# a neighborhood name lookup for a geo-location pointrequest = Yelp::Neighborhood::Request::GeoPoint.new( :latitude => 37.782093, :longitude => -122.483230, :yws_id => YOUR_YWSID_HERE)response = client.search(request)
  48. 48. DATA & ANALYSIS APIS Fusion Tables
  49. 49. SIMPLEGEO https://github.com/simplegeo/simplegeo-ruby API for adding geospatial capabilities to appsAccess POIs, Locational Context, and personal data Emphasis on speed, simplicity, and flexibility
  50. 50. SIMPLEGEO Context API# grab the context of a lat/lonSimpleGeo::Client.get_context(37.772445,-122.405913)# contextSimpleGeo::Client.get_context_by_address("41 Decatur St, SanFrancisco, CA 94103")SimpleGeo::Client.get_context_ip("184.84.228.110")
  51. 51. SIMPLEGEO Places APISimpleGeo::Client.get_places(37.772445, -122.405913)options = {q=>Starbucks, category=>Coffee & Tea,radius=>5}SimpleGeo::Client.get_places(37.772445, -122.405913, options)address = "41 Decatur St, San Francisco, CA"options = {radius => 1}SimpleGeo::Client.get_places_by_address(address, options)ip = 173.164.219.53SimpleGeo::Client.get_places_by_ip(ip)
  52. 52. FUSION TABLES https://github.com/tokumine/fusion_tablesDirect access to Google’s Fusion Tables APIFull SQL interface or OO query interfaceEasy integration to other Google services (maps, earth, viz.) Easy storage/retrieve of geospatial data
  53. 53. FUSION TABLESrequire fusion_tables# Connect to service@ft = GData::Client::FusionTables.new@ft.clientlogin(username, password)# 1. SQL interface@ft.execute "SHOW TABLES"@ft.execute "INSERT INTO #{my_table_id} (name, geo) VALUES(tokyo, 35.6894 139.6917);"@ft.execute "SELECT count() FROM #{my_table_id};"
  54. 54. GEOCOMMONS http://geocommons.comOpen Data Storage, Analysis, and Visualization Strong emphasis on usability Build complex geospatial workflows Share data visualizations on the web
  55. 55. GEOCOMMONS CSV Easy Spatial Visualization / Analytics SHPJSONWMS Maps & Viz Analytics
  56. 56. GEOCOMMONS GEM API GeoCommons Mgmt Analysis Visualization geoiq- ruby
  57. 57. GEOCOMMONS GEM finding data...# create a client@geoiq = Geoiq.client("http://geocommons.com", "user", "password")# search for tags@geoiq.search("tag:economics")# Search for data in a location@geoiq.search("points",{:bbox => ‘-87.2,33.4,-75.9,38.4, :limit=>10})
  58. 58. GEOCOMMONS GEM getting data...# get dataset and featuresdataset = geoiq.dataset.find(1348)features = dataset.features# get features with a custom filterfiltered_features = @dataset.features({"filter[PERIMETER][][max]"=> 0.3})bbox_filtered_features = @dataset.features({:bbox =>-87.2,33.4,-75.9,38.4})
  59. 59. GEOCOMMONS uploading data...# Upload CSVcsv_file = data/sculptures.csv@dataset = @geoiq.dataset.csv_upload(csv_file, {:title =>"gardensculptures"})# Upload SHP@dataset = @geoiq.dataset.shp_upload("data/simple.shp", "data/simple.dbf", "data/simple.shx")# Upload by URL (type = csv,kml,rss,wms,tile)@dataset = @geoiq.dataset.url_upload("http://geothings.net/geoiq/simple_testing.csv", {:type => "csv"})
  60. 60. GEOCOMMONS create new datasets...# Create a new overlaydata = {‘title’ => ‘My Overlay’, ‘attributes’ => {‘attr1’ => ...}}overlay = @geoiq.dataset.create(data)# add features to the overlayfeatures = {features => [{‘type’ => ‘Point’, ‘coordinates’ =>[0,0]},{...}]}@geoiq.dataset.update(id, features)
  61. 61. GEOCOMMONS create new visualizations...# Create a new mapmap = @geoiq.map(:title => "my empty map")@geoiq_map = map.create# get a map and its layers@map = @geoiq.map.find(239)layer_titles = @map.layers.map{ |l| l[title]}# add a dataset to a map as a new layer@map.add_layer(1466)#deleting map or dataset@map.delete@dataset.delete
  62. 62. PUTTING IT TOGETHER
  63. 63. SOME EXAMPLES......THEN QUESTIONS
  64. 64. Code Samples from this talk:https://github.com/chelm/OSCON-Ruby-GeoSpatial-Intro

×