rgeo 2.3.0 → 3.0.0.pre.rc.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/README.md +1 -0
  4. data/ext/geos_c_impl/analysis.c +8 -6
  5. data/ext/geos_c_impl/analysis.h +1 -3
  6. data/ext/geos_c_impl/errors.c +10 -8
  7. data/ext/geos_c_impl/errors.h +7 -3
  8. data/ext/geos_c_impl/extconf.rb +3 -0
  9. data/ext/geos_c_impl/factory.c +251 -182
  10. data/ext/geos_c_impl/factory.h +43 -62
  11. data/ext/geos_c_impl/geometry.c +56 -24
  12. data/ext/geos_c_impl/geometry.h +8 -3
  13. data/ext/geos_c_impl/geometry_collection.c +41 -148
  14. data/ext/geos_c_impl/geometry_collection.h +1 -14
  15. data/ext/geos_c_impl/globals.c +91 -0
  16. data/ext/geos_c_impl/globals.h +45 -0
  17. data/ext/geos_c_impl/line_string.c +28 -29
  18. data/ext/geos_c_impl/line_string.h +1 -3
  19. data/ext/geos_c_impl/main.c +10 -9
  20. data/ext/geos_c_impl/point.c +9 -8
  21. data/ext/geos_c_impl/point.h +1 -3
  22. data/ext/geos_c_impl/polygon.c +15 -51
  23. data/ext/geos_c_impl/polygon.h +1 -3
  24. data/ext/geos_c_impl/preface.h +8 -0
  25. data/lib/rgeo/cartesian/analysis.rb +2 -2
  26. data/lib/rgeo/cartesian/calculations.rb +54 -17
  27. data/lib/rgeo/cartesian/factory.rb +0 -7
  28. data/lib/rgeo/cartesian/feature_classes.rb +66 -46
  29. data/lib/rgeo/cartesian/feature_methods.rb +56 -20
  30. data/lib/rgeo/cartesian/interface.rb +0 -6
  31. data/lib/rgeo/cartesian/planar_graph.rb +379 -0
  32. data/lib/rgeo/cartesian/sweepline_intersector.rb +149 -0
  33. data/lib/rgeo/cartesian/valid_op.rb +71 -0
  34. data/lib/rgeo/cartesian.rb +3 -0
  35. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +6 -6
  36. data/lib/rgeo/error.rb +15 -0
  37. data/lib/rgeo/feature/curve.rb +12 -2
  38. data/lib/rgeo/feature/geometry.rb +38 -28
  39. data/lib/rgeo/feature/geometry_collection.rb +13 -5
  40. data/lib/rgeo/feature/line_string.rb +3 -3
  41. data/lib/rgeo/feature/multi_curve.rb +6 -1
  42. data/lib/rgeo/feature/multi_surface.rb +3 -3
  43. data/lib/rgeo/feature/point.rb +4 -4
  44. data/lib/rgeo/feature/surface.rb +3 -3
  45. data/lib/rgeo/geographic/factory.rb +0 -7
  46. data/lib/rgeo/geographic/interface.rb +4 -18
  47. data/lib/rgeo/geographic/proj4_projector.rb +0 -2
  48. data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
  49. data/lib/rgeo/geographic/projected_feature_methods.rb +63 -30
  50. data/lib/rgeo/geographic/simple_mercator_projector.rb +0 -2
  51. data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
  52. data/lib/rgeo/geographic/spherical_feature_methods.rb +68 -2
  53. data/lib/rgeo/geos/capi_factory.rb +21 -31
  54. data/lib/rgeo/geos/capi_feature_classes.rb +64 -11
  55. data/lib/rgeo/geos/ffi_factory.rb +0 -28
  56. data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
  57. data/lib/rgeo/geos/ffi_feature_methods.rb +53 -10
  58. data/lib/rgeo/geos/interface.rb +18 -10
  59. data/lib/rgeo/geos/zm_factory.rb +0 -12
  60. data/lib/rgeo/geos/zm_feature_methods.rb +30 -5
  61. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +18 -8
  62. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -1
  63. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +37 -26
  64. data/lib/rgeo/impl_helper/basic_point_methods.rb +13 -3
  65. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +8 -3
  66. data/lib/rgeo/impl_helper/valid_op.rb +354 -0
  67. data/lib/rgeo/impl_helper/validity_check.rb +138 -0
  68. data/lib/rgeo/impl_helper.rb +1 -0
  69. data/lib/rgeo/version.rb +1 -1
  70. data/lib/rgeo/wkrep/wkb_generator.rb +1 -1
  71. data/lib/rgeo/wkrep/wkt_generator.rb +6 -6
  72. metadata +30 -7
