rgeo 0.1.18 → 0.1.19
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.
- data/History.rdoc +11 -0
- data/README.rdoc +17 -30
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +4 -9
- data/ext/geos_c_impl/factory.h +8 -8
- data/ext/geos_c_impl/geometry.c +19 -2
- data/ext/geos_c_impl/geometry_collection.c +1 -1
- data/ext/geos_c_impl/polygon.c +2 -2
- data/lib/active_record/connection_adapters/mysql2spatial_adapter.rb +8 -6
- data/lib/active_record/connection_adapters/mysqlspatial_adapter.rb +8 -6
- data/lib/rgeo/active_record/arel_modifications.rb +4 -0
- data/lib/rgeo/active_record/base_modifications.rb +37 -2
- data/lib/rgeo/active_record/mysql_common.rb +2 -2
- data/lib/rgeo/cartesian.rb +6 -22
- data/lib/rgeo/cartesian/analysis.rb +3 -0
- data/lib/rgeo/cartesian/bounding_box.rb +337 -0
- data/lib/rgeo/cartesian/feature_classes.rb +11 -11
- data/lib/rgeo/cartesian/feature_methods.rb +5 -0
- data/lib/rgeo/cartesian/interface.rb +21 -4
- data/lib/rgeo/features/geometry.rb +0 -15
- data/lib/rgeo/geography/interface.rb +33 -6
- data/lib/rgeo/geography/simple_mercator/feature_classes.rb +30 -17
- data/lib/rgeo/geography/simple_mercator/feature_methods.rb +1 -1
- data/lib/rgeo/geography/simple_spherical/feature_classes.rb +38 -11
- data/lib/rgeo/geos.rb +2 -0
- data/lib/rgeo/geos/factory.rb +37 -21
- data/lib/rgeo/geos/impl_additions.rb +20 -0
- data/lib/rgeo/geos/interface.rb +17 -8
- data/lib/rgeo/geos/zm_factory.rb +241 -0
- data/lib/rgeo/geos/zm_impl.rb +432 -0
- data/lib/rgeo/impl_helpers/basic_geometry_collection_methods.rb +39 -0
- data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +0 -5
- data/lib/rgeo/impl_helpers/basic_line_string_methods.rb +10 -1
- data/lib/rgeo/impl_helpers/basic_point_methods.rb +1 -13
- data/lib/rgeo/impl_helpers/basic_polygon_methods.rb +10 -0
- data/tests/common/geometry_collection_tests.rb +16 -0
- data/tests/common/point_tests.rb +27 -1
- data/tests/geos/tc_point.rb +2 -0
- data/tests/geos/tc_zmfactory.rb +85 -0
- data/tests/simple_cartesian/tc_geometry_collection.rb +1 -0
- data/tests/simple_cartesian/tc_point.rb +2 -1
- data/tests/simple_mercator/tc_point.rb +2 -0
- data/tests/simple_spherical/tc_geometry_collection.rb +2 -0
- data/tests/simple_spherical/tc_point.rb +2 -1
- data/tests/tc_oneoff.rb +0 -1
- data/tests/wkrep/tc_wkb_generator.rb +4 -4
- data/tests/wkrep/tc_wkb_parser.rb +2 -2
- data/tests/wkrep/tc_wkt_generator.rb +4 -4
- data/tests/wkrep/tc_wkt_parser.rb +5 -5
- metadata +23 -3
@@ -0,0 +1,337 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Cartesian toplevel interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module Cartesian
|
40
|
+
|
41
|
+
|
42
|
+
# This is a bounding box for Cartesian data.
|
43
|
+
# The simple cartesian implementation uses this internally to compute
|
44
|
+
# envelopes. You may also use it directly to compute and represent
|
45
|
+
# bounding boxes.
|
46
|
+
#
|
47
|
+
# A bounding box is a set of ranges in each dimension: X, Y, as well
|
48
|
+
# as Z and M if supported. You can compute a bounding box for one or
|
49
|
+
# more geometry objects by creating a new bounding box object, and
|
50
|
+
# adding the geometries to it. You may then query it for the bounds,
|
51
|
+
# or use it to determine whether it encloses other geometries or
|
52
|
+
# bounding boxes.
|
53
|
+
|
54
|
+
class BoundingBox
|
55
|
+
|
56
|
+
|
57
|
+
# Create a new empty bounding box with the given factory.
|
58
|
+
#
|
59
|
+
# The factory defines the coordinate system for the bounding box,
|
60
|
+
# and also defines whether it should track Z and M coordinates.
|
61
|
+
# All geometries will be cast to this factory when added to this
|
62
|
+
# bounding box, and any generated envelope geometry will have this
|
63
|
+
# as its factory.
|
64
|
+
#
|
65
|
+
# Options include:
|
66
|
+
#
|
67
|
+
# <tt>:ignore_z</tt>::
|
68
|
+
# If true, ignore z coordinates even if the factory supports them.
|
69
|
+
# Default is false.
|
70
|
+
# <tt>:ignore_m</tt>::
|
71
|
+
# If true, ignore m coordinates even if the factory supports them.
|
72
|
+
# Default is false.
|
73
|
+
|
74
|
+
def initialize(factory_, opts_={})
|
75
|
+
@factory = factory_
|
76
|
+
@has_z = !opts_[:ignore_z] && factory_.has_capability?(:z_coordinate) ? true : false
|
77
|
+
@has_m = !opts_[:ignore_m] && factory_.has_capability?(:m_coordinate) ? true : false
|
78
|
+
@min_x = @max_x = @min_y = @max_y = @min_z = @max_z = @min_m = @max_m = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def eql?(rhs_) # :nodoc:
|
83
|
+
rhs_.is_a?(BoundingBox) && @factory == rhs_.factory &&
|
84
|
+
@min_x == rhs_.min_x && @max_x == rhs_.max_x &&
|
85
|
+
@min_y == rhs_.min_y && @max_y == rhs_.max_y &&
|
86
|
+
@min_z == rhs_.min_z && @max_z == rhs_.max_z &&
|
87
|
+
@min_m == rhs_.min_m && @max_m == rhs_.max_m
|
88
|
+
end
|
89
|
+
alias_method :==, :eql?
|
90
|
+
|
91
|
+
|
92
|
+
# Returns the bounding box's factory.
|
93
|
+
|
94
|
+
def factory
|
95
|
+
@factory
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Returns true if this bounding box is still empty.
|
100
|
+
|
101
|
+
def empty?
|
102
|
+
@min_x.nil?
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Returns true if this bounding box tracks Z coordinates.
|
107
|
+
|
108
|
+
def has_z
|
109
|
+
@has_z
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Returns true if this bounding box tracks M coordinates.
|
114
|
+
|
115
|
+
def has_m
|
116
|
+
@has_m
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Returns the minimum X, or nil if this bounding box is empty.
|
121
|
+
|
122
|
+
def min_x
|
123
|
+
@min_x
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Returns the maximum X, or nil if this bounding box is empty.
|
128
|
+
|
129
|
+
def max_x
|
130
|
+
@max_x
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Returns the minimum Y, or nil if this bounding box is empty.
|
135
|
+
|
136
|
+
def min_y
|
137
|
+
@min_y
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Returns the maximum Y, or nil if this bounding box is empty.
|
142
|
+
|
143
|
+
def max_y
|
144
|
+
@max_y
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Returns the minimum Z, or nil if this bounding box is empty.
|
149
|
+
|
150
|
+
def min_z
|
151
|
+
@min_z
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# Returns the maximum Z, or nil if this bounding box is empty.
|
156
|
+
|
157
|
+
def max_z
|
158
|
+
@max_z
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
# Returns the minimum M, or nil if this bounding box is empty.
|
163
|
+
|
164
|
+
def min_m
|
165
|
+
@min_m
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Returns the maximum M, or nil if this bounding box is empty.
|
170
|
+
|
171
|
+
def max_m
|
172
|
+
@max_m
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Returns a point representing the minimum extent in all dimensions,
|
177
|
+
# or nil if this bounding box is empty.
|
178
|
+
|
179
|
+
def min_point
|
180
|
+
if @min_x
|
181
|
+
extras_ = []
|
182
|
+
extras_ << @min_z if @has_z
|
183
|
+
extras_ << @min_m if @has_m
|
184
|
+
@factory.point(@min_x, @min_y, *extras_)
|
185
|
+
else
|
186
|
+
nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
# Returns a point representing the maximum extent in all dimensions,
|
192
|
+
# or nil if this bounding box is empty.
|
193
|
+
|
194
|
+
def max_point
|
195
|
+
if @min_x
|
196
|
+
extras_ = []
|
197
|
+
extras_ << @max_z if @has_z
|
198
|
+
extras_ << @max_m if @has_m
|
199
|
+
@factory.point(@max_x, @max_y, *extras_)
|
200
|
+
else
|
201
|
+
nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
# Adjusts the extents of this bounding box to encomass the given
|
207
|
+
# object, which may be a geometry or another bounding box.
|
208
|
+
# Returns self.
|
209
|
+
|
210
|
+
def add(geometry_)
|
211
|
+
case geometry_
|
212
|
+
when BoundingBox
|
213
|
+
add(geometry_.min_point)
|
214
|
+
add(geometry_.max_point)
|
215
|
+
when Features::Geometry
|
216
|
+
if geometry_.factory == @factory
|
217
|
+
_add_geometry(geometry_)
|
218
|
+
else
|
219
|
+
_add_geometry(Factory.cast(geometry_, @factory))
|
220
|
+
end
|
221
|
+
end
|
222
|
+
self
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
# Converts this bounding box to an envelope polygon.
|
227
|
+
# Returns the empty collection if this bounding box is empty.
|
228
|
+
|
229
|
+
def to_geometry
|
230
|
+
if @min_x
|
231
|
+
extras_ = []
|
232
|
+
extras_ << @min_z if @has_z
|
233
|
+
extras_ << @min_m if @has_m
|
234
|
+
point_min_ = @factory.point(@min_x, @min_y, *extras_)
|
235
|
+
if @min_x == @max_x && @min_y == @max_y
|
236
|
+
point_min_
|
237
|
+
else
|
238
|
+
extras_ = []
|
239
|
+
extras_ << @max_z if @has_z
|
240
|
+
extras_ << @max_m if @has_m
|
241
|
+
point_max_ = @factory.point(@max_x, @max_y, *extras_)
|
242
|
+
if @min_x == @max_x || @min_y == @max_y
|
243
|
+
@factory.line(point_min_, point_max_)
|
244
|
+
else
|
245
|
+
@factory.polygon(@factory.linear_ring(point_min_, @factory.point(@max_x, @min_y, *extras_), point_max_, @factory.point(@min_x, @max_y, *extras_), point_min_))
|
246
|
+
end
|
247
|
+
end
|
248
|
+
else
|
249
|
+
@factory.collection([])
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
# Returns true if this bounding box contains the given object,
|
255
|
+
# which may be a geometry or another bounding box.
|
256
|
+
#
|
257
|
+
# Supports these options:
|
258
|
+
#
|
259
|
+
# <tt>:ignore_z</tt>
|
260
|
+
# Ignore the Z coordinate when testing, even if both objects
|
261
|
+
# have Z. Default is false.
|
262
|
+
# <tt>:ignore_m</tt>
|
263
|
+
# Ignore the M coordinate when testing, even if both objects
|
264
|
+
# have M. Default is false.
|
265
|
+
|
266
|
+
def contains?(rhs_, opts_={})
|
267
|
+
if Features::Geometry === rhs_
|
268
|
+
contains?(BoundingBox.new(@factory).add(rhs_))
|
269
|
+
elsif rhs_.empty?
|
270
|
+
true
|
271
|
+
elsif empty?
|
272
|
+
false
|
273
|
+
elsif @min_x > rhs_.min_x || @max_x < rhs_.max_x || @min_y > rhs_.min_y || @max_y < rhs_.max_y
|
274
|
+
false
|
275
|
+
elsif @has_m && rhs_.has_m && !opts_[:ignore_m] && (@min_m > rhs_.min_m || @max_m < rhs_.max_m)
|
276
|
+
false
|
277
|
+
elsif @has_z && rhs_.has_z && !opts_[:ignore_z] && (@min_z > rhs_.min_z || @max_z < rhs_.max_z)
|
278
|
+
false
|
279
|
+
else
|
280
|
+
true
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
|
285
|
+
def _add_geometry(geometry_) # :nodoc:
|
286
|
+
case geometry_
|
287
|
+
when Features::Point
|
288
|
+
_add_point(geometry_)
|
289
|
+
when Features::LineString
|
290
|
+
geometry_.points.each{ |p_| _add_point(p_) }
|
291
|
+
when Features::Polygon
|
292
|
+
geometry_.exterior_ring.points.each{ |p_| _add_point(p_) }
|
293
|
+
when Features::MultiPoint
|
294
|
+
geometry_.each{ |p_| _add_point(p_) }
|
295
|
+
when Features::MultiLineString
|
296
|
+
geometry_.each{ |line_| line_.points.each{ |p_| _add_point(p_) } }
|
297
|
+
when Features::MultiPolygon
|
298
|
+
geometry_.each{ |poly_| poly_.exterior_ring.points.each{ |p_| _add_point(p_) } }
|
299
|
+
when Features::GeometryCollection
|
300
|
+
geometry_.each{ |g_| _add_geometry(g_) }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
def _add_point(point_) # :nodoc:
|
306
|
+
if @min_x
|
307
|
+
x_ = point_.x
|
308
|
+
@min_x = x_ if x_ < @min_x
|
309
|
+
@max_x = x_ if x_ > @max_x
|
310
|
+
y_ = point_.y
|
311
|
+
@min_y = y_ if y_ < @min_y
|
312
|
+
@max_y = y_ if y_ > @max_y
|
313
|
+
if @has_z
|
314
|
+
z_ = point_.z
|
315
|
+
@min_z = z_ if z_ < @min_z
|
316
|
+
@max_z = z_ if z_ > @max_z
|
317
|
+
end
|
318
|
+
if @has_m
|
319
|
+
m_ = point_.m
|
320
|
+
@min_m = m_ if m_ < @min_m
|
321
|
+
@max_m = m_ if m_ > @max_m
|
322
|
+
end
|
323
|
+
else
|
324
|
+
@min_x = @max_x = point_.x
|
325
|
+
@min_y = @max_y = point_.y
|
326
|
+
@min_z = @max_z = point_.z if @has_z
|
327
|
+
@min_m = @max_m = point_.m if @has_m
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
@@ -44,8 +44,8 @@ module RGeo
|
|
44
44
|
|
45
45
|
include ::RGeo::Features::Point
|
46
46
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
47
|
-
include ::RGeo::Cartesian::GeometryMethods
|
48
47
|
include ::RGeo::ImplHelpers::BasicPointMethods
|
48
|
+
include ::RGeo::Cartesian::GeometryMethods
|
49
49
|
|
50
50
|
|
51
51
|
def distance(rhs_)
|
@@ -69,8 +69,8 @@ module RGeo
|
|
69
69
|
|
70
70
|
include ::RGeo::Features::LineString
|
71
71
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
72
|
-
include ::RGeo::Cartesian::GeometryMethods
|
73
72
|
include ::RGeo::ImplHelpers::BasicLineStringMethods
|
73
|
+
include ::RGeo::Cartesian::GeometryMethods
|
74
74
|
include ::RGeo::Cartesian::LineStringMethods
|
75
75
|
|
76
76
|
|
@@ -82,10 +82,10 @@ module RGeo
|
|
82
82
|
|
83
83
|
include ::RGeo::Features::Line
|
84
84
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
85
|
-
include ::RGeo::Cartesian::GeometryMethods
|
86
85
|
include ::RGeo::ImplHelpers::BasicLineStringMethods
|
87
|
-
include ::RGeo::Cartesian::LineStringMethods
|
88
86
|
include ::RGeo::ImplHelpers::BasicLineMethods
|
87
|
+
include ::RGeo::Cartesian::GeometryMethods
|
88
|
+
include ::RGeo::Cartesian::LineStringMethods
|
89
89
|
|
90
90
|
|
91
91
|
end
|
@@ -96,10 +96,10 @@ module RGeo
|
|
96
96
|
|
97
97
|
include ::RGeo::Features::Line
|
98
98
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
99
|
-
include ::RGeo::Cartesian::GeometryMethods
|
100
99
|
include ::RGeo::ImplHelpers::BasicLineStringMethods
|
101
|
-
include ::RGeo::Cartesian::LineStringMethods
|
102
100
|
include ::RGeo::ImplHelpers::BasicLinearRingMethods
|
101
|
+
include ::RGeo::Cartesian::GeometryMethods
|
102
|
+
include ::RGeo::Cartesian::LineStringMethods
|
103
103
|
|
104
104
|
|
105
105
|
end
|
@@ -110,8 +110,8 @@ module RGeo
|
|
110
110
|
|
111
111
|
include ::RGeo::Features::Polygon
|
112
112
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
113
|
-
include ::RGeo::Cartesian::GeometryMethods
|
114
113
|
include ::RGeo::ImplHelpers::BasicPolygonMethods
|
114
|
+
include ::RGeo::Cartesian::GeometryMethods
|
115
115
|
|
116
116
|
|
117
117
|
end
|
@@ -122,8 +122,8 @@ module RGeo
|
|
122
122
|
|
123
123
|
include ::RGeo::Features::GeometryCollection
|
124
124
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
125
|
-
include ::RGeo::Cartesian::GeometryMethods
|
126
125
|
include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
|
126
|
+
include ::RGeo::Cartesian::GeometryMethods
|
127
127
|
|
128
128
|
|
129
129
|
end
|
@@ -134,9 +134,9 @@ module RGeo
|
|
134
134
|
|
135
135
|
include ::RGeo::Features::GeometryCollection
|
136
136
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
137
|
-
include ::RGeo::Cartesian::GeometryMethods
|
138
137
|
include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
|
139
138
|
include ::RGeo::ImplHelpers::BasicMultiPointMethods
|
139
|
+
include ::RGeo::Cartesian::GeometryMethods
|
140
140
|
|
141
141
|
|
142
142
|
end
|
@@ -147,9 +147,9 @@ module RGeo
|
|
147
147
|
|
148
148
|
include ::RGeo::Features::GeometryCollection
|
149
149
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
150
|
-
include ::RGeo::Cartesian::GeometryMethods
|
151
150
|
include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
|
152
151
|
include ::RGeo::ImplHelpers::BasicMultiLineStringMethods
|
152
|
+
include ::RGeo::Cartesian::GeometryMethods
|
153
153
|
|
154
154
|
|
155
155
|
end
|
@@ -160,9 +160,9 @@ module RGeo
|
|
160
160
|
|
161
161
|
include ::RGeo::Features::GeometryCollection
|
162
162
|
include ::RGeo::ImplHelpers::BasicGeometryMethods
|
163
|
-
include ::RGeo::Cartesian::GeometryMethods
|
164
163
|
include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
|
165
164
|
include ::RGeo::ImplHelpers::BasicMultiPolygonMethods
|
165
|
+
include ::RGeo::Cartesian::GeometryMethods
|
166
166
|
|
167
167
|
|
168
168
|
end
|