public
Fork of fragility/spatial_adapter
Description: Miscellaneous PostgreSQL-related changes to Spatial Adapter
Homepage: http://georuby.rubyforge.org/
Clone URL: git://github.com/melriffe/spatial_adapter.git
Mel Riffe (author)
Mon Aug 04 10:56:45 -0700 2008
commit  9b559a1fba884b9536c3f60c197164eda79f7309
tree    6a69604443a66f250b63042f8287834304800275
parent  816b2637518191375b7dfbbc09506db68b7e5797
spatial_adapter / README
100644 124 lines (92 sloc) 7.959 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
=Spatial Adapter for Rails
This is the Spatial Adapter for Rails 0.1.1. It is a plugin for Rails which manages the MySql Spatial and PostGIS geometric columns in a transparent way (that is like the other base data type columns). It also provides a way to manage these columns in migrations. It replaces both the "PostGIS Adapter for Rails" and "MySql Spatial Adapter for Rails" plugins.
 
===Dependencies
You need to install a version >= 0.1.1 of the GeoRuby gem (http://rubyforge.org/projects/georuby/) :
gem install georuby
 
 
===Installation
At the root of your Rails project, type :
       script\plugin install svn://rubyforge.org/var/svn/georuby/SpatialAdapter/trunk/spatial_adapter
You need to have SVN installed.
 
====== PostGIS SQL Scripts
This is only for PostgreSQL databases:
 
Place the following scripts in a folder named 'spatial' under the 'db' folder; For example:
  RAILS_ROOT/db/spatial/lwpostgis.sql
  RAILS_ROOT/db/spatial/spatial_ref_sys
  
These will be used when creating the Test database when running the Rake Test tasks. These scripts should have been installed when the PostGIS libraries were installed. Online reference: http://postgis.refractions.net/
 
===Operations
Geometric columns in your ActiveRecord models now appear just like any other column of other basic data types. They can also be dumped in ruby schema mode and loaded in migrations the same way as columns of basic types.
 
==== Migrations
 
Here is an example of code for the creation of a table with a geometric column in PostGIS, along with the addition of a spatial index on the column :
ActiveRecord::Schema.define do
create_table "table_points", :force => true do |t|
     t.column "data", :string
     t.column "geom", :point, :null=>false, :srid => 123, :with_z => true
   end
 
add_index "table_points", "geom", :spatial=>true
     end
 
Here is a related statement valid for MySql version <= 5.0.16 :
ActiveRecord::Schema.define do
create_table "table_points", ;options=>"ENGINE=MyISAM", :force => true do |t|
     t.column "data", :string
     t.column "geom", :point, :null=>false
   end
 
add_index "table_points", "geom", :spatial=>true
     end
The differences with the PostGIS version are because of the following reasons :
- On all version of MySql, the :srid and :with_z would be ignored, since they are not supported.
- On MySql versions <= 5.0.16, you have to add <tt>:options => "ENGINE=MyISAM"</tt> to the create_table statetement, since only MyISAM tables can have geometric columns.
 
==== Model
 
Here is the model you would use, in both MySql and PostGIS:
class TablePoint < ActiveRecord::Base
end
That was easy! As you see, there is no need to declare a column as geometric. The plugin will get this information by itself.
 
==== Access
 
Here is an example of PostGIS row creation and access, using the model and the table defined above :
pt = TablePoint.new(:data => "Hello!",:geom => Point.from_x_y_z(-1.6,2.8,-3.4,123))
pt.save
pt = TablePoint.find_first
puts pt.geom.x #access the geom column like any other
 
For MySQL, it is slightly different since it does not support Z dimension or SRID :
pt = TablePoint.new(:data => "Hello!",:geom => Point.from_x_y(-1.6,2.8))
pt.save
pt = TablePoint.find_first
puts pt.geom.x #access the geom column like any other
 
==== Fixtures
 
If you use fixtures for your unit tests, at some point, you will want to input a geometry. You could transform your geometries to a form suitable for YAML yourself everytime but the spatial adapter provides a method to do it for you: +to_yaml+. It works for both MySQL and PostGIS (although the string returned is different for each database). You would use it like this, if the geometric column is a point:
fixture:
id: 1
data: HELLO
geom: <%= Point.from_x_y(123.5,321.9).to_yaml %>
 
==== Find_by
 
find_by_[column] has been redefined when column is of a geometric type. Instead of using the Rails default '=' operator, for which I can't see a definition for MySql spatial datatypes and which performs a bounding box equality test in PostGIS, it uses a bounding box intersection: && in PostGIS and MBRIntersects in MySQL, which can both make use of a spatial index if one is present to speed up the queries. You could use this query, for example, if you need to display data from the database: You would want only the geometries which are in the screen rectangle and you could use a bounding box query for that. Since this is a common case, it is the default. You have 2 ways to use the find_by_[geom_column]: Either by passing a geometric object directly, or passing an array with the 2 opposite corners of a bounding box (with 2 or 3 coordinates depending of the dimension of the data).
Park.find_by_geom(LineString.from_coordinates([[1.4,5.6],[2.7,8.9],[1.6,5.6]]))
or
Park.find_by_geom([[3,5.6],[19.98,5.9]])
In PostGIS, since you can only use operations with geometries with the same SRID, you can add a third element representing the SRID of the bounding box to the array. It is by default set to -1:
Park.find_by_geom([[3,5.6],[19.98,5.9],123])
 
==== Geometric data types
 
Ruby geometric datatypes are currently made available only through the GeoRuby library (http://thepochisuperstarmegashow.com/ProjectsDoc/georuby-doc/index.html): This is where the <tt>Point.from_x_y</tt> in the example above comes from. It is a goal of a future release of the Spatial Adapter to support additional geometric datatype libraries, such as Ruby/GEOS, as long as they can support reading and writing of EWKB.
 
 
===Warning
- If you use a version of MySQL before 5.0.16, only tables using the MyISAM engine can support geometric columns. After MySQL 5.0.16, any engine (incuding INNODB) is supported.
 
- Since ActiveRecord seems to keep only the string values directly returned from the database, it translates from these to the correct types everytime an attribute is read, which is probably ok for simple types, but might be less than efficient for geometries, since the EWKB string has to be parsed everytime. Also it means you cannot modify the geometry object returned from an attribute directly :
       place = Place.find_first
       place.the_geom.y=123456.7
 
- Since the translation to a geometry is performed everytime the_geom is read, the change to y will not be saved! You would have to do something like this :
       place = Place.find_first
       the_geom = place.the_geom
       the_geom.y=123456.7
       place.the_geom = the_geom
 
 
===Changes since last version
- The PostGIS adapter and the MySql Spatial adapter have been merged into one plugin. The correct files to load is determined using the type of connection defined in the environment.
- Geometric columns can now be dumped just like other base data types. This means you can use the ruby schema mode, even if you use the plugin.
- Support of M dimensions in migrations. The <tt>:dimension</tt> key in the column definition has disappeared and has been replaced by <tt>:with_z</tt> and <tt>:with_m</tt>.
- Addition of unit tests. At the plugin root, Run <tt>rake test:mysql</tt> to run the mysql tests and <tt>rake test:postgis</tt> for the postgis ones. You will need to configure your connection in <tt>test/db/database_mysql.yml</tt> and <tt>test/db/database_postgis.yml</tt>. If you get errors on your platform, please report to mailto:guilhem.vellut+georuby@gmail.com.
- Addition of a find_by methods with a special behaviour for geometries
- Addition of a to_yaml method to use inside a YAML fixture
 
===TODO
- Support of other geometric datatype libraries in addition to GeoRuby
- Tutorials
 
===License
The Spatial Adapter for Rails is released under the MIT license.
 
===Support
Any questions, enhancement proposals, bug notifications or corrections can be sent to mailto:guilhem.vellut+georuby@gmail.com.