activerecord-postgis-adapter 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84cec176fe58c09c168a2e70ded5aa3c6cd340bc
4
- data.tar.gz: feb4f2299f2031b0f8f3f5750225600b4f1f8f29
3
+ metadata.gz: 9072742044be5bdca4d15241b2e55fd59753f07f
4
+ data.tar.gz: f2f0227789eb674f799d1dee7f85555e1040d4e9
5
5
  SHA512:
6
- metadata.gz: fd646dad76070fb45abc821d56d5945cf28d76e967f9a479d11bc81d1fe2a4e1cc33c98d7e346eec3a7546f2207d09b3f427f0f3a87a529a12f294cc21701d6b
7
- data.tar.gz: 1b916339a0926ced1441a14aecc8f68e21f5bffbf196c64f677f975121622b554bfe178d3819e0eeb2bd78d8d8c878011b819ab97694d74e298d7f3262872748
6
+ metadata.gz: fde41e0dcd38d4a6d2a7a53f739e50610c998682bb0f5303383e580269ce486ec15fa45aaa698fa5d71e7d943ff404785cb5bf96d785d329877f54d08a0f8732
7
+ data.tar.gz: f8fe668e18334aefef68f4762e5da778d3b3d4929cab9c1d065a17e55ea392f51954406f643cf47b7021c1372ef3dc42bba397f9d2cc4742bd7718561fb5bc1f
@@ -16,15 +16,16 @@ require 'active_record'
16
16
  require 'active_record/connection_adapters/postgresql_adapter'
17
17
  require 'rgeo/active_record'
18
18
 
19
- require 'active_record/connection_adapters/postgis_adapter/version.rb'
20
- require 'active_record/connection_adapters/postgis_adapter/common_adapter_methods.rb'
21
- require 'active_record/connection_adapters/postgis_adapter/main_adapter.rb'
22
- require 'active_record/connection_adapters/postgis_adapter/spatial_table_definition.rb'
23
- require 'active_record/connection_adapters/postgis_adapter/spatial_column.rb'
24
- require 'active_record/connection_adapters/postgis_adapter/arel_tosql.rb'
25
- require 'active_record/connection_adapters/postgis_adapter/setup.rb'
19
+ require 'active_record/connection_adapters/postgis_adapter/version'
20
+ require 'active_record/connection_adapters/postgis_adapter/common_adapter_methods'
21
+ require 'active_record/connection_adapters/postgis_adapter/main_adapter'
22
+ require 'active_record/connection_adapters/postgis_adapter/spatial_column_info'
23
+ require 'active_record/connection_adapters/postgis_adapter/spatial_table_definition'
24
+ require 'active_record/connection_adapters/postgis_adapter/spatial_column'
25
+ require 'active_record/connection_adapters/postgis_adapter/arel_tosql'
26
+ require 'active_record/connection_adapters/postgis_adapter/setup'
26
27
  require 'active_record/connection_adapters/postgis_adapter/create_connection'
27
- require 'active_record/connection_adapters/postgis_adapter/postgis_database_tasks.rb'
28
+ require 'active_record/connection_adapters/postgis_adapter/postgis_database_tasks'
28
29
 
29
30
  ::ActiveRecord::ConnectionAdapters::PostGISAdapter.initial_setup
30
31
 
@@ -2,7 +2,7 @@ module ActiveRecord # :nodoc:
2
2
  module ConnectionAdapters # :nodoc:
3
3
  module PostGISAdapter # :nodoc:
4
4
  SPATIAL_COLUMN_CONSTRUCTORS = ::RGeo::ActiveRecord::DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS.merge(
5
- :geography => {:type => 'geometry', :geographic => true}
5
+ geography: { type: 'geometry', geographic: true }
6
6
  )
7
7
 
8
8
  # http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
@@ -31,16 +31,16 @@ module ActiveRecord # :nodoc:
31
31
 
32
32
  def srs_database_columns
33
33
  {
34
- :auth_name_column => 'auth_name',
35
- :auth_srid_column => 'auth_srid',
36
- :proj4text_column => 'proj4text',
37
- :srtext_column => 'srtext',
34
+ auth_name_column: 'auth_name',
35
+ auth_srid_column: 'auth_srid',
36
+ proj4text_column: 'proj4text',
37
+ srtext_column: 'srtext',
38
38
  }