@@ -0,0 +1,354 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module RGeo
6
+ module ImplHelper
7
+ # Mixin based off of the JTS/GEOS IsValidOp class.
8
+ # Implements #valid? and #invalid_reason on Features that include this.
9
+ #
10
+ # @see https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/operation/valid/IsValidOp.java
11
+ module ValidOp
12
+ # Validity of geometry
13
+ #
14
+ # @return Boolean
15
+ def valid?
16
+ invalid_reason.nil?
17
+ end
18
+
19
+ # Reason for invalidity or nil if valid
20
+ #
21
+ # @return String
22
+ def invalid_reason
23
+ return @invalid_reason if defined?(@invalid_reason)
24
+ @invalid_reason = check_valid
25
+ end
26
+
27
+ private
28
+
29
+ def validity_helper
30
+ ValidOpHelpers
31
+ end
32
+
33
+ # Method that performs validity checking. Just checks the type of geometry
34
+ # and delegates to the proper validity checker.
35
+ #
36
+ # Returns a string describing the error or nil if it's a valid geometry.
37
+ # In some cases, "Unkown Validity" is returned if a dependent method has
38
+ # not been implemented.
39
+ #
40
+ # @return String
41
+ def check_valid
42
+ case self
43
+ when Feature::Point
44
+ check_valid_point
45
+ when Feature::LinearRing
46
+ check_valid_linear_ring
47
+ when Feature::LineString
48
+ check_valid_line_string
49
+ when Feature::Polygon
50
+ check_valid_polygon
51
+ when Feature::MultiPoint
52
+ check_valid_multi_point
53
+ when Feature::MultiPolygon
54
+ check_valid_multi_polygon
55
+ when Feature::GeometryCollection
56
+ check_valid_geometry_collection
57
+ else
58
+ raise NotImplementedError, "check_valid is not implemented for #{self}"
59
+ end
60
+ rescue RGeo::Error::UnsupportedOperation, NoMethodError
61
+ "Unkown Validity"
62
+ end
63
+
64
+ def check_valid_point
65
+ validity_helper.check_invalid_coordinate(self)
66
+ end
67
+
68
+ def check_valid_line_string
69
+ # check coordinates are all valid
70
+ points.each do |pt|
71
+ check = validity_helper.check_invalid_coordinate(pt)
72
+ return check unless check.nil?
73
+ end
74
+
75
+ # check more than 1 point
76
+ return Error::TOO_FEW_POINTS unless num_points > 1
77
+
78
+ nil
79
+ end
80
+
81
+ def check_valid_linear_ring
82
+ # check coordinates are all valid
83
+ points.each do |pt|
84
+ check = validity_helper.check_invalid_coordinate(pt)
85
+ return check unless check.nil?
86
+ end
87
+
88
+ # check closed
89
+ return Error::UNCLOSED_RING unless closed?
90
+
91
+ # check more than 3 points
92
+ return Error::TOO_FEW_POINTS unless num_points > 3
93
+
94
+ # check no self-intersections
95
+ validity_helper.check_no_self_intersections(self)
96
+ end
97
+
98
+ def check_valid_polygon
99
+ # check coordinates are all valid
100
+ exterior_ring.points.each do |pt|
101
+ check = validity_helper.check_invalid_coordinate(pt)
102
+ return check unless check.nil?
103
+ end
104
+ interior_rings.each do |ring|
105
+ ring.points.each do |pt|
106
+ check = validity_helper.check_invalid_coordinate(pt)
107
+ return check unless check.nil?
108
+ end
109
+ end
110
+
111
+ # check closed
112
+ return Error::UNCLOSED_RING unless exterior_ring.closed?
113
+ return Error::UNCLOSED_RING unless interior_rings.all?(&:closed?)
114
+
115
+ # check more than 3 points in each ring
116
+ return Error::TOO_FEW_POINTS unless exterior_ring.num_points > 3
117
+ return Error::TOO_FEW_POINTS unless interior_rings.all? { |r| r.num_points > 3 }
118
+
119
+ # can skip this check if there's no holes
120
+ unless interior_rings.empty?
121
+ check = validity_helper.check_consistent_area(self)
122
+ return check unless check.nil?
123
+ end
124
+
125
+ # check that there are no self-intersections
126
+ check = validity_helper.check_no_self_intersecting_rings(self)
127
+ return check unless check.nil?
128
+
129
+ # can skip these checks if there's no holes
130
+ unless interior_rings.empty?
131
+ check = validity_helper.check_holes_in_shell(self)
132
+ return check unless check.nil?
133
+
134
+ check = validity_helper.check_holes_not_nested(self)
135
+ return check unless check.nil?
136
+
137
+ check = validity_helper.check_connected_interiors(self)
138
+ return check unless check.nil?
139
+ end
140
+
141
+ nil
142
+ end
143
+
144
+ def check_valid_multi_point
145
+ geometries.each do |pt|
146
+ check = validity_helper.check_invalid_coordinate(pt)
147
+ return check unless check.nil?
148
+ end
149
+ nil
150
+ end
151
+
152
+ def check_valid_multi_polygon
153
+ geometries.each do |poly|
154
+ return poly.invalid_reason unless poly.invalid_reason.nil?
155
+ end
156
+
157
+ check = validity_helper.check_consistent_area_mp(self)
158
+ return check unless check.nil?
159
+
160
+ # check no shells are nested
161
+ check = validity_helper.check_shells_not_nested(self)
162
+ return check unless check.nil?
163
+
164
+ nil
165
+ end
166
+
167
+ def check_valid_geometry_collection
168
+ geometries.each do |geom|
169
+ return geom.invalid_reason unless geom.invalid_reason.nil?
170
+ end
171
+
172
+ nil
173
+ end
174
+ end
175
+
176
+ ##
177
+ # Helper functions for specific validity checks
178
+ ##
179
+ module ValidOpHelpers
180
+ module_function
181
+
182
+ # Checks that the given point has valid coordinates.
183
+ #
184
+ # @param pt [RGeo::Feature::Point]
185
+ #
186
+ # @return [String] invalid_reason
187
+ def check_invalid_coordinate(pt)
188
+ x = pt.x
189
+ y = pt.y
190
+ return if x.finite? && y.finite? && x.real? && y.real?
191
+
192
+ Error::INVALID_COORDINATE
193
+ end
194
+
195
+ # Checks that the edges in the polygon form a consistent area.
196
+ #
197
+ # Specifically, checks that there are intersections no between the
198
+ # holes and the shell.
199
+ #
200
+ # Also checks that there are no duplicate rings.
201
+ #
202
+ # @param poly [RGeo::Feature::Polygon]
203
+ #
204
+ # @return [String] invalid_reason
205
+ def check_consistent_area(poly)
206
+ # Holes don't cross exterior check.
207
+ exterior = poly.exterior_ring
208
+ poly.interior_rings.each do |ring|
209
+ return Error::SELF_INTERSECTION if ring.crosses?(exterior)
210
+ end
211
+
212
+ # check interiors do not cross
213
+ poly.interior_rings.combination(2).each do |ring1, ring2|
214
+ return Error::SELF_INTERSECTION if ring1.crosses?(ring2)
215
+ end
216
+
217
+ # Duplicate rings check
218
+ rings = [exterior] + poly.interior_rings
219
+ return Error::SELF_INTERSECTION if rings.uniq.size != rings.size
220
+
221
+ nil
222
+ end
223
+
224
+ # Checks that the ring does not self-intersect. This is just a simplicity
225
+ # check on the ring.
226
+ #
227
+ # @param ring [RGeo::Feature::LinearRing]
228
+ #
229
+ # @return [String] invalid_reason
230
+ def check_no_self_intersections(ring)
231
+ return Error::SELF_INTERSECTION unless ring.simple?
232
+ end
233
+
234
+ # Check that rings do not self intersect in a polygon
235
+ #
236
+ # @param poly [RGeo::Feature::Polygon]
237
+ #
238
+ # @return [String] invalid_reason
239
+ def check_no_self_intersecting_rings(poly)
240
+ exterior = poly.exterior_ring
241
+
242
+ check = check_no_self_intersections(exterior)
243
+ return check unless check.nil?
244
+
245
+ poly.interior_rings.each do |ring|
246
+ check = check_no_self_intersections(ring)
247
+ return check unless check.nil?
248
+ end
249
+
250
+ nil
251
+ end
252
+
253
+ # Checks holes are contained inside the exterior of a polygon.
254
+ # Assuming check_consistent_area has already passed on the polygon,
255
+ # a simple point in polygon check can be done on one of the points
256
+ # in each hole to verify (since we know none of them intersect).
257
+ #
258
+ # @param poly [RGeo::Feature::Polygon]
259
+ #
260
+ # @return [String] invalid_reason
261
+ def check_holes_in_shell(poly)
262
+ # get hole-less shell as test polygon
263
+ shell = poly.exterior_ring
264
+ shell = shell.factory.polygon(shell)
265
+
266
+ poly.interior_rings.each do |interior|
267
+ test_pt = interior.start_point
268
+ unless shell.contains?(test_pt) || poly.exterior_ring.contains?(test_pt)
269
+ return Error::HOLE_OUTSIDE_SHELL
270
+ end
271
+ end
272
+
273
+ nil
274
+ end
275
+
276
+ # Checks that holes are not nested within each other.
277
+ #
278
+ # @param poly [RGeo::Feature::Polygon]
279
+ #
280
+ # @return [String] invalid_reason
281
+ def check_holes_not_nested(poly)
282
+ # convert holes from linear_rings to polygons
283
+ # Same logic that applies to check_holes_in_shell applies here
284
+ # since we've already passed the consistent area test, we just
285
+ # have to check if one point from each hole is contained in the other.
286
+ holes = poly.interior_rings
287
+ holes = holes.map { |v| v.factory.polygon(v) }
288
+ holes.combination(2).each do |p1, p2|
289
+ if p1.contains?(p2.exterior_ring.start_point) || p2.contains?(p1.exterior_ring.start_point)
290
+ return Error::NESTED_HOLES
291
+ end
292
+ end
293
+
294
+ nil
295
+ end
296
+
297
+ # Checks that the interior of the polygon is connected.
298
+ # A disconnected interior can be described by this polygon for example
299
+ # POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (5 0, 10 5, 5 10, 0 5, 5 0))
300
+ #
301
+ # Which is a square with a diamond inside of it.
302
+ #
303
+ # @param poly [RGeo::Feature::Polygon]
304
+ #
305
+ # @return [String] invalid_reason
306
+ def check_connected_interiors(poly)
307
+ # This is not proper and will flag valid geometries as invalid, but
308
+ # is an ok approximation.
309
+ # Idea is to check if a single hole has multiple points on the
310
+ # exterior ring.
311
+ poly.interior_rings.each do |ring|
312
+ touches = Set.new
313
+ ring.points.each do |pt|
314
+ touches.add(pt) if poly.exterior_ring.contains?(pt)
315
+ end
316
+
317
+ return Error::DISCONNECTED_INTERIOR if touches.size > 1
318
+ end
319
+
320
+ nil
321
+ end
322
+
323
+ # Checks that polygons do not intersect in a multipolygon.
324
+ #
325
+ # @param mp [RGeo::Feature::MultiPolygon]
326
+ #
327
+ # @return [String] invalid_reason
328
+ def check_consistent_area_mp(mp)
329
+ mp.geometries.combination(2) do |p1, p2|
330
+ if p1.exterior_ring.crosses?(p2.exterior_ring)
331
+ return Error::SELF_INTERSECTION
332
+ end
333
+ end
334
+ nil
335
+ end
336
+
337
+ # Checks that individual polygons within a multipolygon are not nested.
338
+ #
339
+ # @param mp [RGeo::Feature::MultiPolygon]
340
+ #
341
+ # @return [String] invalid_reason
342
+ def check_shells_not_nested(mp)
343
+ # Since we've passed the consistent area test, we can just check
344
+ # that one point lies in the other.
345
+ mp.geometries.combination(2) do |p1, p2|
346
+ if p1.contains?(p2.exterior_ring.start_point) || p2.contains?(p1.exterior_ring.start_point)
347
+ return Error::NESTED_SHELLS
348
+ end
349
+ end
350
+ nil
351
+ end
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RGeo
4
+ module ImplHelper
5
+ # This helper enforces valid geometry computation, avoiding results such
6
+ # as a 0 area for a bowtie shaped polygon. Implementations that are part
7
+ # of RGeo core should all include this.
8
+ #
9
+ # You can play around validity checks if needed:
10
+ #
11
+ # - {check_validity!} is the method that will raise if your geometry is
12
+ # not valid. Its message will be the same as {invalid_reason}.
13
+ # - {make_valid} is the method you can call to get a valid copy of the
14
+ # current geometry.
15
+ # - finally, you can bypass any checked method by prepending `unsafe_` to
16
+ # it. At your own risk.
17
+ module ValidityCheck
18
+ # Every method that should not be overriden by the validity check.
19
+ # Those methods are either accessors or very basic methods not related
20
+ # to validity checks, or are used to check validity, in which case the
21
+ # `true/false` gives a correct information, no need to raise).
22
+ UNCHECKED_METHODS = [
23
+ # Basic methods
24
+ :factory, :geometry_type, :as_text, :as_binary, :srid,
25
+ # Tests
26
+ :simple?, :closed?, :empty?,
27
+ # Accessors
28
+ :exterior_ring, :interior_rings, :[], :num_geometries, :num_interior_rings,
29
+ :geometry_n, :each, :points, :point_n, :start_point, :end_point, :x, :y, :z, :m,
30
+ # Trivial methods
31
+ :num_points,
32
+ # Comparison
33
+ :equals?, :rep_equals?, :eql?, :==, :'!='
34
+ ].freeze
35
+ private_constant :UNCHECKED_METHODS
36
+
37
+ # Since methods have their unsafe_ counter part, it means that the `+`
38
+ # method would lead to having an `unsafe_+` method that is not simply
39
+ # callable. Here's a simple fallback:
40
+ SYMBOL2NAME = {
41
+ :+ => "add",
42
+ :- => "remove",
43
+ :* => "multiply"
44
+ }.tap { |h| h.default_proc = ->(_, key) { key.to_s } }.freeze
45
+ private_constant :SYMBOL2NAME
46
+
47
+ class << self
48
+ # Note for contributors: this should be called after all methods
49
+ # are loaded for a given feature classe. No worries though, this
50
+ # is tested.
51
+ def override_classes # :nodoc:
52
+ # Using pop here to be thread safe.
53
+ while (klass = classes.pop)
54
+ override(klass)
55
+ end
56
+ end
57
+
58
+ def included(klass) # :nodoc:
59
+ classes << klass
60
+ end
61
+
62
+ private
63
+
64
+ def classes
65
+ @classes ||= []
66
+ end
67
+
68
+ def override(klass)
69
+ methods_to_check = feature_methods(klass)
70
+
71
+ klass.class_eval do
72
+ methods_to_check.each do |method_sym|
73
+ copy = "unsafe_#{SYMBOL2NAME[method_sym]}".to_sym
74
+ alias_method copy, method_sym
75
+ undef_method method_sym
76
+ define_method(method_sym) do |*args|
77
+ check_validity!
78
+ args.each do |arg|
79
+ arg.check_validity! if RGeo::Feature::Geometry.check_type(arg)
80
+ end
81
+ method(copy).call(*args)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def feature_methods(klass)
88
+ feature_defs = Set.new
89
+ klass
90
+ .ancestors
91
+ .select { |ancestor| ancestor <= RGeo::Feature::Geometry }
92
+ .each { |ancestor| feature_defs.merge(ancestor.instance_methods(false)) }
93
+ feature_defs & klass.instance_methods - UNCHECKED_METHODS
94
+ end
95
+ end
96
+
97
+ # Raises {invalid_reason} if the polygon is not valid, does nothing
98
+ # otherwise.
99
+ def check_validity!
100
+ # This method will use a cached invalid_reason for performance purposes.
101
+ # DO NOT MUTATE GEOMETRIES.
102
+ return unless invalid_reason_memo
103
+
104
+ raise Error::InvalidGeometry, invalid_reason_memo
105
+ end
106
+
107
+ # Tell why the geometry is not valid, `nil` means it is valid.
108
+ def invalid_reason
109
+ if defined?(super) == "super"
110
+ raise Error::RGeoError, "ValidityCheck MUST be loaded before " \
111
+ "definition of #{self.class}##{__method__}."
112
+ end
113
+
114
+ raise Error::UnsupportedOperation, "Method #{self.class}##{__method__} not defined."
115
+ end
116
+
117
+ # Try and make the geometry valid, this may change its shape.
118
+ # Returns a valid copy of the geometry.
119
+ def make_valid
120
+ if defined?(super) == "super"
121
+ raise Error::RGeoError, "ValidityCheck MUST be loaded before " \
122
+ "definition of #{self.class}##{__method__}."
123
+ end
124
+
125
+ raise Error::UnsupportedOperation, "Method #{self.class}##{__method__} not defined."
126
+ end
127
+
128
+ private
129
+
130
+ def invalid_reason_memo
131
+ # `defined?` is a bit faster than `instance_variable_defined?`.
132
+ return @invalid_reason_memo if defined?(@invalid_reason_memo)
133
+
134
+ @invalid_reason_memo = invalid_reason
135
+ end
136
+ end
137
+ end
138
+ end
@@ -7,3 +7,4 @@ require_relative "impl_helper/basic_geometry_collection_methods"
7
7
  require_relative "impl_helper/basic_point_methods"
