Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Geospatial applications on Rails
Search
Sergey Nartimov
June 01, 2013
Programming
8
400
Geospatial applications on Rails
Sergey Nartimov
June 01, 2013
Tweet
Share
More Decks by Sergey Nartimov
See All by Sergey Nartimov
PubSub at Rails
lest
0
120
Rails in production - RubyConfBY 22 Mar 2015
lest
1
140
Sequel - BRUG 21 Feb 2015
lest
0
77
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
650
Authentication Security – RUBYSPB
lest
2
150
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
640
Ruby Stdlib – Minsk.rb October 2012
lest
10
340
Background jobs with realtime results – RailsClub'Moscow 2012
lest
5
210
Other Decks in Programming
See All in Programming
AWSマネコンに複数のアカウントで入れるようになりました
yuhta28
2
160
CI改善もDatadogとともに
taumu
0
110
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
150
Grafana Loki によるサーバログのコスト削減
mot_techtalk
1
110
WebDriver BiDiとは何なのか
yotahada3
1
140
AWS Lambda functions with C# 用の Dev Container Template を作ってみた件
mappie_kochi
0
240
Compose でデザインと実装の差異を減らすための取り組み
oidy
1
300
Spring gRPC について / About Spring gRPC
mackey0225
0
220
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
200
Open source software: how to live long and go far
gaelvaroquaux
0
620
ARA Ansible for the teams
kksat
0
150
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
7
2.5k
Featured
See All Featured
Visualization
eitanlees
146
15k
Automating Front-end Workflow
addyosmani
1367
200k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
The Cult of Friendly URLs
andyhume
78
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
Building Applications with DynamoDB
mza
93
6.2k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Raft: Consensus for Rubyists
vanstee
137
6.8k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
540
Transcript
Geospatial applications on Rails Sergey Nartimov Brainspec https://github.com/lest twitter: @just_lest
About • Rails, Rubinius, Elixir contributor • Software engineer at
Brainspec Sergey Nartimov Brainspec https://github.com/lest twitter: @just_lest
Geospatial data
Geospatial data types • Point • Linestring • Polygon •
Multi... • Geometry collection
Geospatial analysis • Coverage • Intersection • Distance • etc.
Geographic coordinate system
Geographic distance
Map projection
Mercator projection
None
Mercator projection
Mercator projection
Geospatial support
Geospatial support • MySQL • http://dev.mysql.com/doc/refman/5.5/en/ spatial-extensions.html
Geospatial support • MongoDB • http://www.mongodb.org/display/DOCS/ Geospatial+Indexing
Geospatial support • SpatiaLite • http://www.gaia-gis.it/gaia-sins/splite- doxy-4.0.0/index.html
Geospatial support • PostGIS • http://postgis.org/docs/
Rails & PostGIS
• https://github.com/dazuma/activerecord- postgis-adapter • https://github.com/dazuma/rgeo
# config/database.yml adapter: postgis # When postgresql >= 9.1 and
postgis >= 2.0 postgis_extension: true # When postgresql < 9.1 or postgis < 2.0 # e.g. for postgresql 9.1 and postgis 1.5 on ubuntu script_dir: "/usr/share/postgresql/9.1/contrib/postgis-1.5" schema_search_path: public,postgis
create_table :locations do |t| t.point :coords, geographic: true end create_table
:locations do |t| t.string :text t.point :coords, srid: 3785 end add_index :locations, :coords, spatial: true
class Location < ActiveRecord::Base GEOFACTORY = RGeo::Geographic.spherical_factory(srid: 4326) set_rgeo_factory_for_column :coords,
GEOFACTORY end
Points in radius
point = Location::GEOFACTORY.point(27, 53) radius = 50_000 # 50 km
Location.where('st_dwithin(coords, ?, ?)', point, radius) .order('st_distance(coords, ?)', point)
Squeel • https://github.com/ernie/squeel
point = Location::GEOFACTORY.point(27, 53) radius = 50_000 # 50 km
Location.where { st_dwithin(coords, point, radius) } .order { st_distance(coords, point) }
class Location < ActiveRecord::Base GEOFACTORY = RGeo::Geographic.simple_mercator_factory set_rgeo_factory_for_column :coords, GEOFACTORY.projection_factory
end point = Location::GEOFACTORY.point(27, 53) radius = 50_000 / Math.cos(lat * Math::PI / 180.0) Location.where { st_dwithin(coords, point, radius) } .order { st_distance(coords, point) }
Points in bounding box
None
None
sw = Location::GEOFACTORY.point(48.389537, 54.306922) ne = Location::GEOFACTORY.point(48.399643, 54.311216) bbox =
RGeo::Cartesian::BoundingBox.create_from_points(sw, ne) Location.where('coords && ?', bbox)
Clustering • http://pgxn.org/dist/kmeans/ • http://postgis.refractions.net/docs/ ST_SnapToGrid.html
None
Time zones example
• http://efele.net/maps/tz/world/
None
• https://github.com/dazuma/rgeo-shapefile
class CreateTimeZonePolygons < ActiveRecord::Migration def change create_table :time_zone_polygons do |t|
t.string :tzid t.geometry :geometry, geographic: true t.timestamps end add_index :time_zone_polygons, :geometry, spatial: true end end
class TimeZonePolygon < ActiveRecord::Base set_rgeo_factory_for_column :geometry, RGeo::Geographic.spherical_factory(srid: 4326) end
RGeo::Shapefile::Reader.open('tz_world.shp') do |file| file.each do |record| polygon = TimeZonePolygon.new polygon.tzid
= record.attributes['TZID'] polygon.geometry = record.geometry polygon.save! end end
point = TimeZonePolygon::GEOFACTORY.point(27, 53) time_zone = TimeZonePolygon .where { st_covers(geometry,
point) }.first time_zone.tzid # => "Europe/Minsk"
• Further improvements
Thanks <3 Sergey Nartimov Brainspec https://github.com/lest twitter: @just_lest