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.
Files changed (50) hide show
  1. data/History.rdoc +11 -0
  2. data/README.rdoc +17 -30
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/factory.c +4 -9
  5. data/ext/geos_c_impl/factory.h +8 -8
  6. data/ext/geos_c_impl/geometry.c +19 -2
  7. data/ext/geos_c_impl/geometry_collection.c +1 -1
  8. data/ext/geos_c_impl/polygon.c +2 -2
  9. data/lib/active_record/connection_adapters/mysql2spatial_adapter.rb +8 -6
  10. data/lib/active_record/connection_adapters/mysqlspatial_adapter.rb +8 -6
  11. data/lib/rgeo/active_record/arel_modifications.rb +4 -0
  12. data/lib/rgeo/active_record/base_modifications.rb +37 -2
  13. data/lib/rgeo/active_record/mysql_common.rb +2 -2
  14. data/lib/rgeo/cartesian.rb +6 -22
  15. data/lib/rgeo/cartesian/analysis.rb +3 -0
  16. data/lib/rgeo/cartesian/bounding_box.rb +337 -0
  17. data/lib/rgeo/cartesian/feature_classes.rb +11 -11
  18. data/lib/rgeo/cartesian/feature_methods.rb +5 -0
  19. data/lib/rgeo/cartesian/interface.rb +21 -4
  20. data/lib/rgeo/features/geometry.rb +0 -15
  21. data/lib/rgeo/geography/interface.rb +33 -6
  22. data/lib/rgeo/geography/simple_mercator/feature_classes.rb +30 -17
  23. data/lib/rgeo/geography/simple_mercator/feature_methods.rb +1 -1
  24. data/lib/rgeo/geography/simple_spherical/feature_classes.rb +38 -11
  25. data/lib/rgeo/geos.rb +2 -0
  26. data/lib/rgeo/geos/factory.rb +37 -21
  27. data/lib/rgeo/geos/impl_additions.rb +20 -0
  28. data/lib/rgeo/geos/interface.rb +17 -8
  29. data/lib/rgeo/geos/zm_factory.rb +241 -0
  30. data/lib/rgeo/geos/zm_impl.rb +432 -0
  31. data/lib/rgeo/impl_helpers/basic_geometry_collection_methods.rb +39 -0
  32. data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +0 -5
  33. data/lib/rgeo/impl_helpers/basic_line_string_methods.rb +10 -1
  34. data/lib/rgeo/impl_helpers/basic_point_methods.rb +1 -13
  35. data/lib/rgeo/impl_helpers/basic_polygon_methods.rb +10 -0
  36. data/tests/common/geometry_collection_tests.rb +16 -0
  37. data/tests/common/point_tests.rb +27 -1
  38. data/tests/geos/tc_point.rb +2 -0
  39. data/tests/geos/tc_zmfactory.rb +85 -0
  40. data/tests/simple_cartesian/tc_geometry_collection.rb +1 -0
  41. data/tests/simple_cartesian/tc_point.rb +2 -1
  42. data/tests/simple_mercator/tc_point.rb +2 -0
  43. data/tests/simple_spherical/tc_geometry_collection.rb +2 -0
  44. data/tests/simple_spherical/tc_point.rb +2 -1
  45. data/tests/tc_oneoff.rb +0 -1
  46. data/tests/wkrep/tc_wkb_generator.rb +4 -4
  47. data/tests/wkrep/tc_wkb_parser.rb +2 -2
  48. data/tests/wkrep/tc_wkt_generator.rb +4 -4
  49. data/tests/wkrep/tc_wkt_parser.rb +5 -5
  50. metadata +23 -3
@@ -39,6 +39,9 @@ module RGeo
39
39
  module Cartesian
40
40
 
41
41
 
42
+ # This provides includes some spatial analysis algorithms supporting
43
+ # Cartesian data.
44
+
42
45
  module Analysis
43
46
 
44
47
  class << self
@@ -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
@@ -47,6 +47,11 @@ module RGeo
47
47
  end
48
48
 
49
49
 
50
+ def envelope
51
+ BoundingBox.new(factory).add(self).to_geometry
52
+ end
53
+
54
+
50
55
  end
51
56
 
52
57