8
8
  require_relative "impl_helper/basic_line_string_methods"
9
9
  require_relative "impl_helper/basic_polygon_methods"
10
+ require_relative "impl_helper/valid_op"
data/lib/rgeo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RGeo
4
- VERSION = "2.3.0"
4
+ VERSION = "3.0.0-rc.1"
5
5
  end
@@ -178,7 +178,7 @@ module RGeo
178
178
  emit_line_string_coords(obj)
179
179
  elsif type == Feature::Polygon
180
180
  exterior_ring = obj.exterior_ring
181
- if exterior_ring.is_empty?
181
+ if exterior_ring.empty?
182
182
  emit_integer(0)
183
183
  else
184
184
  emit_integer(1 + obj.num_interior_rings)
@@ -160,7 +160,7 @@ module RGeo
160
160
  end
161
161
 
162
162
  def generate_line_string(obj)
163
- if obj.is_empty?
163
+ if obj.empty?
164
164
  "EMPTY"
165
165
  else
166
166
  "#{@begin_bracket}#{obj.points.map { |p| generate_coords(p) }.join(', ')}#{@end_bracket}"
@@ -168,7 +168,7 @@ module RGeo
168
168
  end
169
169
 
170
170
  def generate_polygon(obj)
171
- if obj.is_empty?
171
+ if obj.empty?
172
172
  "EMPTY"