39
39
  end
40
40
 
41
41
  def quote(value, column=nil)
42
42
  if ::RGeo::Feature::Geometry.check_type(value)
43
- "'#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value)}'"
43
+ "'#{::RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true).generate(value)}'"
44
44
  elsif value.is_a?(::RGeo::Cartesian::BoundingBox)
45
45
  "'#{value.min_x},#{value.min_y},#{value.max_x},#{value.max_y}'::box"
46
46
  else
@@ -15,13 +15,14 @@ module ActiveRecord # :nodoc:
15
15
  def native_database_types
16
16
  # Overridden to add the :spatial type
17
17
  @@native_database_types ||= super.merge(
18
- :spatial => {:name => 'geometry'},
19
- :geography => {:name => 'geography'})
18
+ geography: { name: 'geography' },
19
+ spatial: { name: 'geometry' },
20
+ )
20
21
  end
21
22
 
22
23
  def type_cast(value, column, array_member = false)
23
24
  if ::RGeo::Feature::Geometry.check_type(value)
24
- ::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value)
25
+ ::RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true).generate(value)
25
26
  else
26
27
  super
27
28
  end
@@ -30,8 +31,8 @@ module ActiveRecord # :nodoc:
30
31
  # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS
31
32
  # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
32
33
  def columns(table_name, name = nil)
34
+ column_info = SpatialColumnInfo.new(self, quote_string(table_name.to_s))
33
35
  # Limit, precision, and scale are all handled by the superclass.
34
- spatial_info_ = spatial_column_info(table_name)
35
36
  column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod|
36
37
  oid = column_type_map.fetch(oid.to_i, fmod.to_i) { OID::Identity.new }
37
38
  SpatialColumn.new(@rgeo_factory_settings,
@@ -41,7 +42,7 @@ module ActiveRecord # :nodoc:
41
42
  oid,
42
43
  type,
43
44
  notnull == 'f',
44
- type =~ /geometry/i ? spatial_info_[column_name] : nil)
45
+ column_info.get(column_name, type))
45
46
  end
46
47
  end
47
48
 
@@ -112,12 +113,15 @@ module ActiveRecord # :nodoc:
112
113
  table_definition = td
113
114
  end
114
115
  table_definition.non_geographic_spatial_columns.each do |col|
115
- type = col.spatial_type.gsub('_', '').upcase
116
- has_z = col.has_z?
117
- has_m = col.has_m?
118
- type = "#{type}M" if has_m && !has_z
119
- dimensions_ = set_dimensions(has_m, has_z)
120
- execute("SELECT AddGeometryColumn('#{quote_string(table_name)}', '#{quote_string(col.name.to_s)}', #{col.srid}, '#{quote_string(type)}', #{dimensions_})")
116
+ options = {
117
+ has_m: col.has_m?,
118
+ has_z: col.has_z?,
119
+ srid: col.srid,
120
+ type: col.spatial_type,
121
+ }
122
+ column_name = col.name.to_s
123
+
124
+ add_spatial_column(table_name, column_name, options)
121
125
  end
122
126
  end
123
127
 
@@ -125,7 +129,7 @@ module ActiveRecord # :nodoc:
125
129
  table_name = table_name.to_s
126
130
  column_name = column_name.to_s
127
131
  if (info = spatial_column_constructor(type.to_sym))
128
- add_spatial_column(column_name, table_name, info, type, options)
132
+ add_spatial_column(table_name, column_name, info, type, options)
129
133
  else
130
134
  super
131
135
  end
@@ -154,30 +158,12 @@ module ActiveRecord # :nodoc:
154
158
  end
155
159
 
156
160
  def spatial_column_info(table_name)
157
- info = query("SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='#{quote_string(table_name.to_s)}'")
158
- result = {}
159
- info.each do |row|
160
- name = row[0]
161
- type = row[3]
162
- dimension = row[1].to_i
163
- has_m = !!(type =~ /m$/i)
164
- type.sub!(/m$/, '')
165
- has_z = dimension > 3 || dimension == 3 && !has_m
166
- result[name] = {
167
- :name => name,
168
- :type => type,
169
- :dimension => dimension,
170
- :srid => row[2].to_i,
171
- :has_z => has_z,
172
- :has_m => has_m,
173
- }
174
- end
175
- result
161
+ SpatialColumnInfo.new(self, quote_string(table_name.to_s)).all
176
162
  end
