ar-postgis 0.7.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.
Files changed (26) hide show
  1. checksums.yaml +7 -0
  2. data/Documentation.rdoc +292 -0
  3. data/History.rdoc +147 -0
  4. data/LICENSE.txt +29 -0
  5. data/README.rdoc +78 -0
  6. data/lib/active_record/connection_adapters/postgis_adapter.rb +38 -0
  7. data/lib/active_record/connection_adapters/postgis_adapter/rails4/create_connection.rb +29 -0
  8. data/lib/active_record/connection_adapters/postgis_adapter/rails4/databases.rake +17 -0
  9. data/lib/active_record/connection_adapters/postgis_adapter/rails4/main_adapter.rb +202 -0
  10. data/lib/active_record/connection_adapters/postgis_adapter/rails4/postgis_database_tasks.rb +204 -0
  11. data/lib/active_record/connection_adapters/postgis_adapter/rails4/spatial_column.rb +184 -0
  12. data/lib/active_record/connection_adapters/postgis_adapter/rails4/spatial_table_definition.rb +121 -0
  13. data/lib/active_record/connection_adapters/postgis_adapter/railtie.rb +3 -0
  14. data/lib/active_record/connection_adapters/postgis_adapter/shared/arel_tosql.rb +23 -0
  15. data/lib/active_record/connection_adapters/postgis_adapter/shared/common_adapter_methods.rb +46 -0
  16. data/lib/active_record/connection_adapters/postgis_adapter/shared/railtie.rb +13 -0
  17. data/lib/active_record/connection_adapters/postgis_adapter/shared/setup.rb +21 -0
  18. data/lib/active_record/connection_adapters/postgis_adapter/version.rb +7 -0
  19. data/lib/activerecord-postgis-adapter.rb +1 -0
  20. data/test/database.yml +5 -0
  21. data/test/tc_basic.rb +212 -0
  22. data/test/tc_ddl.rb +303 -0
  23. data/test/tc_nested_class.rb +48 -0
  24. data/test/tc_spatial_queries.rb +126 -0
  25. data/test/tc_tasks.rb +112 -0
  26. metadata +149 -0