173
173
  else
174
174
  "#{@begin_bracket}#{([generate_line_string(obj.exterior_ring)] + obj.interior_rings.map { |r| generate_line_string(r) }).join(', ')}#{@end_bracket}"
@@ -176,7 +176,7 @@ module RGeo
176
176
  end
177
177
 
178
178
  def generate_geometry_collection(obj)
179
- if obj.is_empty?
179
+ if obj.empty?
180
180
  "EMPTY"
181
181
  else
182
182
  "#{@begin_bracket}#{obj.map { |f| generate_feature(f) }.join(', ')}#{@end_bracket}"
@@ -184,7 +184,7 @@ module RGeo
184
184
  end
185
185
 
186
186
  def generate_multi_point(obj)
187
- if obj.is_empty?
187
+ if obj.empty?
188
188
  "EMPTY"
189
189
  else
190
190
  "#{@begin_bracket}#{obj.map { |f| generate_point(f) }.join(', ')}#{@end_bracket}"
@@ -192,7 +192,7 @@ module RGeo
192
192
  end
193
193
 
194
194
  def generate_multi_line_string(obj)
195
- if obj.is_empty?
195
+ if obj.empty?
196
196
  "EMPTY"
197
197
  else
198
198
  "#{@begin_bracket}#{obj.map { |f| generate_line_string(f) }.join(', ')}#{@end_bracket}"
