activerecord-postgis-adapter 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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