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
410
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
150
Sequel - BRUG 21 Feb 2015
lest
0
82
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
660
Authentication Security – RUBYSPB
lest
2
170
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
650
Ruby Stdlib – Minsk.rb October 2012
lest
10
360
Background jobs with realtime results – RailsClub'Moscow 2012
lest
5
210
Other Decks in Programming
See All in Programming
ECS初心者の仲間 – TUIツール「e1s」の紹介
keidarcy
0
150
コンテキストエンジニアリング Cursor編
kinopeee
1
740
AI時代のドメイン駆動設計-DDD実践におけるAI活用のあり方 / ddd-in-ai-era
minodriven
25
9.7k
AI時代のUIはどこへ行く?
yusukebe
11
5.7k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
300
開発チーム・開発組織の設計改善スキルの向上
masuda220
PRO
18
9.6k
Ruby Parser progress report 2025
yui_knk
1
260
ソフトウェアテスト徹底指南書の紹介
goyoki
1
130
Kiroの仕様駆動開発から見えてきたAIコーディングとの正しい付き合い方
clshinji
1
190
KessokuでDIでもgoroutineを活用する / Go Connect #6
mazrean
0
140
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
120
Claude Codeで挑むOSSコントリビュート
eycjur
0
190
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Java REST API Framework Comparison - PWX 2021
mraible
33
8.8k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Rails Girls Zürich Keynote
gr2m
95
14k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Faster Mobile Websites
deanohume
309
31k
Making the Leap to Tech Lead
cromwellryan
134
9.5k
Six Lessons from altMBA
skipperchong
28
4k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.5k
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