@@ -200,7 +200,7 @@ module RGeo
200
200
  end
201
201
 
202
202
  def generate_multi_polygon(obj)
203
- if obj.is_empty?
203
+ if obj.empty?
204
204
  "EMPTY"
205
205
  else
206
206
  "#{@begin_bracket}#{obj.map { |f| generate_polygon(f) }.join(', ')}#{@end_bracket}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgeo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.0.0.pre.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-04-16 00:00:00.000000000 Z
12
+ date: 2022-03-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi-geos
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.2'
20
+ version: '2.2'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.2'
27
+ version: '2.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: minitest
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: 1.8.1
84
+ - !ruby/object:Gem::Dependency
85
+ name: yard
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.9'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.9'
84
98
  description: RGeo is a geospatial data library for Ruby. It provides an implementation
85
99
  of the Open Geospatial Consortium's Simple Features Specification, used by most
86
100
  standard spatial/geographic data storage systems such as PostGIS. A number of add-on
@@ -90,11 +104,13 @@ email:
90
104
  - dazuma@gmail.com
91
105
  - parhameter@gmail.com
92
106
  - kfdoggett@gmail.com
107
+ - buonomo.ulysse@gmail.com
93
108
  executables: []
94
109
  extensions:
95
110
  - ext/geos_c_impl/extconf.rb