177
163
 
178
164
  private
179
165
 
180
- def add_spatial_column(column_name, table_name, info, type, options)
166
+ def add_spatial_column(table_name, column_name, info = {}, type = nil, options)
181
167
  limit = options[:limit]
182
168
  options.merge!(limit) if limit.is_a?(::Hash)
183
169
  type = (options[:type] || info[:type] || type).to_s.gsub('_', '').upcase
@@ -211,7 +197,6 @@ module ActiveRecord # :nodoc:
211
197
  dimensions += 1 if has_m
212
198
  dimensions
213
199
  end
214
-
215
200
  end
216
201
  end
217
202
  end
@@ -3,7 +3,7 @@ module ActiveRecord # :nodoc:
3
3
  module PostGISAdapter # :nodoc:
4
4
  class SpatialColumn < ConnectionAdapters::PostgreSQLColumn # :nodoc:
5
5
 
6
- def initialize(factory_settings, table_name, name, default, oid_type, sql_type=nil, null=true, opts=nil)
6
+ def initialize(factory_settings, table_name, name, default, oid_type, sql_type = nil, null = true, opts = nil)
7
7
  @factory_settings = factory_settings
8
8
  @table_name = table_name
9
9
  @geographic = !!(sql_type =~ /geography/i)
@@ -42,12 +42,12 @@ module ActiveRecord # :nodoc:
42
42
  super(name, default, oid_type, sql_type, null)
43
43
  if spatial?
44
44
  if @srid
45
- @limit = {:srid => @srid, :type => @geometric_type.type_name.underscore}
45
+ @limit = { srid: @srid, type: @geometric_type.type_name.underscore }
46
46
  @limit[:has_z] = true if @has_z
47
47
  @limit[:has_m] = true if @has_m
48
48
  @limit[:geographic] = true if @geographic
49
49
  else
50
- @limit = {:no_constraints => true}
50
+ @limit = { no_constraints: true }
51
51
  end
52
52
  end
53
53
  end
@@ -91,8 +91,12 @@ module ActiveRecord # :nodoc:
91
91
 
92
92
  def self.convert_to_geometry(input, factory_settings, table_name, column, geographic, srid, has_z, has_m)
93
93
  if srid
94
- constraints = {:geographic => geographic, :has_z_coordinate => has_z,
95
- :has_m_coordinate => has_m, :srid => srid}
94
+ constraints = {
95
+ geographic: geographic,
96
+ has_z_coordinate: has_z,
97
+ has_m_coordinate: has_m,
98
+ srid: srid
99
+ }
96
100
  else
97
101
  constraints = nil
98
102
  end
@@ -107,9 +111,9 @@ module ActiveRecord # :nodoc:
107
111
  factory = factory_settings.get_column_factory(table_name, column, constraints)
108
112
  marker = input[0,1]
109
113
  if marker == "\x00" || marker == "\x01" || input[0,4] =~ /[0-9a-fA-F]{4}/
110
- ::RGeo::WKRep::WKBParser.new(factory, :support_ewkb => true).parse(input) rescue nil
114
+ ::RGeo::WKRep::WKBParser.new(factory, support_ewkb: true).parse(input) rescue nil
111
115
  else
112
- ::RGeo::WKRep::WKTParser.new(factory, :support_ewkt => true).parse(input) rescue nil
116
+ ::RGeo::WKRep::WKTParser.new(factory, support_ewkt: true).parse(input) rescue nil
113
117
  end
114
118
  end
115
119
  else
@@ -129,7 +133,7 @@ module ActiveRecord # :nodoc:
129
133
 
130
134
  def type_cast(value)
131
135
  return if value.nil?
132
- ::RGeo::WKRep::WKBParser.new(@factory_generator, :support_ewkb => true).parse(value) rescue nil
136
+ ::RGeo::WKRep::WKBParser.new(@factory_generator, support_ewkb: true).parse(value) rescue nil
133
137
  end
134
138
 
135
139
  end
