activerecord-spatial 1.0.0 → 2.0.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 +4 -4
- data/.rubocop.yml +1670 -0
- data/Gemfile +12 -13
- data/Guardfile +7 -10
- data/MIT-LICENSE +1 -1
- data/README.rdoc +8 -19
- data/Rakefile +2 -1
- data/activerecord-spatial.gemspec +12 -13
- data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions/active_record.rb +46 -0
- data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions.rb +7 -38
- data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/postgis.rb +6 -7
- data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid.rb +4 -5
- data/lib/activerecord-spatial/active_record/models/geography_column.rb +1 -2
- data/lib/activerecord-spatial/active_record/models/geometry_column.rb +1 -2
- data/lib/activerecord-spatial/active_record/models/spatial_column.rb +1 -2
- data/lib/activerecord-spatial/active_record/models/spatial_ref_sys.rb +5 -6
- data/lib/activerecord-spatial/active_record.rb +0 -1
- data/lib/activerecord-spatial/associations/active_record.rb +62 -120
- data/lib/activerecord-spatial/associations/base.rb +26 -75
- data/lib/activerecord-spatial/associations/preloader/spatial_association.rb +57 -0
- data/lib/activerecord-spatial/associations/reflection/spatial_reflection.rb +41 -0
- data/lib/activerecord-spatial/associations.rb +26 -4
- data/lib/activerecord-spatial/spatial_columns.rb +85 -94
- data/lib/activerecord-spatial/spatial_function.rb +62 -51
- data/lib/activerecord-spatial/spatial_scope_constants/postgis_2_0.rb +48 -0
- data/lib/activerecord-spatial/spatial_scope_constants/postgis_2_2.rb +46 -0
- data/lib/activerecord-spatial/spatial_scope_constants/postgis_legacy.rb +30 -0
- data/lib/activerecord-spatial/spatial_scope_constants.rb +10 -61
- data/lib/activerecord-spatial/spatial_scopes.rb +47 -49
- data/lib/activerecord-spatial/version.rb +1 -2
- data/lib/activerecord-spatial.rb +2 -6
- data/lib/tasks/test.rake +21 -19
- data/test/.rubocop.yml +35 -0
- data/test/accessors_geographies_tests.rb +19 -19
- data/test/accessors_geometries_tests.rb +19 -19
- data/test/adapter_tests.rb +1 -2
- data/test/associations_tests.rb +181 -203
- data/test/geography_column_tests.rb +2 -3
- data/test/geometry_column_tests.rb +1 -2
- data/test/models/bar.rb +2 -3
- data/test/models/blort.rb +1 -2
- data/test/models/foo.rb +2 -3
- data/test/models/foo3d.rb +2 -3
- data/test/models/foo_geography.rb +2 -3
- data/test/models/zortable.rb +2 -3
- data/test/spatial_function_tests.rb +12 -17
- data/test/spatial_scopes_geographies_tests.rb +17 -20
- data/test/spatial_scopes_tests.rb +84 -75
- data/test/test_helper.rb +66 -79
- metadata +16 -14
- data/lib/activerecord-spatial/associations/active_record_3.rb +0 -123
@@ -2,8 +2,8 @@
|
|
2
2
|
module ActiveRecordSpatial
|
3
3
|
class SpatialFunction
|
4
4
|
DEFAULT_OPTIONS = {
|
5
|
-
:
|
6
|
-
:
|
5
|
+
column: ActiveRecordSpatial.default_column_name,
|
6
|
+
use_index: true
|
7
7
|
}.freeze
|
8
8
|
|
9
9
|
def initialize(klass)
|
@@ -18,30 +18,32 @@ module ActiveRecordSpatial
|
|
18
18
|
options = default_options(args.extract_options!)
|
19
19
|
|
20
20
|
geom = options.fetch(:geom_arg, args.first)
|
21
|
-
args = Array.wrap(options.fetch(:args, args.from(1)))
|
21
|
+
args = Array.wrap(options.fetch(:args, args.from(1))).collect do |arg|
|
22
|
+
arel_quoted_value(arg)
|
23
|
+
end
|
22
24
|
|
23
|
-
column_name =
|
24
|
-
first_geom_arg =
|
25
|
+
column_name = column_name(options[:column])
|
26
|
+
first_geom_arg = wrap_column_or_geometry(
|
25
27
|
@klass.arel_table[column_name],
|
26
28
|
options[:column]
|
27
29
|
)
|
28
|
-
geom_args = [
|
30
|
+
geom_args = [first_geom_arg]
|
29
31
|
|
30
32
|
if geom.present?
|
31
33
|
column_type = @klass.spatial_column_by_name(column_name).spatial_type
|
32
34
|
column_srid = @klass.srid_for(column_name)
|
33
35
|
|
34
|
-
|
36
|
+
if !geom.is_a?(Hash)
|
35
37
|
geom_arg = read_geos(geom, column_srid)
|
36
38
|
geom_srid = read_geom_srid(geom_arg, column_type)
|
37
|
-
geom_args <<
|
39
|
+
geom_args << set_srid_or_transform(column_srid, geom_srid, geom_arg, column_type)
|
38
40
|
else
|
39
41
|
klass = if geom[:class]
|
40
42
|
geom[:class]
|
41
43
|
elsif geom[:class_name]
|
42
44
|
geom[:class_name].classify.constantize
|
43
45
|
else
|
44
|
-
raise ArgumentError
|
46
|
+
raise ArgumentError, 'Need either a :class or :class_name option to determine the class.'
|
45
47
|
end
|
46
48
|
|
47
49
|
if geom[:value]
|
@@ -49,35 +51,49 @@ module ActiveRecordSpatial
|
|
49
51
|
geom_srid = read_geom_srid(geom_arg, column_type)
|
50
52
|
else
|
51
53
|
geom_arg = geom
|
52
|
-
geom_srid = klass.srid_for(
|
54
|
+
geom_srid = klass.srid_for(column_name(geom[:column]))
|
53
55
|
end
|
54
56
|
|
55
|
-
transformed_geom =
|
56
|
-
geom_args <<
|
57
|
+
transformed_geom = set_srid_or_transform(column_srid, geom_srid, geom_arg, column_type)
|
58
|
+
geom_args << wrap_column_or_geometry(transformed_geom, geom)
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
if options[:invert] && geom_args.length > 1
|
61
|
-
geom_args.reverse!
|
62
|
-
end
|
62
|
+
geom_args.reverse! if options[:invert] && geom_args.length > 1
|
63
63
|
|
64
64
|
ret = Arel::Nodes::NamedFunction.new(
|
65
65
|
function_name(function, options[:use_index]),
|
66
66
|
geom_args + args
|
67
67
|
)
|
68
68
|
|
69
|
-
if options[:allow_null]
|
70
|
-
ret = ret.or(first_geom_arg.eq(nil))
|
71
|
-
end
|
69
|
+
ret = ret.or(first_geom_arg.eq(nil)) if options[:allow_null]
|
72
70
|
|
73
71
|
ret
|
74
72
|
end
|
75
73
|
|
76
|
-
|
74
|
+
class << self
|
75
|
+
def additional_ordering(*args)
|
76
|
+
options = args.extract_options!
|
77
|
+
|
78
|
+
desc = if args.first == :desc
|
79
|
+
true
|
80
|
+
else
|
81
|
+
options[:desc]
|
82
|
+
end
|
83
|
+
|
84
|
+
''.tap do |ret|
|
85
|
+
ret << ' DESC' if desc
|
86
|
+
ret << " NULLS #{options[:nulls].to_s.upcase}" if options[:nulls]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
77
93
|
def set_srid_or_transform(column_srid, geom_srid, geom, type)
|
78
94
|
geom_param = case geom
|
79
95
|
when Geos::Geometry
|
80
|
-
Arel.sql("#{@klass.connection.quote(geom.to_ewkb)}
|
96
|
+
Arel.sql("#{@klass.connection.quote(geom.to_ewkb)}::geometry")
|
81
97
|
when Hash
|
82
98
|
table_name = if geom[:table_alias]
|
83
99
|
@klass.connection.quote_table_name(geom[:table_alias])
|
@@ -87,22 +103,22 @@ module ActiveRecordSpatial
|
|
87
103
|
geom[:class_name].classify.constantize.quoted_table_name
|
88
104
|
end
|
89
105
|
|
90
|
-
Arel.sql("#{table_name}.#{@klass.connection.quote_table_name(
|
106
|
+
Arel.sql("#{table_name}.#{@klass.connection.quote_table_name(column_name(geom[:column]))}")
|
91
107
|
else
|
92
|
-
raise ArgumentError
|
108
|
+
raise ArgumentError, 'Expected either a Geos::Geometry or a Hash.'
|
93
109
|
end
|
94
110
|
|
95
|
-
|
111
|
+
if column_srid != geom_srid
|
96
112
|
if column_srid == ActiveRecordSpatial::UNKNOWN_SRIDS[type] || geom_srid == ActiveRecordSpatial::UNKNOWN_SRIDS[type]
|
97
113
|
Arel::Nodes::NamedFunction.new(
|
98
114
|
function_name('SetSRID'),
|
99
|
-
[
|
115
|
+
[geom_param, column_srid]
|
100
116
|
)
|
101
117
|
|
102
118
|
else
|
103
119
|
Arel::Nodes::NamedFunction.new(
|
104
120
|
function_name('Transform'),
|
105
|
-
[
|
121
|
+
[geom_param, column_srid]
|
106
122
|
)
|
107
123
|
end
|
108
124
|
else
|
@@ -118,7 +134,7 @@ module ActiveRecordSpatial
|
|
118
134
|
end
|
119
135
|
|
120
136
|
def read_geom_srid(geos, column_type = :geometry)
|
121
|
-
if geos.srid
|
137
|
+
if geos.srid.zero? || geos.srid == -1
|
122
138
|
ActiveRecordSpatial::UNKNOWN_SRIDS[column_type]
|
123
139
|
else
|
124
140
|
geos.srid
|
@@ -128,16 +144,16 @@ module ActiveRecordSpatial
|
|
128
144
|
def default_options(*args)
|
129
145
|
options = args.extract_options!
|
130
146
|
|
131
|
-
if args.length
|
147
|
+
if args.length.positive?
|
132
148
|
desc = if args.first == :desc
|
133
149
|
true
|
134
150
|
else
|
135
151
|
options[:desc]
|
136
152
|
end
|
137
153
|
|
138
|
-
DEFAULT_OPTIONS.merge(
|
139
|
-
:
|
140
|
-
|
154
|
+
DEFAULT_OPTIONS.merge(
|
155
|
+
desc: desc
|
156
|
+
).merge(options || {})
|
141
157
|
else
|
142
158
|
DEFAULT_OPTIONS.merge(options || {})
|
143
159
|
end
|
@@ -156,47 +172,42 @@ module ActiveRecordSpatial
|
|
156
172
|
column_name_or_options[:name]
|
157
173
|
else
|
158
174
|
column_name_or_options
|
159
|
-
end
|
175
|
+
end
|
176
|
+
|
177
|
+
column_name || ActiveRecordSpatial.default_column_name
|
160
178
|
end
|
161
179
|
|
162
180
|
def wrap_column_or_geometry(column_name_or_geometry, options = nil)
|
163
181
|
if options.is_a?(Hash) && options[:wrapper]
|
164
182
|
wrapper, args = if options[:wrapper].is_a?(Hash)
|
165
|
-
[
|
183
|
+
[options[:wrapper].keys.first, Array.wrap(options[:wrapper].values.first)]
|
166
184
|
else
|
167
|
-
[
|
185
|
+
[options[:wrapper], []]
|
168
186
|
end
|
169
187
|
|
170
188
|
Arel::Nodes::NamedFunction.new(
|
171
189
|
function_name(wrapper),
|
172
|
-
[
|
190
|
+
[column_name_or_geometry, *args.collect { |arg| arel_quoted_value(arg) }]
|
173
191
|
)
|
174
192
|
else
|
175
193
|
column_name_or_geometry
|
176
194
|
end
|
177
195
|
end
|
178
196
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
desc = if args.first == :desc
|
184
|
-
true
|
197
|
+
def arel_nodes_quoted?
|
198
|
+
if defined?(@arel_nodes_quoted)
|
199
|
+
@arel_nodes_quoted
|
185
200
|
else
|
186
|
-
|
201
|
+
@arel_nodes_quoted = defined?(Arel::Nodes::Quoted)
|
187
202
|
end
|
203
|
+
end
|
188
204
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
if options[:nulls]
|
195
|
-
ret << " NULLS #{options[:nulls].to_s.upcase}"
|
196
|
-
end
|
205
|
+
def arel_quoted_value(value)
|
206
|
+
if arel_nodes_quoted?
|
207
|
+
Arel::Nodes::Quoted.new(value)
|
208
|
+
else
|
209
|
+
value
|
197
210
|
end
|
198
211
|
end
|
199
|
-
end
|
200
212
|
end
|
201
213
|
end
|
202
|
-
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
module ActiveRecordSpatial
|
3
|
+
module SpatialScopeConstants
|
4
|
+
ONE_ARGUMENT_MEASUREMENTS = %w{
|
5
|
+
3dlength_spheroid
|
6
|
+
length2d_spheroid
|
7
|
+
length_spheroid
|
8
|
+
}
|
9
|
+
|
10
|
+
ONE_ARGUMENT_MEASUREMENTS.concat(%w{
|
11
|
+
3dlength_spheroid
|
12
|
+
})
|
13
|
+
|
14
|
+
RELATIONSHIPS.concat(%w{
|
15
|
+
3dintersects
|
16
|
+
})
|
17
|
+
|
18
|
+
ZERO_ARGUMENT_MEASUREMENTS.concat(%w{
|
19
|
+
3dlength
|
20
|
+
3dperimeter
|
21
|
+
})
|
22
|
+
|
23
|
+
ONE_GEOMETRY_ARGUMENT_MEASUREMENTS.concat(%w{
|
24
|
+
3ddistance
|
25
|
+
3dmaxdistance
|
26
|
+
distance_sphere
|
27
|
+
})
|
28
|
+
|
29
|
+
ONE_GEOMETRY_ARGUMENT_AND_ONE_ARGUMENT_RELATIONSHIPS.concat(%w{
|
30
|
+
3ddwithin
|
31
|
+
3ddfullywithin
|
32
|
+
})
|
33
|
+
|
34
|
+
COMPATIBILITY_FUNCTION_ALIASES.merge!(
|
35
|
+
'order_by_st_length3d' => 'order_by_st_3dlength',
|
36
|
+
'order_by_st_perimeter3d' => 'order_by_st_3dperimeter',
|
37
|
+
'order_by_st_length3d_spheroid' => 'order_by_st_3dlength_spheroid',
|
38
|
+
'order_by_st_distancesphere' => 'order_by_st_distance_sphere'
|
39
|
+
)
|
40
|
+
|
41
|
+
FUNCTION_ALIASES.merge!(
|
42
|
+
'st_3d_dwithin' => 'st_3ddwithin',
|
43
|
+
'st_3d_dfully_within' => 'st_3ddfullywithin',
|
44
|
+
'order_by_st_3d_distance' => 'order_by_st_3ddistance',
|
45
|
+
'order_by_st_3d_max_distance' => 'order_by_st_3dmaxdistance'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
module ActiveRecordSpatial
|
3
|
+
module SpatialScopeConstants
|
4
|
+
ONE_ARGUMENT_MEASUREMENTS = %w{
|
5
|
+
lengthspheroid
|
6
|
+
}
|
7
|
+
|
8
|
+
RELATIONSHIPS.concat(%w{
|
9
|
+
3dintersects
|
10
|
+
})
|
11
|
+
|
12
|
+
ZERO_ARGUMENT_MEASUREMENTS.concat(%w{
|
13
|
+
3dlength
|
14
|
+
3dperimeter
|
15
|
+
})
|
16
|
+
|
17
|
+
ONE_GEOMETRY_ARGUMENT_MEASUREMENTS.concat(%w{
|
18
|
+
3ddistance
|
19
|
+
3dmaxdistance
|
20
|
+
distancesphere
|
21
|
+
})
|
22
|
+
|
23
|
+
ONE_GEOMETRY_ARGUMENT_AND_ONE_ARGUMENT_RELATIONSHIPS.concat(%w{
|
24
|
+
3ddwithin
|
25
|
+
3ddfullywithin
|
26
|
+
})
|
27
|
+
|
28
|
+
COMPATIBILITY_FUNCTION_ALIASES.merge!(
|
29
|
+
'order_by_st_length3d' => 'order_by_st_3dlength',
|
30
|
+
'order_by_st_perimeter3d' => 'order_by_st_3dperimeter',
|
31
|
+
'order_by_st_3dlength_spheroid' => 'order_by_st_lengthspheroid',
|
32
|
+
'order_by_st_length3d_spheroid' => 'order_by_st_lengthspheroid',
|
33
|
+
'order_by_st_2dlength_spheroid' => 'order_by_st_lengthspheroid',
|
34
|
+
'order_by_st_length2d_spheroid' => 'order_by_st_lengthspheroid',
|
35
|
+
'order_by_st_length_spheroid' => 'order_by_st_lengthspheroid',
|
36
|
+
'order_by_st_distance_sphere' => 'order_by_st_distancesphere'
|
37
|
+
)
|
38
|
+
|
39
|
+
FUNCTION_ALIASES.merge!(
|
40
|
+
'st_3d_dwithin' => 'st_3ddwithin',
|
41
|
+
'st_3d_dfully_within' => 'st_3ddfullywithin',
|
42
|
+
'order_by_st_3d_distance' => 'order_by_st_3ddistance',
|
43
|
+
'order_by_st_3d_max_distance' => 'order_by_st_3dmaxdistance'
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
module ActiveRecordSpatial
|
3
|
+
module SpatialScopeConstants
|
4
|
+
ONE_ARGUMENT_MEASUREMENTS = %w{
|
5
|
+
3dlength_spheroid
|
6
|
+
length2d_spheroid
|
7
|
+
length_spheroid
|
8
|
+
}
|
9
|
+
|
10
|
+
ONE_GEOMETRY_ARGUMENT_MEASUREMENTS.concat(%w{
|
11
|
+
distance_sphere
|
12
|
+
})
|
13
|
+
|
14
|
+
ZERO_ARGUMENT_MEASUREMENTS.concat(%w{
|
15
|
+
length3d
|
16
|
+
perimeter3d
|
17
|
+
})
|
18
|
+
|
19
|
+
ONE_ARGUMENT_MEASUREMENTS.concat(%w{
|
20
|
+
length3d_spheroid
|
21
|
+
})
|
22
|
+
|
23
|
+
COMPATIBILITY_FUNCTION_ALIASES.merge!(
|
24
|
+
'order_by_st_3dlength' => 'order_by_st_length3d',
|
25
|
+
'order_by_st_3dperimeter' => 'order_by_st_perimeter3d',
|
26
|
+
'order_by_st_3dlength_spheroid' => 'order_by_st_length3d_spheroid',
|
27
|
+
'order_by_st_distancesphere' => 'order_by_st_distance_sphere'
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
@@ -33,7 +33,7 @@ module ActiveRecordSpatial
|
|
33
33
|
|
34
34
|
ONE_GEOMETRY_ARGUMENT_MEASUREMENTS = %w{
|
35
35
|
distance
|
36
|
-
|
36
|
+
distancesphere
|
37
37
|
maxdistance
|
38
38
|
}
|
39
39
|
|
@@ -42,73 +42,22 @@ module ActiveRecordSpatial
|
|
42
42
|
dfullywithin
|
43
43
|
}
|
44
44
|
|
45
|
-
ONE_ARGUMENT_MEASUREMENTS = %w{
|
46
|
-
length2d_spheroid
|
47
|
-
length_spheroid
|
48
|
-
}
|
49
|
-
|
50
|
-
# Some functions were renamed in PostGIS 2.0.
|
51
|
-
if ActiveRecordSpatial::POSTGIS[:lib] >= '2.0'
|
52
|
-
RELATIONSHIPS.concat(%w{
|
53
|
-
3dintersects
|
54
|
-
})
|
55
|
-
|
56
|
-
ZERO_ARGUMENT_MEASUREMENTS.concat(%w{
|
57
|
-
3dlength
|
58
|
-
3dperimeter
|
59
|
-
})
|
60
|
-
|
61
|
-
ONE_ARGUMENT_MEASUREMENTS.concat(%w{
|
62
|
-
3dlength_spheroid
|
63
|
-
})
|
64
|
-
|
65
|
-
ONE_GEOMETRY_ARGUMENT_MEASUREMENTS.concat(%w{
|
66
|
-
3ddistance
|
67
|
-
3dmaxdistance
|
68
|
-
})
|
69
|
-
|
70
|
-
ONE_GEOMETRY_ARGUMENT_AND_ONE_ARGUMENT_RELATIONSHIPS.concat(%w{
|
71
|
-
3ddwithin
|
72
|
-
3ddfullywithin
|
73
|
-
})
|
74
|
-
else
|
75
|
-
ZERO_ARGUMENT_MEASUREMENTS.concat(%w{
|
76
|
-
length3d
|
77
|
-
perimeter3d
|
78
|
-
})
|
79
|
-
|
80
|
-
ONE_ARGUMENT_MEASUREMENTS.concat(%w{
|
81
|
-
length3d_spheroid
|
82
|
-
})
|
83
|
-
end
|
84
|
-
|
85
45
|
FUNCTION_ALIASES = {
|
86
46
|
'order_by_st_max_distance' => 'order_by_st_maxdistance',
|
87
47
|
'st_geometrytype' => 'st_geometry_type'
|
88
48
|
}
|
89
49
|
|
90
|
-
COMPATIBILITY_FUNCTION_ALIASES =
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
50
|
+
COMPATIBILITY_FUNCTION_ALIASES = {}
|
51
|
+
|
52
|
+
# Some functions were renamed or deprecated in PostGIS 2.2.
|
53
|
+
if ActiveRecordSpatial::POSTGIS[:lib] >= '2.2'
|
54
|
+
require 'activerecord-spatial/spatial_scope_constants/postgis_2_2'
|
55
|
+
elsif ActiveRecordSpatial::POSTGIS[:lib] >= '2.0'
|
56
|
+
require 'activerecord-spatial/spatial_scope_constants/postgis_2_0'
|
96
57
|
else
|
97
|
-
|
98
|
-
'order_by_st_3dlength' => 'order_by_st_length3d',
|
99
|
-
'order_by_st_3dperimeter' => 'order_by_st_perimeter3d',
|
100
|
-
'order_by_st_3dlength_spheroid' => 'order_by_st_length3d_spheroid'
|
101
|
-
}
|
58
|
+
require 'activerecord-spatial/spatial_scope_constants/postgis_legacy'
|
102
59
|
end
|
103
60
|
|
104
|
-
|
105
|
-
FUNCTION_ALIASES.merge!({
|
106
|
-
'st_3d_dwithin' => 'st_3ddwithin',
|
107
|
-
'st_3d_dfully_within' => 'st_3ddfullywithin',
|
108
|
-
'order_by_st_3d_distance' => 'order_by_st_3ddistance',
|
109
|
-
'order_by_st_3d_max_distance' => 'order_by_st_3dmaxdistance'
|
110
|
-
})
|
111
|
-
end
|
61
|
+
constants.each(&:freeze)
|
112
62
|
end
|
113
63
|
end
|
114
|
-
|
@@ -71,14 +71,14 @@ module ActiveRecordSpatial
|
|
71
71
|
# When wrapping a geometry column in a function, you can set the name of
|
72
72
|
# the function and its methods like so:
|
73
73
|
#
|
74
|
-
# Foo.st_within(geom, :
|
75
|
-
# :
|
76
|
-
# :
|
74
|
+
# Foo.st_within(geom, column: {
|
75
|
+
# name: :the_geom,
|
76
|
+
# wrapper: :centroid
|
77
77
|
# })
|
78
78
|
#
|
79
|
-
# Foo.st_within(geom, :
|
80
|
-
# :
|
81
|
-
# :
|
79
|
+
# Foo.st_within(geom, column: {
|
80
|
+
# wrapper: {
|
81
|
+
# snap: [ 'POINT (0 0)', 1 ]
|
82
82
|
# }
|
83
83
|
# })
|
84
84
|
#
|
@@ -131,126 +131,120 @@ module ActiveRecordSpatial
|
|
131
131
|
extend ActiveSupport::Concern
|
132
132
|
|
133
133
|
DEFAULT_OPTIONS = {
|
134
|
-
:
|
135
|
-
:
|
134
|
+
column: ActiveRecordSpatial.default_column_name,
|
135
|
+
use_index: true
|
136
136
|
}.freeze
|
137
137
|
|
138
138
|
included do
|
139
|
-
assert_arguments_length = proc
|
140
|
-
raise ArgumentError
|
141
|
-
|
142
|
-
}
|
139
|
+
assert_arguments_length = proc do |args, min, max = (1.0 / 0.0)|
|
140
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for #{min}-#{max})" unless args.length.between?(min, max)
|
141
|
+
end
|
143
142
|
|
144
143
|
SpatialScopeConstants::RELATIONSHIPS.each do |relationship|
|
145
|
-
|
144
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
146
145
|
scope :st_#{relationship}, lambda { |geom, options = {}|
|
147
146
|
options = {
|
148
|
-
:
|
147
|
+
geom_arg: geom
|
149
148
|
}.merge(options)
|
150
149
|
|
151
150
|
unless geom.nil?
|
152
|
-
|
151
|
+
where(
|
153
152
|
ActiveRecordSpatial::SpatialFunction.build!(self, '#{relationship}', options).to_sql
|
154
153
|
)
|
155
154
|
end
|
156
155
|
}
|
157
|
-
|
158
|
-
self.class_eval(src, __FILE__, line)
|
156
|
+
RUBY
|
159
157
|
end
|
160
158
|
|
161
159
|
SpatialScopeConstants::ONE_GEOMETRY_ARGUMENT_AND_ONE_ARGUMENT_RELATIONSHIPS.each do |relationship|
|
162
|
-
|
160
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
163
161
|
scope :st_#{relationship}, lambda { |geom, distance, options = {}|
|
164
162
|
options = {
|
165
|
-
:
|
166
|
-
:
|
163
|
+
geom_arg: geom,
|
164
|
+
args: distance
|
167
165
|
}.merge(options)
|
168
166
|
|
169
|
-
|
167
|
+
where(
|
170
168
|
ActiveRecordSpatial::SpatialFunction.build!(self, '#{relationship}', options).to_sql
|
171
169
|
)
|
172
170
|
}
|
173
|
-
|
174
|
-
self.class_eval(src, __FILE__, line)
|
171
|
+
RUBY
|
175
172
|
end
|
176
173
|
|
177
|
-
|
174
|
+
class_eval do
|
178
175
|
scope :st_geometry_type, lambda { |*args|
|
179
176
|
assert_arguments_length[args, 1]
|
180
177
|
options = args.extract_options!
|
181
178
|
types = args
|
182
179
|
|
183
|
-
|
180
|
+
where(
|
184
181
|
ActiveRecordSpatial::SpatialFunction.build!(self, 'GeometryType', options).in(types).to_sql
|
185
182
|
)
|
186
183
|
}
|
187
184
|
end
|
188
185
|
|
189
186
|
SpatialScopeConstants::ZERO_ARGUMENT_MEASUREMENTS.each do |measurement|
|
190
|
-
|
187
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
191
188
|
scope :order_by_st_#{measurement}, lambda { |options = {}|
|
192
189
|
if options.is_a?(Symbol)
|
193
190
|
options = {
|
194
|
-
:
|
191
|
+
desc: options
|
195
192
|
}
|
196
193
|
end
|
197
194
|
|
198
195
|
function_call = ActiveRecordSpatial::SpatialFunction.build!(self, '#{measurement}', options).to_sql
|
199
196
|
function_call << ActiveRecordSpatial::SpatialFunction.additional_ordering(options)
|
200
197
|
|
201
|
-
|
198
|
+
order(function_call)
|
202
199
|
}
|
203
|
-
|
204
|
-
self.class_eval(src, __FILE__, line)
|
200
|
+
RUBY
|
205
201
|
end
|
206
202
|
|
207
203
|
SpatialScopeConstants::ONE_GEOMETRY_ARGUMENT_MEASUREMENTS.each do |measurement|
|
208
|
-
|
204
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
209
205
|
scope :order_by_st_#{measurement}, lambda { |geom, options = {}|
|
210
206
|
if options.is_a?(Symbol)
|
211
207
|
options = {
|
212
|
-
:
|
208
|
+
desc: options
|
213
209
|
}
|
214
210
|
end
|
215
211
|
|
216
212
|
options = {
|
217
|
-
:
|
213
|
+
geom_arg: geom
|
218
214
|
}.merge(options)
|
219
215
|
|
220
216
|
function_call = ActiveRecordSpatial::SpatialFunction.build!(self, '#{measurement}', options).to_sql
|
221
217
|
function_call << ActiveRecordSpatial::SpatialFunction.additional_ordering(options)
|
222
218
|
|
223
|
-
|
219
|
+
order(function_call)
|
224
220
|
}
|
225
|
-
|
226
|
-
self.class_eval(src, __FILE__, line)
|
221
|
+
RUBY
|
227
222
|
end
|
228
223
|
|
229
224
|
SpatialScopeConstants::ONE_ARGUMENT_MEASUREMENTS.each do |measurement|
|
230
|
-
|
225
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
231
226
|
scope :order_by_st_#{measurement}, lambda { |argument, options = {}|
|
232
227
|
options = {
|
233
|
-
:
|
228
|
+
args: argument
|
234
229
|
}.merge(options)
|
235
230
|
|
236
231
|
function_call = ActiveRecordSpatial::SpatialFunction.build!(self, '#{measurement}', options).to_sql
|
237
232
|
function_call << ActiveRecordSpatial::SpatialFunction.additional_ordering(options)
|
238
233
|
|
239
|
-
|
234
|
+
order(function_call)
|
240
235
|
}
|
241
|
-
|
242
|
-
self.class_eval(src, __FILE__, line)
|
236
|
+
RUBY
|
243
237
|
end
|
244
238
|
|
245
|
-
|
239
|
+
class_eval do
|
246
240
|
scope :order_by_st_hausdorffdistance, lambda { |*args|
|
247
241
|
assert_arguments_length[args, 1, 3]
|
248
242
|
options = args.extract_options!
|
249
243
|
geom, densify_frac = args
|
250
244
|
|
251
245
|
options = {
|
252
|
-
:
|
253
|
-
:
|
246
|
+
geom_arg: geom,
|
247
|
+
args: densify_frac
|
254
248
|
}.merge(options)
|
255
249
|
|
256
250
|
function_call = ActiveRecordSpatial::SpatialFunction.build!(
|
@@ -260,23 +254,27 @@ module ActiveRecordSpatial
|
|
260
254
|
).to_sql
|
261
255
|
function_call << ActiveRecordSpatial::SpatialFunction.additional_ordering(options)
|
262
256
|
|
263
|
-
|
257
|
+
order(function_call)
|
264
258
|
}
|
265
259
|
|
266
260
|
scope :order_by_st_distance_spheroid, lambda { |geom, spheroid, options = {}|
|
267
261
|
options = {
|
268
|
-
:
|
269
|
-
:
|
262
|
+
geom_arg: geom,
|
263
|
+
args: spheroid
|
270
264
|
}.merge(options)
|
271
265
|
|
272
266
|
function_call = ActiveRecordSpatial::SpatialFunction.build!(
|
273
267
|
self,
|
274
|
-
'
|
268
|
+
if ActiveRecordSpatial::POSTGIS[:lib] >= '2.2'
|
269
|
+
'distancespheroid'
|
270
|
+
else
|
271
|
+
'distance_spheroid'
|
272
|
+
end,
|
275
273
|
options
|
276
274
|
).to_sql
|
277
275
|
function_call << ActiveRecordSpatial::SpatialFunction.additional_ordering(options)
|
278
276
|
|
279
|
-
|
277
|
+
order(function_call)
|
280
278
|
}
|
281
279
|
|
282
280
|
class << self
|