96
111
  extra_rdoc_files: []
97
112
  files:
113
+ - ".yardopts"
98
114
  - LICENSE.txt
99
115
  - README.md
100
116
  - ext/geos_c_impl/analysis.c
@@ -110,6 +126,8 @@ files:
110
126
  - ext/geos_c_impl/geometry.h
111
127
  - ext/geos_c_impl/geometry_collection.c
112
128
  - ext/geos_c_impl/geometry_collection.h
129
+ - ext/geos_c_impl/globals.c
130
+ - ext/geos_c_impl/globals.h
113
131
  - ext/geos_c_impl/line_string.c
114
132
  - ext/geos_c_impl/line_string.h
115
133
  - ext/geos_c_impl/main.c
@@ -127,6 +145,9 @@ files:
127
145
  - lib/rgeo/cartesian/feature_classes.rb
128
146
  - lib/rgeo/cartesian/feature_methods.rb
129
147
  - lib/rgeo/cartesian/interface.rb
148
+ - lib/rgeo/cartesian/planar_graph.rb
149
+ - lib/rgeo/cartesian/sweepline_intersector.rb
150
+ - lib/rgeo/cartesian/valid_op.rb
130
151
  - lib/rgeo/coord_sys.rb
131
152
  - lib/rgeo/coord_sys/cs/entities.rb
132
153
  - lib/rgeo/coord_sys/cs/factories.rb
@@ -183,6 +204,8 @@ files:
183
204
  - lib/rgeo/impl_helper/basic_polygon_methods.rb
184
205
  - lib/rgeo/impl_helper/math.rb
185
206
  - lib/rgeo/impl_helper/utils.rb
207
+ - lib/rgeo/impl_helper/valid_op.rb
208
+ - lib/rgeo/impl_helper/validity_check.rb
186
209
  - lib/rgeo/version.rb
187
210
  - lib/rgeo/wkrep.rb
188
211
  - lib/rgeo/wkrep/wkb_generator.rb
@@ -204,11 +227,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
227
  version: 2.5.0
205
228
  required_rubygems_version: !ruby/object:Gem::Requirement
206
229
  requirements:
207
- - - ">="
230
+ - - ">"
208
231
  - !ruby/object:Gem::Version
209
- version: '0'
232
+ version: 1.3.1
210
233
  requirements: []
211
- rubygems_version: 3.2.3
234
+ rubygems_version: 3.1.4
212
235
  signing_key:
213
236
  specification_version: 4
214
237
  summary: RGeo is a geospatial data library for Ruby.