@@ -0,0 +1,42 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ConnectionAdapters # :nodoc:
3
+ module PostGISAdapter
4
+ # Do spatial sql queries for column info and memoize that info.
5
+ class SpatialColumnInfo
6
+ def initialize(adapter, table_name)
7
+ @adapter = adapter
8
+ @table_name = table_name
9
+ end
10
+
11
+ def all
12
+ info = @adapter.query("SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='#{@table_name}'")
13
+ result = {}
14
+ info.each do |row|
15
+ name = row[0]
16
+ type = row[3]
17
+ dimension = row[1].to_i
18
+ has_m = !!(type =~ /m$/i)
19
+ type.sub!(/m$/, '')
20
+ has_z = dimension > 3 || dimension == 3 && !has_m
21
+ result[name] = {
22
+ dimension: dimension,
23
+ has_m: has_m,
24
+ has_z: has_z,
25
+ name: name,
26
+ srid: row[2].to_i,
27
+ type: type,
28
+ }
29
+ end
30
+ result
31
+ end
32
+
33
+ # will not query the database for non-spatial columns/tables
34
+ def get(column_name, type)
35
+ return nil unless type =~ /geometry/i
36
+ @spatial_column_info ||= all
37
+ @spatial_column_info[column_name]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module PostGISAdapter
4
- VERSION = '2.0.2'.freeze
4
+ VERSION = '2.1.0'.freeze
5
5
  end
6
6
  end
7
7
  end
data/test/basic_test.rb CHANGED
@@ -1,190 +1,182 @@
1
1
  require 'test_helper'
2
2
 
