rs_spatial_adapter 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +197 -0
- data/VERSION +1 -0
- data/lib/spatial_adapter.rb +41 -0
- data/lib/spatial_adapter/common/raw_geom_info.rb +23 -0
- data/lib/spatial_adapter/common/schema_definitions.rb +11 -0
- data/lib/spatial_adapter/common/schema_dumper.rb +136 -0
- data/lib/spatial_adapter/common/spatial_column.rb +70 -0
- data/lib/spatial_adapter/common/table_definition.rb +14 -0
- data/lib/spatial_adapter/mysql.rb +98 -0
- data/lib/spatial_adapter/mysql2.rb +97 -0
- data/lib/spatial_adapter/postgresql.rb +388 -0
- data/lib/spatial_adapter/railtie.rb +13 -0
- data/rails/init.rb +11 -0
- data/spec/README.txt +22 -0
- data/spec/db/mysql2_raw.rb +70 -0
- data/spec/db/mysql_raw.rb +70 -0
- data/spec/db/postgis_raw.rb +190 -0
- data/spec/models/common.rb +65 -0
- data/spec/mysql/connection_adapter_spec.rb +106 -0
- data/spec/mysql/migration_spec.rb +64 -0
- data/spec/mysql/models_spec.rb +65 -0
- data/spec/mysql/schema_dumper_spec.rb +56 -0
- data/spec/mysql2/connection_adapter_spec.rb +106 -0
- data/spec/mysql2/migration_spec.rb +64 -0
- data/spec/mysql2/models_spec.rb +65 -0
- data/spec/mysql2/schema_dumper_spec.rb +56 -0
- data/spec/postgresql/connection_adapter_spec.rb +227 -0
- data/spec/postgresql/migration_spec.rb +365 -0
- data/spec/postgresql/models_spec.rb +221 -0
- data/spec/postgresql/schema_dumper_spec.rb +79 -0
- data/spec/shared_examples.rb +43 -0
- data/spec/spec_helper.rb +90 -0
- metadata +131 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006 Guilhem Vellut <guilhem.vellut+georuby@gmail.com>
|
2
|
+
Copyright (c) 2010 Pete Deffendol <pete@fragility.us>
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
12
|
+
copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
= Spatial Adapter for ActiveRecord
|
2
|
+
|
3
|
+
This is the Spatial Adapter for ActiveRecord. It enhances ActiveRecord to
|
4
|
+
handle spatial datatypes in the following databases:
|
5
|
+
|
6
|
+
- PostgreSQL (using PostGIS)
|
7
|
+
- MySQL (using Spatial Extensions)
|
8
|
+
|
9
|
+
== Dependencies
|
10
|
+
|
11
|
+
The following gems are required:
|
12
|
+
|
13
|
+
- GeoRuby
|
14
|
+
- ActiveRecord (version 2.2.2 and up)
|
15
|
+
|
16
|
+
For PostgreSQL:
|
17
|
+
|
18
|
+
- PostGIS version 1.4.0 or higher should be installed in your database
|
19
|
+
|
20
|
+
== Installation
|
21
|
+
|
22
|
+
Choose ONE of the following installation methods. You shouldn't have to do both.
|
23
|
+
|
24
|
+
=== From RubyGems
|
25
|
+
|
26
|
+
This is the preferred method of installation, and will pull in the required
|
27
|
+
dependencies as well.
|
28
|
+
|
29
|
+
gem install spatial_adapter
|
30
|
+
|
31
|
+
In a Rails 2.x app, you can add a gem dependency in environment.rb:
|
32
|
+
|
33
|
+
config.gem 'spatial_adapter'
|
34
|
+
|
35
|
+
In a Rails 3 app, add a gem dependency to Gemfile:
|
36
|
+
|
37
|
+
gem 'spatial_adapter'
|
38
|
+
|
39
|
+
=== As a Rails Plugin
|
40
|
+
|
41
|
+
In your Rails project, run the following:
|
42
|
+
|
43
|
+
script/plugin install git://github.com/fragility/spatial_adapter.git
|
44
|
+
|
45
|
+
You need to have Git installed first.
|
46
|
+
|
47
|
+
== Configuration
|
48
|
+
|
49
|
+
Choose the database type for which you would like to use spatial_adapter, and
|
50
|
+
load each with
|
51
|
+
|
52
|
+
require 'spatial_adapter/[database]'
|
53
|
+
|
54
|
+
where [database] should be replaced with one of the following:
|
55
|
+
|
56
|
+
- postgresql
|
57
|
+
- mysql
|
58
|
+
|
59
|
+
For example to use the PostgreSQL spatial adapter:
|
60
|
+
|
61
|
+
require 'spatial_adapter/postgresql'
|
62
|
+
|
63
|
+
In a Rails app, spatial_adapter will automatically load the adapter for the database
|
64
|
+
specified in your database.yml configuration.
|
65
|
+
|
66
|
+
== Operations
|
67
|
+
|
68
|
+
Geometric columns in your ActiveRecord models now appear just like any other
|
69
|
+
column of other basic data types. They can also be dumped in ruby schema mode
|
70
|
+
and loaded in migrations the same way as columns of basic types.
|
71
|
+
|
72
|
+
=== Migrations
|
73
|
+
|
74
|
+
Here is an example of code for the creation of a table with a geometric column
|
75
|
+
in PostGIS, along with the addition of a spatial index on the column:
|
76
|
+
|
77
|
+
ActiveRecord::Schema.define do
|
78
|
+
create_table :table_points, :force => true do |t|
|
79
|
+
t.string :data
|
80
|
+
t.point :geom, :null => false, :srid => 123, :with_z => true
|
81
|
+
end
|
82
|
+
|
83
|
+
add_index :table_points, :geom, :spatial => true
|
84
|
+
end
|
85
|
+
|
86
|
+
Here is a related statement valid for MySql version <= 5.0.16:
|
87
|
+
|
88
|
+
ActiveRecord::Schema.define do
|
89
|
+
create_table "table_points", ;options=>"ENGINE=MyISAM", :force => true do |t|
|
90
|
+
t.string :data
|
91
|
+
t.point :geom, :null => false
|
92
|
+
end
|
93
|
+
|
94
|
+
add_index :table_points, :geom, :spatial => true
|
95
|
+
end
|
96
|
+
|
97
|
+
=== Differences Between Databases
|
98
|
+
|
99
|
+
- On all versions of MySQL, the :srid, :with_z, and :with_m options are ignored, since
|
100
|
+
they are not supported.
|
101
|
+
|
102
|
+
- On MySQL versions <= 5.0.16, you have to add <tt>:options =>
|
103
|
+
"ENGINE=MyISAM"</tt> to the create_table statement, since only MyISAM tables
|
104
|
+
can have spatial columns. In addition, only MyISAM tables may have spatial
|
105
|
+
indexes.
|
106
|
+
|
107
|
+
=== Models
|
108
|
+
|
109
|
+
Create your ActiveRecord models normally. Spatial Adapter will automatically
|
110
|
+
handle spatial columns, converting them to the appropriate GeoRuby type.
|
111
|
+
|
112
|
+
class TablePoint < ActiveRecord::Base
|
113
|
+
end
|
114
|
+
|
115
|
+
=== Access
|
116
|
+
|
117
|
+
Here is an example of row creation and access, using the model and the table
|
118
|
+
defined above:
|
119
|
+
|
120
|
+
pt = TablePoint.new(
|
121
|
+
:data => "Hello!",
|
122
|
+
:geom => Point.from_x_y_z(-1.6, 2.8, -3.4, 123))
|
123
|
+
pt.save
|
124
|
+
pt = TablePoint.find_first
|
125
|
+
puts pt.geom.x #access the geom column like any other
|
126
|
+
|
127
|
+
=== Fixtures
|
128
|
+
|
129
|
+
If you use fixtures for your unit tests, at some point, you will want to input
|
130
|
+
a geometry. You could transform your geometries to a form suitable for YAML
|
131
|
+
yourself every time but Spatial Adapter provides a method to do it for you:
|
132
|
+
+to_fixture_format+. You would use it like this, if the geometric column is a
|
133
|
+
point:
|
134
|
+
|
135
|
+
fixture:
|
136
|
+
id: 1
|
137
|
+
data: HELLO
|
138
|
+
geom: <%= Point.from_x_y(123.5,321.9).to_fixture_format %>
|
139
|
+
|
140
|
+
=== Finder Enhancements
|
141
|
+
|
142
|
+
Enhancements to find_by_* and friends has been removed from this version of
|
143
|
+
Spatial Adapter until a cleaner implementation can be made. (The previous
|
144
|
+
implementation made adapter-specific modifications to ActiveRecord::Base,
|
145
|
+
which prevented multiple adapters from being loaded at once.)
|
146
|
+
|
147
|
+
=== Geometric data types
|
148
|
+
|
149
|
+
Ruby geometric datatypes are currently made available only through the GeoRuby
|
150
|
+
library (http://georuby.rubyforge.org/): This is where the
|
151
|
+
<tt>Point.from_x_y</tt> in the example above comes from.
|
152
|
+
|
153
|
+
== Warning
|
154
|
+
|
155
|
+
- Since ActiveRecord seems to keep only the string values directly returned
|
156
|
+
from the database, it translates from these to the correct types everytime
|
157
|
+
an attribute is read, which is probably ok for simple types, but might be
|
158
|
+
less than efficient for geometries, since the EWKB string has to be parsed
|
159
|
+
everytime. Also it means you cannot modify the geometry object returned from
|
160
|
+
an attribute directly:
|
161
|
+
|
162
|
+
place = Place.find_first
|
163
|
+
place.the_geom.y=123456.7 # this doesn't work
|
164
|
+
|
165
|
+
Since the translation to a geometry is performed every time the_geom is read,
|
166
|
+
the change to y will not be saved! You would have to do something like this:
|
167
|
+
|
168
|
+
place = Place.find_first
|
169
|
+
the_geom = place.the_geom
|
170
|
+
the_geom.y=123456.7
|
171
|
+
place.the_geom = the_geom
|
172
|
+
|
173
|
+
== License
|
174
|
+
|
175
|
+
The Spatial Adapter for ActiveRecord is released under the MIT license.
|
176
|
+
|
177
|
+
== Latest Changes
|
178
|
+
|
179
|
+
Spatial Adapter has been refactored and is now available as a Ruby gem. The
|
180
|
+
dependency on Rails has been removed. Unfortunately, the current version is
|
181
|
+
without some of the previous functionality, until a cleaner implementation is
|
182
|
+
made.
|
183
|
+
|
184
|
+
The previous release is available on the "legacy" branch.
|
185
|
+
|
186
|
+
=== Removed Features in 0.2.0
|
187
|
+
|
188
|
+
- Compatibility with ActiveRecord/Rails older than version 2.2.2
|
189
|
+
- enhancements to find_by_* for spatial columns
|
190
|
+
- to_fixture_format extension to the GeoRuby types
|
191
|
+
|
192
|
+
These will hopefully be added back in the near future.
|
193
|
+
|
194
|
+
== Support
|
195
|
+
|
196
|
+
Any questions, enhancement proposals, bug notifications or corrections can be
|
197
|
+
made via the project page at http://github.com/fragility/spatial_adapter
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.2.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# This file should typically not be directly require'd into your project. You
|
2
|
+
# should require the database-specific adapter you desire, e.g.
|
3
|
+
#
|
4
|
+
# require 'spatial_adapter/postgresql'
|
5
|
+
#
|
6
|
+
# Why is this file here?
|
7
|
+
#
|
8
|
+
# Mostly to keep Rails happy when using config.gem to specify dependencies.
|
9
|
+
# The Rails init code (rails/init.rb) will then load the adapter that matches
|
10
|
+
# your database.yml configuration.
|
11
|
+
|
12
|
+
require 'geo_ruby'
|
13
|
+
require 'active_record'
|
14
|
+
|
15
|
+
include GeoRuby::SimpleFeatures
|
16
|
+
|
17
|
+
module SpatialAdapter
|
18
|
+
# Translation of geometric data types
|
19
|
+
def geometry_data_types
|
20
|
+
{
|
21
|
+
:point => { :name => "POINT" },
|
22
|
+
:line_string => { :name => "LINESTRING" },
|
23
|
+
:polygon => { :name => "POLYGON" },
|
24
|
+
:geometry_collection => { :name => "GEOMETRYCOLLECTION" },
|
25
|
+
:multi_point => { :name => "MULTIPOINT" },
|
26
|
+
:multi_line_string => { :name => "MULTILINESTRING" },
|
27
|
+
:multi_polygon => { :name => "MULTIPOLYGON" },
|
28
|
+
:geometry => { :name => "GEOMETRY"}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
class NotCompatibleError < ::StandardError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'spatial_adapter/common/raw_geom_info'
|
37
|
+
require 'spatial_adapter/common/spatial_column'
|
38
|
+
require 'spatial_adapter/common/schema_definitions'
|
39
|
+
require 'spatial_adapter/common/schema_dumper'
|
40
|
+
require 'spatial_adapter/common/table_definition'
|
41
|
+
require 'spatial_adapter/railtie' if defined?(Rails::Railtie)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpatialAdapter
|
2
|
+
class RawGeomInfo < Struct.new(:type,:srid,:dimension,:with_z,:with_m) #:nodoc:
|
3
|
+
def convert!
|
4
|
+
self.type = "geometry" if self.type.nil? #if geometry the geometrytype constraint is not present : need to set the type here then
|
5
|
+
|
6
|
+
if dimension == 4
|
7
|
+
self.with_m = true
|
8
|
+
self.with_z = true
|
9
|
+
elsif dimension == 3
|
10
|
+
if with_m
|
11
|
+
self.with_z = false
|
12
|
+
self.with_m = true
|
13
|
+
else
|
14
|
+
self.with_z = true
|
15
|
+
self.with_m = false
|
16
|
+
end
|
17
|
+
else
|
18
|
+
self.with_z = false
|
19
|
+
self.with_m = false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
2
|
+
|
3
|
+
ActiveRecord::ConnectionAdapters::IndexDefinition.class_eval do
|
4
|
+
attr_accessor :spatial
|
5
|
+
|
6
|
+
alias_method :initialize_without_spatial, :initialize
|
7
|
+
def initialize(table, name, unique, columns, spatial = false)
|
8
|
+
initialize_without_spatial(table, name, unique, columns)
|
9
|
+
@spatial = spatial
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
ActiveRecord::SchemaDumper.ignore_tables << "spatial_ref_sys" << "geometry_columns"
|
2
|
+
|
3
|
+
ActiveRecord::SchemaDumper.class_eval do
|
4
|
+
# These are the valid options for a column specification (spatial options added)
|
5
|
+
VALID_COLUMN_SPEC_KEYS = [:name, :limit, :precision, :scale, :default, :null, :srid, :with_z, :with_m, :geographic]
|
6
|
+
|
7
|
+
def table(table, stream)
|
8
|
+
columns = @connection.columns(table)
|
9
|
+
begin
|
10
|
+
tbl = StringIO.new
|
11
|
+
|
12
|
+
# first dump primary key column
|
13
|
+
if @connection.respond_to?(:pk_and_sequence_for)
|
14
|
+
pk, pk_seq = @connection.pk_and_sequence_for(table)
|
15
|
+
elsif @connection.respond_to?(:primary_key)
|
16
|
+
pk = @connection.primary_key(table)
|
17
|
+
end
|
18
|
+
|
19
|
+
tbl.print " create_table #{table.inspect}"
|
20
|
+
if columns.detect { |c| c.name == pk }
|
21
|
+
if pk != 'id'
|
22
|
+
tbl.print %Q(, :primary_key => "#{pk}")
|
23
|
+
end
|
24
|
+
else
|
25
|
+
tbl.print ", :id => false"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Added by Spatial Adapter to ensure correct MySQL table engine
|
29
|
+
if @connection.respond_to?(:options_for)
|
30
|
+
res = @connection.options_for(table)
|
31
|
+
tbl.print ", :options=>'#{res}'" if res
|
32
|
+
end
|
33
|
+
|
34
|
+
tbl.print ", :force => true"
|
35
|
+
tbl.puts " do |t|"
|
36
|
+
|
37
|
+
# then dump all non-primary key columns
|
38
|
+
column_specs = columns.map do |column|
|
39
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
|
40
|
+
next if column.name == pk
|
41
|
+
spec = column_spec(column)
|
42
|
+
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
|
43
|
+
spec
|
44
|
+
end.compact
|
45
|
+
|
46
|
+
# find all migration keys used in this table
|
47
|
+
keys = VALID_COLUMN_SPEC_KEYS & column_specs.map(&:keys).flatten
|
48
|
+
|
49
|
+
# figure out the lengths for each column based on above keys
|
50
|
+
lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
|
51
|
+
|
52
|
+
# the string we're going to sprintf our values against, with standardized column widths
|
53
|
+
format_string = lengths.map{ |len| "%-#{len}s" }
|
54
|
+
|
55
|
+
# find the max length for the 'type' column, which is special
|
56
|
+
type_length = column_specs.map{ |column| column[:type].length }.max
|
57
|
+
|
58
|
+
# add column type definition to our format string
|
59
|
+
format_string.unshift " t.%-#{type_length}s "
|
60
|
+
|
61
|
+
format_string *= ''
|
62
|
+
|
63
|
+
column_specs.each do |colspec|
|
64
|
+
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
65
|
+
values.unshift colspec[:type]
|
66
|
+
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
67
|
+
tbl.puts
|
68
|
+
end
|
69
|
+
|
70
|
+
tbl.puts " end"
|
71
|
+
tbl.puts
|
72
|
+
|
73
|
+
indexes(table, tbl)
|
74
|
+
|
75
|
+
tbl.rewind
|
76
|
+
stream.print tbl.read
|
77
|
+
rescue => e
|
78
|
+
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
79
|
+
stream.puts "# #{e.message}"
|
80
|
+
stream.puts
|
81
|
+
end
|
82
|
+
|
83
|
+
stream
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def indexes(table, stream)
|
88
|
+
if (indexes = @connection.indexes(table)).any?
|
89
|
+
add_index_statements = indexes.map do |index|
|
90
|
+
statment_parts = [ ('add_index ' + index.table.inspect) ]
|
91
|
+
statment_parts << index.columns.inspect
|
92
|
+
statment_parts << (':name => ' + index.name.inspect)
|
93
|
+
statment_parts << ':unique => true' if index.unique
|
94
|
+
# Add spatial option (this is the only change from the original method)
|
95
|
+
statment_parts << ':spatial => true' if index.spatial
|
96
|
+
|
97
|
+
' ' + statment_parts.join(', ')
|
98
|
+
end
|
99
|
+
|
100
|
+
stream.puts add_index_statements.sort.join("\n")
|
101
|
+
stream.puts
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# Build specification for a table column
|
108
|
+
def column_spec(column)
|
109
|
+
spec = {}
|
110
|
+
spec[:name] = column.name.inspect
|
111
|
+
|
112
|
+
# AR has an optimisation which handles zero-scale decimals as integers. This
|
113
|
+
# code ensures that the dumper still dumps the column as a decimal.
|
114
|
+
spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
|
115
|
+
'decimal'
|
116
|
+
else
|
117
|
+
column.type.to_s
|
118
|
+
end
|
119
|
+
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal'
|
120
|
+
spec[:precision] = column.precision.inspect if !column.precision.nil?
|
121
|
+
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
122
|
+
spec[:null] = 'false' if !column.null
|
123
|
+
spec[:default] = default_string(column.default) if column.has_default?
|
124
|
+
|
125
|
+
# Additions for spatial columns
|
126
|
+
if column.is_a?(SpatialColumn)
|
127
|
+
# Override with specific geometry type
|
128
|
+
spec[:type] = column.geometry_type.to_s
|
129
|
+
spec[:srid] = column.srid.inspect if column.srid != -1
|
130
|
+
spec[:with_z] = 'true' if column.with_z
|
131
|
+
spec[:with_m] = 'true' if column.with_m
|
132
|
+
spec[:geographic] = 'true' if column.geographic?
|
133
|
+
end
|
134
|
+
spec
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module SpatialAdapter
|
2
|
+
module SpatialColumn
|
3
|
+
attr_reader :geometry_type, :srid, :with_z, :with_m
|
4
|
+
|
5
|
+
def initialize(name, default, sql_type = nil, null = true, srid=-1, with_z=false, with_m=false)
|
6
|
+
super(name, default, sql_type, null)
|
7
|
+
@geometry_type = geometry_simplified_type(@sql_type)
|
8
|
+
@srid = srid
|
9
|
+
@with_z = with_z
|
10
|
+
@with_m = with_m
|
11
|
+
end
|
12
|
+
|
13
|
+
def spatial?
|
14
|
+
!@geometry_type.nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
def geographic?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Redefines type_cast to add support for geometries
|
22
|
+
# alias_method :type_cast_without_spatial, :type_cast
|
23
|
+
def type_cast(value)
|
24
|
+
return nil if value.nil?
|
25
|
+
spatial? ? self.class.string_to_geometry(value) : super
|
26
|
+
end
|
27
|
+
|
28
|
+
#Redefines type_cast_code to add support for geometries.
|
29
|
+
#
|
30
|
+
#WARNING : Since ActiveRecord keeps only the string values directly returned from the database, it translates from these to the correct types everytime an attribute is read (using the code returned by this method), which is probably ok for simple types, but might be less than efficient for geometries. Also you cannot modify the geometry object returned directly or your change will not be saved.
|
31
|
+
# alias_method :type_cast_code_without_spatial, :type_cast_code
|
32
|
+
def type_cast_code(var_name)
|
33
|
+
spatial? ? "#{self.class.name}.string_to_geometry(#{var_name})" : super
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
#Redefines klass to add support for geometries
|
38
|
+
# alias_method :klass_without_spatial, :klass
|
39
|
+
def klass
|
40
|
+
spatial? ? GeoRuby::SimpleFeatures::Geometry : super
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Maps additional data types to base Rails/Arel types
|
46
|
+
#
|
47
|
+
# For Rails 3, only the types defined by Arel can be used. We'll
|
48
|
+
# use :string since the database returns the columns as hex strings.
|
49
|
+
def simplified_type(field_type)
|
50
|
+
case field_type
|
51
|
+
when /geography|geometry|point|linestring|polygon|multipoint|multilinestring|multipolygon|geometrycollection/i then :string
|
52
|
+
else super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# less simlpified geometric type to be use in migrations
|
57
|
+
def geometry_simplified_type(sql_type)
|
58
|
+
case sql_type
|
59
|
+
when /^point$/i then :point
|
60
|
+
when /^linestring$/i then :line_string
|
61
|
+
when /^polygon$/i then :polygon
|
62
|
+
when /^geometry$/i then :geometry
|
63
|
+
when /multipoint/i then :multi_point
|
64
|
+
when /multilinestring/i then :multi_line_string
|
65
|
+
when /multipolygon/i then :multi_polygon
|
66
|
+
when /geometrycollection/i then :geometry_collection
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|