PostGIS on Rails
-
Upload
matt-nemenman -
Category
Technology
-
view
3.261 -
download
2
description
Transcript of PostGIS on Rails
![Page 2: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/2.jpg)
About me
Programmer
Love maps
Building map based rental search engine @ Apartment List
2Friday, April 19,
![Page 3: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/3.jpg)
Location Aware Apps
Where am I?
What is around me?
3Friday, April 19,
![Page 4: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/4.jpg)
Where am I?
Latitude and Longitude
HTML5 geolocation or GPS
Address
Geocoding
Reverse geocoding
4Friday, April 19,
![Page 5: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/5.jpg)
Where am I?
What if you need to know ...
Neighborhood
School district
National park
Earthquake safety zone
5Friday, April 19,
![Page 6: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/6.jpg)
What is around me?
Yelp and Google Places API
Restaurants, bars, etc.
Points of interest
6Friday, April 19,
![Page 7: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/7.jpg)
What is around me?
What if you want to know ...
What are three neighborhoods closest to me?
Average rent for 1 bedroom in Lower Pacific Heights
Crime rate on my city block
Who is around me?
7Friday, April 19,
![Page 8: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/8.jpg)
When 3rd party APIs fall short ...
Get your own data set
Build your own solution
8Friday, April 19,
![Page 9: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/9.jpg)
Spatial Systems
MongoDB
Solr
MySQL
Oracle / DB2
PostGIS
9Friday, April 19,
![Page 10: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/10.jpg)
PostGIS
Geospatial extension to Postgres
New datatypes
Functions to work with those datatypes
Spatial indices using GiST
create extension postgis;
10Friday, April 19,
![Page 11: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/11.jpg)
A Simple Example
11Friday, April 19,
![Page 12: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/12.jpg)
A simple example
Yosemite Park Ranger
Tracking bears equipped with GPS transmitters
Want to show all the bears on Google Maps
12Friday, April 19,
![Page 13: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/13.jpg)
Bears (database migration)
create_table :bears do |t| t.column :lat, :float t.column :lon, :floatend
add_index :bears, :latadd_index :bears, :lonadd_index :bears, [:lat, :lon]
13Friday, April 19,
![Page 14: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/14.jpg)
Bears (model)class Bear < ActiveRecord::Base
def self.bbox(sw_lon, sw_lat, ne_lon, ne_lat) self .where( :lon => sw_lon..ne_lon ) .where( :lat => sw_lat..ne_lat )end
end
14Friday, April 19,
![Page 15: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/15.jpg)
A PostGIS example (migration)
create_table :bears do |t| t.column :coordinates, :geometry, :srid => 4326end
add_index :bears, :coordinates, :spatial => true
15Friday, April 19,
![Page 16: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/16.jpg)
A PostGIS example (model)
def self.box(sw_lon, sw_lat, ne_lon, ne_lat)
factory = Rails.application.spatial_factory
sw = factory.point(sw_lon, sw_lat) nw = factory.point(sw_lon, ne_lat) ne = factory.point(ne_lon, ne_lat) se = factory.point(ne_lon, sw_lat)
ring = factory.linear_ring([sw, nw, ne, se]) bbox = factory.polygon(ring)
self .where('ST_Intersects(coordinates, :bbox)', :bbox => bbox)end
16Friday, April 19,
![Page 17: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/17.jpg)
A PostGIS example
1_000_000.times do Bear.create!( ...)
end
17Friday, April 19,
![Page 18: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/18.jpg)
1,000,000 bears
PostGIS is 1.5x to 50x faster
18Friday, April 19,
![Page 19: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/19.jpg)
Active Record PostGIS Adapter
Migration support
Automatic conversion of PostGIS datatypes to Ruby (RGeo) objects and back
gem 'pg'gem 'rgeo'gem 'activerecord-postgis-adapter'
19Friday, April 19,
![Page 20: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/20.jpg)
Rails Migrations
add_column :bears, :coordinates, :geometry, :srid => 4326
add_index :bears, :coordinates, :spatial => true
20Friday, April 19,
![Page 21: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/21.jpg)
Postgres Table
=> \d bears Table "public.bears" Column | Type -------------+----------------------------- id | integer coordinates | geometry(Geometry,4326) Indexes: "pins_pkey" PRIMARY KEY, btree (id) "index_pins_on_coordinates" gist (coordinates)
21Friday, April 19,
![Page 22: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/22.jpg)
PostGIS Data
=> select id, coordinates from bears limit 4; id | coordinates ----+---------------------------------------------------- 1 | 0101000020E61000002A8A632C341F664021805D8DDBEB4BC0 2 | 0101000020E61000004DF900A54A5866C0A2BAB6AC827D50C0 3 | 0101000020E61000002450EA628F5259C01C789C77C2883040 4 | 0101000020E610000038760C7B85443C4013206005DC2C48C0(4 rows)
22Friday, April 19,
![Page 23: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/23.jpg)
RGeo
##> bear=Bear.first => #<Bear id: 1, coordinates: #<RGeo::Geos::CAPIPointImpl:0x3fd52ab501b4 "POINT (176.9751188224921 -55.84263770165877)">>
##> bear.coordinates.x => 176.9751188224921
##> bear.coordinates.y => -55.84263770165877
23Friday, April 19,
![Page 24: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/24.jpg)
More examples# \d parks Column | Type ------------------------+----------------------------- id | integer name | character varying(255) boundary | geometry(Geometry,4326)
Indexes: "parks_pkey" PRIMARY KEY, btree (id) "index_parks_on_name" btree (name) "index_parks_on_boundary" gist (polygon)
# select id, name, boundary from parks limit 2; id | name | boundary --------+-------------+------------------------ 1 | Yosemite |0103000020E6100000010000... 2 | Yellowstone |0103000020E6100000010000...
24Friday, April 19,
![Page 25: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/25.jpg)
How many bears are in Yosemite now?
##> park = Park.find_by_name(‘Yosemite’)
##> bears = Bear.where(‘ST_Intersects(coordinates, :bounds)’, :bounds => park.boundary)
##> bear_count = bears.count
25Friday, April 19,
![Page 26: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/26.jpg)
How Many Bears in Yosemite and Yellowstone
(Ruby)?
##> yosemite = Park.find_by_name(‘Yosemite’)
##> yellowstone = Park.find_by_name(‘Yellowstone’)
##> bounds = yosemite.boundary + yellowstone.boundary
##> bears = Bear.where(‘ST_Intersects(coordinates, :bounds)’, :bounds => bounds)
##> bear_count = bears.count
26Friday, April 19,
![Page 27: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/27.jpg)
How Many Bears in Yosemite and Yellowstone
(SQL)?
select count(*) from bears inner join parks on ST_Intersects(bears.coordinates, parks.boundary) where parks.name in (‘Yosemite’, ‘Yellowstone’);
27Friday, April 19,
![Page 28: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/28.jpg)
Three parks closest to me?
Distance operator (KNN) is a feature of Postgres 9.1 and above
select id, name, boundary <-> ST_Point(37.775, -122.44) as distancefrom parksorder by distancelimit 3;
28Friday, April 19,
![Page 29: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/29.jpg)
What else is possible?
29Friday, April 19,
![Page 30: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/30.jpg)
Geometry Simplification
ST_Simplify
ST_ConvexHull
ST_ConcaveHull
30Friday, April 19,
![Page 31: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/31.jpg)
Spatial Relationships
ST_Centroid
ST_Contained
ST_Area
ST_Perimeter
ST_DWithin
31Friday, April 19,
![Page 32: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/32.jpg)
Format Conversions
ST_AsGeoJSON
ST_AsText
32Friday, April 19,
![Page 33: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/33.jpg)
Do Try It at Home
Heroku Postgres https://devcenter.heroku.com/articles/heroku-postgres-extensions-postgis-full-text-search
Postgres.apphttp://postgresapp.com/
select postgis_full_version();
33Friday, April 19,
![Page 34: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/34.jpg)
Data Sources (free)
US Census Data (Tiger)http://www.census.gov/geo/maps-data/data/tiger.html
Zillow Neighborhoodshttp://www.zillow.com/howto/api/neighborhood-boundaries.htm
34Friday, April 19,
![Page 35: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/35.jpg)
Data Sources (commercial)
Maponics
http://www.maponics.com/
Urban Mapping
http://www.urbanmapping.com/
Onboard Informatics
http://www.onboardinformatics.com/
35Friday, April 19,
![Page 36: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/36.jpg)
LinksPostGIS
http://postgis.net/
Active Record PostGIS Adapter
https://github.com/dazuma/activerecord-postgis-adapter
RGeo
https://github.com/dazuma/rgeo
36Friday, April 19,
![Page 37: PostGIS on Rails](https://reader034.fdocuments.us/reader034/viewer/2022051313/548779a7b4af9f7d0d8b53f6/html5/thumbnails/37.jpg)
Q & A
We are hiring @apartmentlist!37Friday, April 19,