3
- module RGeo
4
- module ActiveRecord # :nodoc:
5
- module PostGISAdapter # :nodoc:
6
- module Tests # :nodoc:
7
- class BasicTest < ActiveSupport::TestCase # :nodoc:
8
- DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database.yml'
9
- OVERRIDE_DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database_local.yml'
10
-
11
- include AdapterTestHelper
12
-
13
- define_test_methods do
14
-
15
- def populate_ar_class(content)
16
- klass = create_ar_class
17
- case content
18
- when :mercator_point
19
- klass.connection.create_table(:spatial_test) do |t_|
20
- t_.column 'latlon', :point, :srid => 3785
21
- end
22
- when :latlon_point_geographic
23
- klass.connection.create_table(:spatial_test) do |t_|
24
- t_.column 'latlon', :point, :srid => 4326, :geographic => true
25
- end
26
- when :no_constraints
27
- klass.connection.create_table(:spatial_test) do |t_|
28
- t_.column 'geo', :geometry, :no_constraints => true
29
- end
30
- end
31
- klass
32
- end
33
-
34
- def test_version
35
- refute_nil ::ActiveRecord::ConnectionAdapters::PostGISAdapter::VERSION
36
- end
37
-
38
- def test_postgis_available
39
- connection = create_ar_class.connection
40
- assert_equal 'PostGIS', connection.adapter_name
41
- refute_nil connection.postgis_lib_version
42
- end
43
-
44
- def test_set_and_get_point
45
- klass = populate_ar_class(:mercator_point)
46
- obj = klass.new
47
- assert_nil obj.latlon
48
- obj.latlon = @factory.point(1.0, 2.0)
49
- assert_equal @factory.point(1.0, 2.0), obj.latlon
50
- assert_equal 3785, obj.latlon.srid
51
- end
52
-
53
- def test_set_and_get_point_from_wkt
54
- klass = populate_ar_class(:mercator_point)
55
- obj = klass.new
56
- assert_nil obj.latlon
57
- obj.latlon = 'POINT(1 2)'
58
- assert_equal @factory.point(1.0, 2.0), obj.latlon
59
- assert_equal 3785, obj.latlon.srid
60
- end
61
-
62
- def test_save_and_load_point
63
- klass = populate_ar_class(:mercator_point)
64
- obj = klass.new
65
- obj.latlon = @factory.point(1.0, 2.0)
66
- obj.save!
67
- id = obj.id
68
- obj2 = klass.find(id)
69
- assert_equal @factory.point(1.0, 2.0), obj2.latlon
70
- assert_equal 3785, obj2.latlon.srid
71
- assert_equal true, ::RGeo::Geos.is_geos?(obj2.latlon)
72
- end
73
-
74
- def test_save_and_load_geographic_point
75
- klass = populate_ar_class(:latlon_point_geographic)
76
- obj = klass.new
77
- obj.latlon = @factory.point(1.0, 2.0)
78
- obj.save!
79
- id = obj.id
80
- obj2 = klass.find(id)
81
- assert_equal @geographic_factory.point(1.0, 2.0), obj2.latlon
82
- assert_equal 4326, obj2.latlon.srid
83
- assert_equal false, ::RGeo::Geos.is_geos?(obj2.latlon)
84
- end
85
-
86
- def test_save_and_load_point_from_wkt
87
- klass = populate_ar_class(:mercator_point)
88
- obj = klass.new
89
- obj.latlon = 'POINT(1 2)'
90
- obj.save!
91
- id = obj.id
92
- obj2 = klass.find(id)
93
- assert_equal @factory.point(1.0, 2.0), obj2.latlon
94
- assert_equal 3785, obj2.latlon.srid
95
- end
96
-
97
- def test_set_point_bad_wkt
98
- klass = populate_ar_class(:mercator_point)
99
- obj = klass.create(:latlon => 'POINT (x)')
100
- assert_nil obj.latlon
101
- end
102
-
103
- def test_set_point_wkt_wrong_type
104
- klass = populate_ar_class(:mercator_point)
105
- assert_raises(::ActiveRecord::StatementInvalid) do
106
- klass.create(:latlon => 'LINESTRING(1 2, 3 4, 5 6)')
107
- end
108
- end
109
-
110
- def test_custom_factory
111
- klass = create_ar_class
112
- klass.connection.create_table(:spatial_test) do |t|
113
- t.point(:latlon, :srid => 4326)
114
- end
115
- factory = ::RGeo::Geographic.simple_mercator_factory
116
- klass.class_eval do
117
- set_rgeo_factory_for_column(:latlon, factory)
118
- end
119
- rec_ = klass.new
120
- rec_.latlon = 'POINT(-122 47)'
121
- assert_equal factory, rec_.latlon.factory
122
- rec_.save!
123
- assert_equal factory, rec_.latlon.factory
124
- rec2_ = klass.find(rec_.id)
125
- assert_equal factory, rec2_.latlon.factory
126
- end
127
-
128
- def test_readme_example
129
- klass = create_ar_class
130
- klass.connection.create_table(:spatial_test) do |t_|
131
- t_.column(:shape, :geometry)
132
- t_.line_string(:path, :srid => 3785)
133
- t_.point(:latlon, :geographic => true)
134
- end
135
- klass.connection.change_table(:spatial_test) do |t_|
136
- t_.index(:latlon, :spatial => true)
137
- end
138
- klass.class_eval do
139
- self.rgeo_factory_generator = ::RGeo::Geos.method(:factory)
140
- set_rgeo_factory_for_column(:latlon, ::RGeo::Geographic.spherical_factory)
141
- end
142
- rec_ = klass.new
143
- rec_.latlon = 'POINT(-122 47)'
144
- loc_ = rec_.latlon
145
- assert_equal 47, loc_.latitude
146
- rec_.shape = loc_
147
- assert_equal true, ::RGeo::Geos.is_geos?(rec_.shape)
148
- end
149
-
150
- # no_constraints no longer supported in PostGIS 2.0
151
- def _test_save_and_load_no_constraints
152
- klass = populate_ar_class(:no_constraints)
153
- factory1_ = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
154
- factory2_ = ::RGeo::Cartesian.preferred_factory(:srid => 2000)
155
- obj = klass.new
156
- obj.geo = factory1_.point(1.0, 2.0)
157
- obj.save!
158
- id = obj.id
159
- obj2 = klass.find(id)
160
- assert_equal factory1_.point(1.0, 2.0), obj2.geo
161
- assert_equal 3785, obj2.geo.srid
162
- obj2.geo = factory2_.point(3.0, 4.0)
163
- obj2.save!
164
- obj3 = klass.find(id)
165
- assert_equal factory2_.point(3.0, 4.0), obj3.geo
166
- assert_equal 2000, obj3.geo.srid
167
- end
168
-
169
- def test_point_to_json
170
- klass = populate_ar_class(:mercator_point)
171
- obj = klass.new
172
- assert_match(/"latlon":null/, obj.to_json)
173
- obj.latlon = @factory.point(1.0, 2.0)
174
- assert_match(/"latlon":"POINT\s\(1\.0\s2\.0\)"/, obj.to_json)
175
- end
176
-
177
- def test_custom_column
178
- klass = populate_ar_class(:mercator_point)
179
- rec = klass.new
180
- rec.latlon = 'POINT(0 0)'
181
- rec.save
182
- refute_nil klass.select("CURRENT_TIMESTAMP as ts").first.ts
183
- end
184
-
185
- end
3
+ class BasicTest < ActiveSupport::TestCase # :nodoc:
4
+ DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database.yml'
5
+ OVERRIDE_DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database_local.yml'
6
+
7
+ include RGeo::ActiveRecord::AdapterTestHelper
8
+
9
+ define_test_methods do
10
+
11
+ def populate_ar_class(content)
12
+ klass = create_ar_class
13
+ case content
14
+ when :mercator_point
15
+ klass.connection.create_table(:spatial_test) do |t_|
16
+ t_.column 'latlon', :point, :srid => 3785
17
+ end
18
+ when :latlon_point_geographic
19
+ klass.connection.create_table(:spatial_test) do |t_|
20
+ t_.column 'latlon', :point, :srid => 4326, :geographic => true
21
+ end
22
+ when :no_constraints
23
+ klass.connection.create_table(:spatial_test) do |t_|
24
+ t_.column 'geo', :geometry, :no_constraints => true
186
25
  end