@@ -0,0 +1,184 @@
1
+ module ActiveRecord # :nodoc:
2
+
3
+ module ConnectionAdapters # :nodoc:
4
+
5
+ module PostGISAdapter # :nodoc:
6
+
7
+
8
+ class SpatialColumn < ConnectionAdapters::PostgreSQLColumn # :nodoc:
9
+
10
+
11
+ def initialize(factory_settings_, table_name_, name_, default_, oid_type_, sql_type_=nil, null_=true, opts_=nil)
12
+ @factory_settings = factory_settings_
13
+ @table_name = table_name_
14
+ @geographic = sql_type_ =~ /geography/i ? true : false
15
+ if opts_
16
+ # This case comes from an entry in the geometry_columns table
17
+ @geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name(opts_[:type]) ||
18
+ ::RGeo::Feature::Geometry
19
+ @srid = opts_[:srid].to_i
20
+ @has_z = opts_[:has_z] ? true : false
21
+ @has_m = opts_[:has_m] ? true : false
22
+ elsif @geographic
23
+ # Geographic type information is embedded in the SQL type
24
+ @geometric_type = ::RGeo::Feature::Geometry
25
+ @srid = 4326
26
+ @has_z = @has_m = false
27
+ if sql_type_ =~ /geography\((.*)\)$/i
28
+ params_ = $1.split(',')
29
+ if params_.size >= 2
30
+ if params_.first =~ /([a-z]+[^zm])(z?)(m?)/i
31
+ @has_z = $2.length > 0
32
+ @has_m = $3.length > 0
33
+ @geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name($1)
34
+ end
35
+ if params_.last =~ /(\d+)/
36
+ @srid = $1.to_i
37
+ end
38
+ end
39
+ end
40
+ elsif sql_type_ =~ /geography|geometry|point|linestring|polygon/i
41
+ # Just in case there is a geometry column with no geometry_columns entry.
42
+ @geometric_type = ::RGeo::Feature::Geometry
43
+ @srid = @has_z = @has_m = nil
44
+ else
45
+ # Non-spatial column
46
+ @geometric_type = @has_z = @has_m = @srid = nil
47
+ end
48
+ super(name_, default_, oid_type_, sql_type_, null_)
49
+ if spatial?
50
+ if @srid
51
+ @limit = {:srid => @srid, :type => @geometric_type.type_name.underscore}
52
+ @limit[:has_z] = true if @has_z
53
+ @limit[:has_m] = true if @has_m
54
+ @limit[:geographic] = true if @geographic
55
+ else
56
+ @limit = {:no_constraints => true}
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ attr_reader :geographic
63
+ attr_reader :srid
64
+ attr_reader :geometric_type
65
+ attr_reader :has_z
66
+ attr_reader :has_m
67
+
68
+ alias_method :geographic?, :geographic
69
+ alias_method :has_z?, :has_z
70
+ alias_method :has_m?, :has_m
71
+
72
+
73
+ def spatial?
74
+ type == :spatial || type == :geography
75
+ end
76
+
77
+
78
+ def has_spatial_constraints?
79
+ !@srid.nil?
80
+ end
81
+
82
+
83
+ def klass
84
+ spatial? ? ::RGeo::Feature::Geometry : super
85
+ end
86
+
87
+
88
+ def type_cast(value_)
89
+ if spatial?
90
+ SpatialColumn.convert_to_geometry(value_, @factory_settings, @table_name, name,
91
+ @geographic, @srid, @has_z, @has_m)
92
+ else
93
+ super
94
+ end
95
+ end
96
+
97
+
98
+ private
99
+
100
+
101
+ def simplified_type(sql_type_)
102
+ sql_type_ =~ /geography|geometry|point|linestring|polygon/i ? :spatial : super
103
+ end
104
+
105
+
106
+ def self.convert_to_geometry(input_, factory_settings_, table_name_, column_, geographic_, srid_, has_z_, has_m_)
107
+ if srid_
108
+ constraints_ = {:geographic => geographic_, :has_z_coordinate => has_z_,
109
+ :has_m_coordinate => has_m_, :srid => srid_}
110
+ else
111
+ constraints_ = nil
112
+ end
113
+ if ::RGeo::Feature::Geometry === input_
114
+ factory_ = factory_settings_.get_column_factory(table_name_, column_, constraints_)
115
+ ::RGeo::Feature.cast(input_, factory_) rescue nil
116
+ elsif input_.respond_to?(:to_str)
117
+ input_ = input_.to_str
118
+ if input_.length == 0
119
+ nil
120
+ else
121
+ factory_ = factory_settings_.get_column_factory(table_name_, column_, constraints_)
122
+ marker_ = input_[0,1]
123
+ if marker_ == "\x00" || marker_ == "\x01" || input_[0,4] =~ /[0-9a-fA-F]{4}/
124
+ ::RGeo::WKRep::WKBParser.new(factory_, :support_ewkb => true).parse(input_) rescue nil
125
+ else
126
+ ::RGeo::WKRep::WKTParser.new(factory_, :support_ewkt => true).parse(input_) rescue nil
127
+ end
128
+ end
129
+ else
130
+ nil
131
+ end
132
+ end
133
+
134
+
135
+ end
136
+
137
+
138
+ # Register spatial types with the postgres OID mechanism
139
+ # so we can recognize custom columns coming from the database.
140
+
141
+ class SpatialOID < PostgreSQLAdapter::OID::Type # :nodoc:
142
+
143
+ def initialize(factory_generator_)
144
+ @factory_generator = factory_generator_
145
+ end
146
+
147
+ def type_cast(value_)
148
+ return if value_.nil?
149
+ ::RGeo::WKRep::WKBParser.new(@factory_generator, :support_ewkb => true).parse(value_) rescue nil
150
+ end
151
+
152
+ end
153
+
154
+ PostgreSQLAdapter::OID.register_type('geometry', SpatialOID.new(nil))
155
+ PostgreSQLAdapter::OID.register_type('geography', SpatialOID.new(::RGeo::Geographic.method(:spherical_factory)))
156
+
157
+
158
+ # This is a hack to ActiveRecord::ModelSchema. We have to "decorate" the decorate_columns
159
+ # method to apply class-specific customizations to spatial type casting.
160
+
161
+ module DecorateColumnsModification # :nodoc:
162
+
163
+ def decorate_columns(columns_hash_)
164
+ columns_hash_ = super(columns_hash_)
165
+ return unless columns_hash_
166
+ canonical_columns_ = self.columns_hash
167
+ columns_hash_.each do |name_, col_|
168
+ if col_.is_a?(SpatialOID) && (canonical_ = canonical_columns_[name_]) && canonical_.spatial?
169
+ columns_hash_[name_] = canonical_
170
+ end
171
+ end
172
+ columns_hash_
173
+ end
174
+
175
+ end
176
+
177
+ ::ActiveRecord::Base.extend(DecorateColumnsModification)
178
+
179
+
180
+ end
181
+
182
+ end
183
+
184
+ end
@@ -0,0 +1,121 @@
1
+ module ActiveRecord # :nodoc:
2
+
3
+ module ConnectionAdapters # :nodoc:
4
+
5
+ module PostGISAdapter # :nodoc:
6
+
7
+
8
+ class TableDefinition < ConnectionAdapters::PostgreSQLAdapter::TableDefinition # :nodoc:
9
+
10
+ def initialize(types_, name_, temporary_, options_, as_, base_)
11
+ @base = base_
12
+ @spatial_columns_hash = {}
13
+ super(types_, name_, temporary_, options_, as_)
14
+ end
15
+
16
+ def column(name_, type_, options_={})
17
+ if (info_ = @base.spatial_column_constructor(type_.to_sym))
18
+ type_ = options_[:type] || info_[:type] || type_
19
+ if type_.to_s == 'geometry' &&
20
+ (options_[:no_constraints] ||
21
+ options_[:limit].is_a?(::Hash) && options_[:limit][:no_constraints])
22
+ then
23
+ options_.delete(:limit)
24
+ else
25
+ options_[:type] = type_
26
+ type_ = :spatial
27
+ end
28
+ end
29
+ if type_ == :spatial
30
+ if (limit_ = options_.delete(:limit))
31
+ options_.merge!(limit_) if limit_.is_a?(::Hash)
32
+ end
33
+ if options_[:geographic]
34
+ type_ = :geography
35
+ spatial_type_ = (options_[:type] || 'geometry').to_s.upcase.gsub('_', '')
36
+ spatial_type_ << 'Z' if options_[:has_z]
37
+ spatial_type_ << 'M' if options_[:has_m]
38
+ options_[:limit] = "#{spatial_type_},#{options_[:srid] || 4326}"
39
+ end
40
+ name_ = name_.to_s
41
+ if primary_key_column_name == name_
42
+ raise ArgumentError, "you can't redefine the primary key column '#{name_}'. To define a custom primary key, pass { id: false } to create_table."
43
+ end
44
+ col_ = new_column_definition(name_, type_, options_)
45
+ col_.set_spatial_type(options_[:type])
46
+ col_.set_geographic(options_[:geographic])
47
+ col_.set_srid(options_[:srid])
48
+ col_.set_has_z(options_[:has_z])
49
+ col_.set_has_m(options_[:has_m])
50
+ (col_.geographic? ? @columns_hash : @spatial_columns_hash)[name_] = col_
51
+ else
52
+ super(name_, type_, options_)
53
+ end
54
+ self
55
+ end
56
+
57
+ def create_column_definition(name_, type_)
58
+ if type_ == :spatial || type_ == :geography
59
+ PostGISAdapter::ColumnDefinition.new(name_, type_)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ def non_geographic_spatial_columns
66
+ @spatial_columns_hash.values
67
+ end
68
+
69
+ end
70
+
71
+
72
+ class ColumnDefinition < ConnectionAdapters::ColumnDefinition # :nodoc:
73
+
74
+ def spatial_type
75
+ @spatial_type
76
+ end
77
+
78
+ def geographic?
79
+ @geographic
80
+ end
81
+
82
+ def srid
83
+ @srid ? @srid.to_i : (geographic? ? 4326 : -1)
84
+ end
85
+
86
+ def has_z?
87
+ @has_z
88
+ end
89
+
90
+ def has_m?
91
+ @has_m
92
+ end
93
+
94
+ def set_geographic(value_)
95
+ @geographic = value_ ? true : false
96
+ end
97
+
98
+ def set_spatial_type(value_)
99
+ @spatial_type = value_.to_s
100
+ end
101
+
102
+ def set_srid(value_)
103
+ @srid = value_
104
+ end
105
+
106
+ def set_has_z(value_)
107
+ @has_z = value_ ? true : false
108
+ end
109
+
110
+ def set_has_m(value_)
111
+ @has_m = value_ ? true : false
112
+ end
113
+
114
+ end
115
+
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,3 @@
1
+ require 'rails/railtie'
2
+ require 'active_record/connection_adapters/postgis_adapter'
3
+ load ::File.expand_path('shared/railtie.rb', ::File.dirname(__FILE__))
@@ -0,0 +1,23 @@
1
+ module Arel # :nodoc:
2
+ module Visitors # :nodoc:
3
+
4
+ class PostGIS < PostgreSQL # :nodoc:
5
+
6
+ FUNC_MAP = {
7
+ 'st_wkttosql' => 'ST_GeomFromEWKT',
8
+ }
9
+
10
+ include ::RGeo::ActiveRecord::SpatialToSql
11
+
12
+ def st_func(standard_name_)
13
+ FUNC_MAP[standard_name_.downcase] || standard_name_
14
+ end
15
+
16
+ alias_method :visit_in_spatial_context, :visit
17
+
18
+ end
19
+
20
+ VISITORS['postgis'] = ::Arel::Visitors::PostGIS
21
+
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ConnectionAdapters # :nodoc:
3
+ module PostGISAdapter # :nodoc:
4
+ SPATIAL_COLUMN_CONSTRUCTORS = ::RGeo::ActiveRecord::DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS.merge(
5
+ :geography => {:type => 'geometry', :geographic => true}
6
+ )
7
+
8
+ module CommonAdapterMethods # :nodoc:
9
+ def set_rgeo_factory_settings(factory_settings_)
10
+ @rgeo_factory_settings = factory_settings_
11
+ end
12
+
13
+ def adapter_name
14
+ PostGISAdapter::ADAPTER_NAME
15
+ end
16
+
17
+ def spatial_column_constructor(name_)
18
+ PostGISAdapter::SPATIAL_COLUMN_CONSTRUCTORS[name_]
19
+ end
20
+
21
+ def postgis_lib_version
22
+ @postgis_lib_version ||= select_value("SELECT PostGIS_Lib_Version()")
23
+ end
24
+
25
+ # http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
26
+ def default_srid
27
+ 0
28
+ end
29
+
30
+ def srs_database_columns
31
+ {:srtext_column => 'srtext', :proj4text_column => 'proj4text', :auth_name_column => 'auth_name', :auth_srid_column => 'auth_srid'}
32
+ end
33
+
34
+ def quote(value_, column_=nil)
35
+ if ::RGeo::Feature::Geometry.check_type(value_)
36
+ "'#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value_)}'"
37
+ elsif value_.is_a?(::RGeo::Cartesian::BoundingBox)
38
+ "'#{value_.min_x},#{value_.min_y},#{value_.max_x},#{value_.max_y}'::box"
39
+ else
40
+ super
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ unless defined?(::ActiveRecord::ConnectionAdapters::PostGISAdapter::Railtie)
2
+ module ActiveRecord # :nodoc:
3
+ module ConnectionAdapters # :nodoc:
4
+ module PostGISAdapter # :nodoc:
5
+ class Railtie < ::Rails::Railtie # :nodoc:
6
+ rake_tasks do
7
+ load ::File.expand_path("../rails4/databases.rake", ::File.dirname(__FILE__))
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveRecord # :nodoc:
2
+
3
+ module ConnectionAdapters # :nodoc:
4
+
5
+ module PostGISAdapter # :nodoc:
6
+
7
+
8
+ def self.initial_setup
9
+ gis_ignore_tables_ = ['geometry_columns', 'spatial_ref_sys', 'layer', 'topology']
10
+ ignore_tables_ = ::ActiveRecord::SchemaDumper.ignore_tables
11
+ gis_ignore_tables_.each do |table_|
12
+ ignore_tables_ << table_ unless ignore_tables_.include?(table_)
13
+ end
14
+ end
15
+
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module PostGISAdapter
4
+ VERSION = "0.7.0".freeze
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'active_record/connection_adapters/postgis_adapter.rb'
data/test/database.yml ADDED
@@ -0,0 +1,5 @@
1
+ adapter: postgis
2
+ host: 127.0.0.1
3
+ database: postgis_adapter_test
4
+ username: postgres
5
+ setup: default
data/test/tc_basic.rb ADDED
@@ -0,0 +1,212 @@
1
+ require 'minitest/autorun'
2
+ require 'rgeo/active_record/adapter_test_helper'
3
+
4
+
5
+ module RGeo
6
+ module ActiveRecord # :nodoc:
7
+ module PostGISAdapter # :nodoc:
8
+ module Tests # :nodoc:
9
+
10
+ class TestBasic < ::MiniTest::Test # :nodoc:
11
+
12
+ DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database.yml'
13
+ OVERRIDE_DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database_local.yml'
14
+
15
+ include AdapterTestHelper
16
+
17
+ define_test_methods do
18
+
19
+
20
+ def populate_ar_class(content_)
21
+ klass_ = create_ar_class
22
+ case content_
23
+ when :mercator_point
24
+ klass_.connection.create_table(:spatial_test) do |t_|
25
+ t_.column 'latlon', :point, :srid => 3785
26
+ end
27
+ when :latlon_point_geographic
28
+ klass_.connection.create_table(:spatial_test) do |t_|
29
+ t_.column 'latlon', :point, :srid => 4326, :geographic => true
30
+ end
31
+ when :no_constraints
32
+ klass_.connection.create_table(:spatial_test) do |t_|
33
+ t_.column 'geo', :geometry, :no_constraints => true
34
+ end
35
+ end
36
+ klass_
37
+ end
38
+
39
+
40
+ def test_version
41
+ refute_nil(::ActiveRecord::ConnectionAdapters::PostGISAdapter::VERSION)
42
+ end
43
+
44
+
45
+ def test_postgis_available
46
+ connection_ = create_ar_class.connection
47
+ assert_equal('PostGIS', connection_.adapter_name)
48
+ refute_nil(connection_.postgis_lib_version)
49
+ end
50
+
51
+
52
+ def test_set_and_get_point
53
+ klass_ = populate_ar_class(:mercator_point)
54
+ obj_ = klass_.new
55
+ assert_nil(obj_.latlon)
56
+ obj_.latlon = @factory.point(1.0, 2.0)
57
+ assert_equal(@factory.point(1.0, 2.0), obj_.latlon)
58
+ assert_equal(3785, obj_.latlon.srid)
59
+ end
60
+
61
+
62
+ def test_set_and_get_point_from_wkt
63
+ klass_ = populate_ar_class(:mercator_point)
64
+ obj_ = klass_.new
65
+ assert_nil(obj_.latlon)
66
+ obj_.latlon = 'POINT(1 2)'
67
+ assert_equal(@factory.point(1.0, 2.0), obj_.latlon)
68
+ assert_equal(3785, obj_.latlon.srid)
69
+ end
70
+
71
+
72
+ def test_save_and_load_point
73
+ klass_ = populate_ar_class(:mercator_point)
74
+ obj_ = klass_.new
75
+ obj_.latlon = @factory.point(1.0, 2.0)
76
+ obj_.save!
77
+ id_ = obj_.id
78
+ obj2_ = klass_.find(id_)
79
+ assert_equal(@factory.point(1.0, 2.0), obj2_.latlon)
80
+ assert_equal(3785, obj2_.latlon.srid)
81
+ assert_equal(true, ::RGeo::Geos.is_geos?(obj2_.latlon))
82
+ end
83
+
84
+
85
+ def test_save_and_load_geographic_point
86
+ klass_ = populate_ar_class(:latlon_point_geographic)
87
+ obj_ = klass_.new
88
+ obj_.latlon = @factory.point(1.0, 2.0)
89
+ obj_.save!
90
+ id_ = obj_.id
91
+ obj2_ = klass_.find(id_)
92
+ assert_equal(@geographic_factory.point(1.0, 2.0), obj2_.latlon)
93
+ assert_equal(4326, obj2_.latlon.srid)
94
+ assert_equal(false, ::RGeo::Geos.is_geos?(obj2_.latlon))
95
+ end
96
+
97
+
98
+ def test_save_and_load_point_from_wkt
99
+ klass_ = populate_ar_class(:mercator_point)
100
+ obj_ = klass_.new
101
+ obj_.latlon = 'POINT(1 2)'
102
+ obj_.save!
103
+ id_ = obj_.id
104
+ obj2_ = klass_.find(id_)
105
+ assert_equal(@factory.point(1.0, 2.0), obj2_.latlon)
106
+ assert_equal(3785, obj2_.latlon.srid)
107
+ end
108
+
109
+
110
+ def test_set_point_bad_wkt
111
+ klass_ = populate_ar_class(:mercator_point)
112
+ obj_ = klass_.create(:latlon => 'POINT (x)')
113
+ assert_nil(obj_.latlon)
114
+ end
115
+
116
+
117
+ def test_set_point_wkt_wrong_type
118
+ klass_ = populate_ar_class(:mercator_point)
119
+ assert_raises(::ActiveRecord::StatementInvalid) do
120
+ klass_.create(:latlon => 'LINESTRING(1 2, 3 4, 5 6)')
121
+ end
122
+ end
123
+
124
+
125
+ def test_custom_factory
126
+ klass_ = create_ar_class
127
+ klass_.connection.create_table(:spatial_test) do |t_|
128
+ t_.point(:latlon, :srid => 4326)
129
+ end
130
+ factory_ = ::RGeo::Geographic.simple_mercator_factory
131
+ klass_.class_eval do
132
+ set_rgeo_factory_for_column(:latlon, factory_)
133
+ end
134
+ rec_ = klass_.new
135
+ rec_.latlon = 'POINT(-122 47)'
136
+ assert_equal(factory_, rec_.latlon.factory)
137
+ rec_.save!
138
+ assert_equal(factory_, rec_.latlon.factory)
139
+ rec2_ = klass_.find(rec_.id)
140
+ assert_equal(factory_, rec2_.latlon.factory)
141
+ end
142
+
143
+
144
+ def test_readme_example
145
+ klass_ = create_ar_class
146
+ klass_.connection.create_table(:spatial_test) do |t_|
147
+ t_.column(:shape, :geometry)
148
+ t_.line_string(:path, :srid => 3785)
149
+ t_.point(:latlon, :geographic => true)
150
+ end
151
+ klass_.connection.change_table(:spatial_test) do |t_|
152
+ t_.index(:latlon, :spatial => true)
153
+ end
154
+ klass_.class_eval do
155
+ self.rgeo_factory_generator = ::RGeo::Geos.method(:factory)
156
+ set_rgeo_factory_for_column(:latlon, ::RGeo::Geographic.spherical_factory)
157
+ end
158
+ rec_ = klass_.new
159
+ rec_.latlon = 'POINT(-122 47)'
160
+ loc_ = rec_.latlon
161
+ assert_equal(47, loc_.latitude)
162
+ rec_.shape = loc_
163
+ assert_equal(true, ::RGeo::Geos.is_geos?(rec_.shape))
164
+ end
165
+
166
+
167
+ # no_constraints no longer supported in PostGIS 2.0
168
+ def _test_save_and_load_no_constraints
169
+ klass_ = populate_ar_class(:no_constraints)
170
+ factory1_ = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
171
+ factory2_ = ::RGeo::Cartesian.preferred_factory(:srid => 2000)
172
+ obj_ = klass_.new
173
+ obj_.geo = factory1_.point(1.0, 2.0)
174
+ obj_.save!
175
+ id_ = obj_.id
176
+ obj2_ = klass_.find(id_)
177
+ assert_equal(factory1_.point(1.0, 2.0), obj2_.geo)
178
+ assert_equal(3785, obj2_.geo.srid)
179
+ obj2_.geo = factory2_.point(3.0, 4.0)
180
+ obj2_.save!
181
+ obj3_ = klass_.find(id_)
182
+ assert_equal(factory2_.point(3.0, 4.0), obj3_.geo)
183
+ assert_equal(2000, obj3_.geo.srid)
184
+ end
185
+
186
+
187
+ def test_point_to_json
188
+ klass_ = populate_ar_class(:mercator_point)
189
+ obj_ = klass_.new
190
+ assert_match(/"latlon":null/, obj_.to_json)
191
+ obj_.latlon = @factory.point(1.0, 2.0)
192
+ assert_match(/"latlon":"POINT\s\(1\.0\s2\.0\)"/, obj_.to_json)
193
+ end
194
+
195
+
196
+ def test_custom_column
197
+ klass_ = populate_ar_class(:mercator_point)
198
+ rec_ = klass_.new
199
+ rec_.latlon = 'POINT(0 0)'
200
+ rec_.save
201
+ refute_nil(klass_.select("CURRENT_TIMESTAMP as ts").first.ts)
202
+ end
203
+
204
+
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+ end
211
+ end
212
+ end