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
79
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
650
Authentication Security – RUBYSPB
lest
2
160
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
650
Ruby Stdlib – Minsk.rb October 2012
lest
10
350
Background jobs with realtime results – RailsClub'Moscow 2012
lest
5
210
Other Decks in Programming
See All in Programming
DevTalks 25 - Create your own AI-infused Java apps with ease
kdubois
2
120
コードに語らせよう――自己ドキュメント化が内包する楽しさについて / Let the Code Speak
nrslib
5
1k
UPDATEがシステムを複雑にする? イミュータブルデータモデルのすすめ
shimomura
0
180
TSConfig Solution Style & subpath imports to switch types on a per-file basis
maminami373
1
180
TypeScript を活かしてデザインシステム MCP を作る / #tskaigi_after_night
izumin5210
4
470
Design Pressure
hynek
0
1.4k
❄️ tmux-nixの実装を通して学ぶNixOSモジュール
momeemt
1
120
コンポーネントライブラリで実現する、アクセシビリティの正しい実装パターン
schktjm
1
660
バランスを見極めよう!実装の意味を明示するための型定義 TSKaigi 2025 Day2 (5/24)
whatasoda
2
770
tsconfigのオプションで変わる型世界
keisukeikeda
1
130
Spring gRPC で始める gRPC 入門 / Introduction to gRPC with Spring gRPC
mackey0225
0
110
Perlで痩せる
yuukis
1
660
Featured
See All Featured
Facilitating Awesome Meetings
lara
54
6.4k
Done Done
chrislema
184
16k
Rebuilding a faster, lazier Slack
samanthasiow
81
9k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
Build The Right Thing And Hit Your Dates
maggiecrowley
35
2.7k
Git: the NoSQL Database
bkeepers
PRO
430
65k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
The Power of CSS Pseudo Elements
geoffreycrofte
76
5.8k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
Adopting Sorbet at Scale
ufuk
76
9.4k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
6
660
Bash Introduction
62gerente
614
210k
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