187
26
  end
27
+ klass
28
+ end
29
+
30
+ def test_version
31
+ refute_nil ::ActiveRecord::ConnectionAdapters::PostGISAdapter::VERSION
32
+ end
33
+
34
+ def test_postgis_available
35
+ connection = create_ar_class.connection
36
+ assert_equal 'PostGIS', connection.adapter_name
37
+ refute_nil connection.postgis_lib_version
38
+ end
39
+
40
+ def test_set_and_get_point
41
+ klass = populate_ar_class(:mercator_point)
42
+ obj = klass.new
43
+ assert_nil obj.latlon
44
+ obj.latlon = @factory.point(1.0, 2.0)
45
+ assert_equal @factory.point(1.0, 2.0), obj.latlon
46
+ assert_equal 3785, obj.latlon.srid
47
+ end
48
+
49
+ def test_set_and_get_point_from_wkt
50
+ klass = populate_ar_class(:mercator_point)
51
+ obj = klass.new
52
+ assert_nil obj.latlon
53
+ obj.latlon = 'POINT(1 2)'
54
+ assert_equal @factory.point(1.0, 2.0), obj.latlon
55
+ assert_equal 3785, obj.latlon.srid
56
+ end
57
+
58
+ def test_save_and_load_point
59
+ klass = populate_ar_class(:mercator_point)
60
+ obj = klass.new
61
+ obj.latlon = @factory.point(1.0, 2.0)
62
+ obj.save!
63
+ id = obj.id
64
+ obj2 = klass.find(id)
65
+ assert_equal @factory.point(1.0, 2.0), obj2.latlon
66
+ assert_equal 3785, obj2.latlon.srid
67
+ assert_equal true, ::RGeo::Geos.is_geos?(obj2.latlon)
68
+ end
69
+
70
+ def test_save_and_load_geographic_point
71
+ klass = populate_ar_class(:latlon_point_geographic)
72
+ obj = klass.new
73
+ obj.latlon = @factory.point(1.0, 2.0)
74
+ obj.save!
75
+ id = obj.id
76
+ obj2 = klass.find(id)
77
+ assert_equal @geographic_factory.point(1.0, 2.0), obj2.latlon
78
+ assert_equal 4326, obj2.latlon.srid
79
+ assert_equal false, ::RGeo::Geos.is_geos?(obj2.latlon)
80
+ end
81
+
82
+ def test_save_and_load_point_from_wkt
83
+ klass = populate_ar_class(:mercator_point)
84
+ obj = klass.new
85
+ obj.latlon = 'POINT(1 2)'
86
+ obj.save!
87
+ id = obj.id
88
+ obj2 = klass.find(id)
89
+ assert_equal @factory.point(1.0, 2.0), obj2.latlon
90
+ assert_equal 3785, obj2.latlon.srid
91
+ end
92
+
93
+ def test_set_point_bad_wkt
94
+ klass = populate_ar_class(:mercator_point)
95
+ obj = klass.create(:latlon => 'POINT (x)')
96
+ assert_nil obj.latlon
97
+ end
98
+
99
+ def test_set_point_wkt_wrong_type
100
+ klass = populate_ar_class(:mercator_point)
101
+ assert_raises(::ActiveRecord::StatementInvalid) do
102
+ klass.create(:latlon => 'LINESTRING(1 2, 3 4, 5 6)')
103
+ end
104
+ end
105
+
106
+ def test_custom_factory
107
+ klass = create_ar_class
108
+ klass.connection.create_table(:spatial_test) do |t|
109
+ t.point(:latlon, :srid => 4326)
110
+ end
111
+ factory = ::RGeo::Geographic.simple_mercator_factory
112
+ klass.class_eval do
113
+ set_rgeo_factory_for_column(:latlon, factory)
114
+ end
115
+ rec_ = klass.new
116
+ rec_.latlon = 'POINT(-122 47)'
117
+ assert_equal factory, rec_.latlon.factory
118
+ rec_.save!
119
+ assert_equal factory, rec_.latlon.factory
120
+ rec2_ = klass.find(rec_.id)
121
+ assert_equal factory, rec2_.latlon.factory
122
+ end
123
+
124
+ def test_readme_example
125
+ klass = create_ar_class
126
+ klass.connection.create_table(:spatial_test) do |t_|
127
+ t_.column(:shape, :geometry)
128
+ t_.line_string(:path, :srid => 3785)
129
+ t_.point(:latlon, :geographic => true)
130
+ end
131
+ klass.connection.change_table(:spatial_test) do |t_|
132
+ t_.index(:latlon, :spatial => true)
133
+ end
134
+ klass.class_eval do
135
+ self.rgeo_factory_generator = ::RGeo::Geos.method(:factory)
136
+ set_rgeo_factory_for_column(:latlon, ::RGeo::Geographic.spherical_factory)
137
+ end
138
+ rec_ = klass.new
139
+ rec_.latlon = 'POINT(-122 47)'
140
+ loc_ = rec_.latlon
141
+ assert_equal 47, loc_.latitude
142
+ rec_.shape = loc_
143
+ assert_equal true, ::RGeo::Geos.is_geos?(rec_.shape)
144
+ end
145
+
146
+ # no_constraints no longer supported in PostGIS 2.0
147
+ def _test_save_and_load_no_constraints
148
+ klass = populate_ar_class(:no_constraints)
149
+ factory1_ = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
150
+ factory2_ = ::RGeo::Cartesian.preferred_factory(:srid => 2000)
151
+ obj = klass.new
152
+ obj.geo = factory1_.point(1.0, 2.0)
153
+ obj.save!
154
+ id = obj.id
155
+ obj2 = klass.find(id)
156
+ assert_equal factory1_.point(1.0, 2.0), obj2.geo
157
+ assert_equal 3785, obj2.geo.srid
158
+ obj2.geo = factory2_.point(3.0, 4.0)
159
+ obj2.save!
160
+ obj3 = klass.find(id)
161
+ assert_equal factory2_.point(3.0, 4.0), obj3.geo
162
+ assert_equal 2000, obj3.geo.srid
188
163
  end
164
+
165
+ def test_point_to_json
166
+ klass = populate_ar_class(:mercator_point)
167
+ obj = klass.new
168
+ assert_match(/"latlon":null/, obj.to_json)
169
+ obj.latlon = @factory.point(1.0, 2.0)
170
+ assert_match(/"latlon":"POINT\s\(1\.0\s2\.0\)"/, obj.to_json)
171
+ end
172
+
173
+ def test_custom_column
174
+ klass = populate_ar_class(:mercator_point)
175
+ rec = klass.new
176
+ rec.latlon = 'POINT(0 0)'
177
+ rec.save
178
+ refute_nil klass.select("CURRENT_TIMESTAMP as ts").first.ts
179
+ end
180
+
189
181
  end
190
182
  end