rgeo 2.3.1 → 3.0.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/README.md +23 -14
  4. data/ext/geos_c_impl/analysis.c +30 -25
  5. data/ext/geos_c_impl/analysis.h +8 -7
  6. data/ext/geos_c_impl/coordinates.c +27 -21
  7. data/ext/geos_c_impl/coordinates.h +5 -2
  8. data/ext/geos_c_impl/errors.c +19 -10
  9. data/ext/geos_c_impl/errors.h +11 -4
  10. data/ext/geos_c_impl/extconf.rb +42 -28
  11. data/ext/geos_c_impl/factory.c +540 -451
  12. data/ext/geos_c_impl/factory.h +105 -95
  13. data/ext/geos_c_impl/geometry.c +593 -387
  14. data/ext/geos_c_impl/geometry.h +10 -5
  15. data/ext/geos_c_impl/geometry_collection.c +306 -339
  16. data/ext/geos_c_impl/geometry_collection.h +6 -20
  17. data/ext/geos_c_impl/globals.c +169 -0
  18. data/ext/geos_c_impl/globals.h +46 -0
  19. data/ext/geos_c_impl/line_string.c +271 -231
  20. data/ext/geos_c_impl/line_string.h +5 -8
  21. data/ext/geos_c_impl/main.c +16 -16
  22. data/ext/geos_c_impl/point.c +65 -67
  23. data/ext/geos_c_impl/point.h +4 -7
  24. data/ext/geos_c_impl/polygon.c +137 -135
  25. data/ext/geos_c_impl/polygon.h +11 -11
  26. data/ext/geos_c_impl/preface.h +16 -10
  27. data/ext/geos_c_impl/ruby_more.c +67 -0
  28. data/ext/geos_c_impl/ruby_more.h +25 -0
  29. data/lib/rgeo/cartesian/analysis.rb +5 -3
  30. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  31. data/lib/rgeo/cartesian/calculations.rb +64 -33
  32. data/lib/rgeo/cartesian/factory.rb +57 -102
  33. data/lib/rgeo/cartesian/feature_classes.rb +68 -46
  34. data/lib/rgeo/cartesian/feature_methods.rb +67 -25
  35. data/lib/rgeo/cartesian/interface.rb +6 -41
  36. data/lib/rgeo/cartesian/planar_graph.rb +373 -0
  37. data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
  38. data/lib/rgeo/cartesian/valid_op.rb +69 -0
  39. data/lib/rgeo/cartesian.rb +3 -0
  40. data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
  41. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  42. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
  43. data/lib/rgeo/coord_sys.rb +1 -20
  44. data/lib/rgeo/error.rb +15 -0
  45. data/lib/rgeo/feature/curve.rb +0 -11
  46. data/lib/rgeo/feature/factory.rb +26 -36
  47. data/lib/rgeo/feature/factory_generator.rb +6 -14
  48. data/lib/rgeo/feature/geometry.rb +146 -66
  49. data/lib/rgeo/feature/geometry_collection.rb +16 -9
  50. data/lib/rgeo/feature/line_string.rb +4 -5
  51. data/lib/rgeo/feature/linear_ring.rb +0 -1
  52. data/lib/rgeo/feature/multi_curve.rb +0 -6
  53. data/lib/rgeo/feature/multi_surface.rb +3 -4
  54. data/lib/rgeo/feature/point.rb +4 -5
  55. data/lib/rgeo/feature/polygon.rb +1 -2
  56. data/lib/rgeo/feature/surface.rb +3 -4
  57. data/lib/rgeo/feature/types.rb +69 -85
  58. data/lib/rgeo/geographic/factory.rb +98 -125
  59. data/lib/rgeo/geographic/interface.rb +69 -166
  60. data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
  61. data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
  62. data/lib/rgeo/geographic/projected_window.rb +36 -22
  63. data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
  64. data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
  65. data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
  66. data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
  67. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  68. data/lib/rgeo/geographic.rb +1 -1
  69. data/lib/rgeo/geos/capi_factory.rb +87 -158
  70. data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
  71. data/lib/rgeo/geos/ffi_factory.rb +105 -173
  72. data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
  73. data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
  74. data/lib/rgeo/geos/interface.rb +20 -59
  75. data/lib/rgeo/geos/utils.rb +5 -5
  76. data/lib/rgeo/geos/zm_factory.rb +53 -95
  77. data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
  78. data/lib/rgeo/geos.rb +8 -8
  79. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
  80. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  81. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
  82. data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
  83. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
  84. data/lib/rgeo/impl_helper/utils.rb +21 -0
  85. data/lib/rgeo/impl_helper/valid_op.rb +350 -0
  86. data/lib/rgeo/impl_helper/validity_check.rb +139 -0
  87. data/lib/rgeo/impl_helper.rb +1 -0
  88. data/lib/rgeo/version.rb +1 -1
  89. data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
  90. data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
  91. data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
  92. data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
  93. data/lib/rgeo.rb +1 -3
  94. metadata +50 -13
  95. data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
  96. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
  97. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
@@ -6,60 +6,84 @@
6
6
  #
7
7
  # -----------------------------------------------------------------------------
8
8
 
9
+ require_relative "../impl_helper/validity_check"
10
+
9
11
  module RGeo
10
12
  module Geos
11
- class FFIGeometryImpl # :nodoc:
13
+ class FFIGeometryImpl
14
+ include Feature::Geometry
15
+ include ImplHelper::ValidityCheck
12
16
  include FFIGeometryMethods
13
17
  end
14
18
 
15
- class FFIPointImpl # :nodoc:
19
+ class FFIPointImpl
20
+ include Feature::Point
21
+ include ImplHelper::ValidityCheck
16
22
  include FFIGeometryMethods
17
23
  include FFIPointMethods
18
24
  end
19
25
 
20
- class FFILineStringImpl # :nodoc:
26
+ class FFILineStringImpl
27
+ include Feature::LineString
28
+ include ImplHelper::ValidityCheck
21
29
  include FFIGeometryMethods
22
30
  include FFILineStringMethods
23
31
  end
24
32
 
25
- class FFILinearRingImpl # :nodoc:
33
+ class FFILinearRingImpl
34
+ include Feature::LinearRing
35
+ include ImplHelper::ValidityCheck
26
36
  include FFIGeometryMethods
27
37
  include FFILineStringMethods
28
38
  include FFILinearRingMethods
29
39
  end
30
40
 
31
- class FFILineImpl # :nodoc:
41
+ class FFILineImpl
42
+ include Feature::Line
43
+ include ImplHelper::ValidityCheck
32
44
  include FFIGeometryMethods
33
45
  include FFILineStringMethods
34
46
  include FFILineMethods
35
47
  end
36
48
 
37
- class FFIPolygonImpl # :nodoc:
49
+ class FFIPolygonImpl
50
+ include Feature::Polygon
51
+ include ImplHelper::ValidityCheck
38
52
  include FFIGeometryMethods
39
53
  include FFIPolygonMethods
40
54
  end
41
55
 
42
- class FFIGeometryCollectionImpl # :nodoc:
56
+ class FFIGeometryCollectionImpl
57
+ include Feature::GeometryCollection
58
+ include ImplHelper::ValidityCheck
43
59
  include FFIGeometryMethods
44
60
  include FFIGeometryCollectionMethods
45
61
  end
46
62
 
47
- class FFIMultiPointImpl # :nodoc:
63
+ class FFIMultiPointImpl
64
+ include Feature::MultiPoint
65
+ include ImplHelper::ValidityCheck
48
66
  include FFIGeometryMethods
49
67
  include FFIGeometryCollectionMethods
50
68
  include FFIMultiPointMethods
51
69
  end
52
70
 
53
- class FFIMultiLineStringImpl # :nodoc:
71
+ class FFIMultiLineStringImpl
72
+ include Feature::MultiLineString
73
+ include ImplHelper::ValidityCheck
54
74
  include FFIGeometryMethods
55
75
  include FFIGeometryCollectionMethods
56
76
  include FFIMultiLineStringMethods
57
77
  end
58
78
 
59
- class FFIMultiPolygonImpl # :nodoc:
79
+ class FFIMultiPolygonImpl
80
+ include Feature::MultiPolygon
81
+ include ImplHelper::ValidityCheck
60
82
  include FFIGeometryMethods
61
83
  include FFIGeometryCollectionMethods
62
84
  include FFIMultiPolygonMethods
63
85
  end
86
+
87
+ ImplHelper::ValidityCheck.override_classes
64
88
  end
65
89
  end
@@ -6,11 +6,15 @@
6
6
  #
7
7
  # -----------------------------------------------------------------------------
8
8
 
9
+ require "ffi-geos"
10
+
9
11
  module RGeo
10
12
  module Geos
11
13
  module FFIGeometryMethods # :nodoc:
12
14
  include Feature::Instance
13
15
 
16
+ attr_reader :factory, :fg_geom, :_klasses
17
+
14
18
  def initialize(factory, fg_geom, klasses)
15
19
  @factory = factory
16
20
  @fg_geom = fg_geom
@@ -54,11 +58,6 @@ module RGeo
54
58
  @_klasses = nil
55
59
  end
56
60
 
57
- attr_reader :factory
58
- attr_reader :fg_geom
59
-
60
- attr_reader :_klasses # :nodoc:
61
-
62
61
  def initialize_copy(orig)
63
62
  @factory = orig.factory
64
63
  @fg_geom = orig.fg_geom.clone
@@ -75,6 +74,14 @@ module RGeo
75
74
  Utils.ffi_compute_dimension(@fg_geom)
76
75
  end
77
76
 
77
+ def coordinate_dimension
78
+ factory.coordinate_dimension
79
+ end
80
+
81
+ def spatial_dimension
82
+ factory.spatial_dimension
83
+ end
84
+
78
85
  def geometry_type
79
86
  Feature::Geometry
80
87
  end
@@ -84,9 +91,7 @@ module RGeo
84
91
  end
85
92
 
86
93
  def prepare!
87
- if @_fg_prep.is_a?(Integer)
88
- @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom)
89
- end
94
+ @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom) if @_fg_prep.is_a?(Integer)
90
95
  self
91
96
  end
92
97
 
@@ -95,11 +100,9 @@ module RGeo
95
100
  end
96
101
 
97
102
  def boundary
98
- if self.class == FFIGeometryCollectionImpl
99
- nil
100
- else
101
- @factory.wrap_fg_geom(@fg_geom.boundary, nil)
102
- end
103
+ @factory.wrap_fg_geom(@fg_geom.boundary, nil)
104
+ rescue ::Geos::GEOSException
105
+ raise Error::InvalidGeometry, "Operation not supported by GeometryCollection"
103
106
  end
104
107
 
105
108
  def as_text
@@ -117,28 +120,45 @@ module RGeo
117
120
  @fg_geom.empty?
118
121
  end
119
122
 
120
- def is_empty?
121
- warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
122
- empty?
123
- end
124
-
125
123
  def simple?
126
124
  @fg_geom.simple?
127
125
  end
128
126
 
129
- def is_simple?
130
- warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
131
- simple?
127
+ def is_3d?
128
+ factory.property(:has_z_coordinate)
129
+ end
130
+
131
+ def measured?
132
+ factory.property(:has_m_coordinate)
133
+ end
134
+
135
+ def valid?
136
+ @fg_geom.valid?
137
+ end
138
+
139
+ def invalid_reason
140
+ # valid_detail gives solely the reason, or nil if valid, which is
141
+ # what we want.
142
+ fg_geom.valid_detail&.dig(:detail)&.force_encoding(Encoding::UTF_8)
143
+ end
144
+
145
+ # (see RGeo::ImplHelper::ValidityCheck#make_valid)
146
+ # Only available since GEOS 3.8+
147
+ if ::Geos::FFIGeos.respond_to?(:GEOSMakeValid_r)
148
+ def make_valid
149
+ @factory.wrap_fg_geom(@fg_geom.make_valid, nil)
150
+ rescue ::Geos::GEOSException
151
+ raise Error::UnsupportedOperation
152
+ end
132
153
  end
133
154
 
134
155
  def equals?(rhs)
135
156
  return false unless rhs.is_a?(RGeo::Feature::Instance)
136
157
  fg = factory.convert_to_fg_geometry(rhs)
137
- if !fg
138
- false
158
+
139
159
  # GEOS has a bug where empty geometries are not spatially equal
140
160
  # to each other. Work around this case first.
141
- elsif fg.empty? && @fg_geom.empty?
161
+ if fg.empty? && @fg_geom.empty?
142
162
  true
143
163
  else
144
164
  @fg_geom.eql?(fg)
@@ -148,83 +168,54 @@ module RGeo
148
168
 
149
169
  def disjoint?(rhs)
150
170
  fg = factory.convert_to_fg_geometry(rhs)
151
- if fg
152
- prep = request_prepared if Utils.ffi_supports_prepared_level_2
153
- prep ? prep.disjoint?(fg) : @fg_geom.disjoint?(fg)
154
- else
155
- false
156
- end
171
+ prep = request_prepared if Utils.ffi_supports_prepared_level2
172
+ prep ? prep.disjoint?(fg) : @fg_geom.disjoint?(fg)
157
173
  end
158
174
 
159
175
  def intersects?(rhs)
160
176
  fg = factory.convert_to_fg_geometry(rhs)
161
- if fg
162
- prep = request_prepared if Utils.ffi_supports_prepared_level_1
163
- prep ? prep.intersects?(fg) : @fg_geom.intersects?(fg)
164
- else
165
- false
166
- end
177
+ prep = request_prepared if Utils.ffi_supports_prepared_level1
178
+ prep ? prep.intersects?(fg) : @fg_geom.intersects?(fg)
167
179
  end
168
180
 
169
181
  def touches?(rhs)
170
182
  fg = factory.convert_to_fg_geometry(rhs)
171
- if fg
172
- prep = request_prepared if Utils.ffi_supports_prepared_level_2
173
- prep ? prep.touches?(fg) : @fg_geom.touches?(fg)
174
- else
175
- false
176
- end
183
+ prep = request_prepared if Utils.ffi_supports_prepared_level2
184
+ prep ? prep.touches?(fg) : @fg_geom.touches?(fg)
177
185
  end
178
186
 
179
187
  def crosses?(rhs)
180
188
  fg = factory.convert_to_fg_geometry(rhs)
181
- if fg
182
- prep = request_prepared if Utils.ffi_supports_prepared_level_2
183
- prep ? prep.crosses?(fg) : @fg_geom.crosses?(fg)
184
- else
185
- false
186
- end
189
+ prep = request_prepared if Utils.ffi_supports_prepared_level2
190
+ prep ? prep.crosses?(fg) : @fg_geom.crosses?(fg)
187
191
  end
188
192
 
189
193
  def within?(rhs)
190
194
  fg = factory.convert_to_fg_geometry(rhs)
191
- if fg
192
- prep = request_prepared if Utils.ffi_supports_prepared_level_2
193
- prep ? prep.within?(fg) : @fg_geom.within?(fg)
194
- else
195
- false
196
- end
195
+ prep = request_prepared if Utils.ffi_supports_prepared_level2
196
+ prep ? prep.within?(fg) : @fg_geom.within?(fg)
197
197
  end
198
198
 
199
199
  def contains?(rhs)
200
200
  fg = factory.convert_to_fg_geometry(rhs)
201
- if fg
202
- prep = request_prepared if Utils.ffi_supports_prepared_level_1
203
- prep ? prep.contains?(fg) : @fg_geom.contains?(fg)
204
- else
205
- false
206
- end
201
+ prep = request_prepared if Utils.ffi_supports_prepared_level1
202
+ prep ? prep.contains?(fg) : @fg_geom.contains?(fg)
207
203
  end
208
204
 
209
205
  def overlaps?(rhs)
210
206
  fg = factory.convert_to_fg_geometry(rhs)
211
- if fg
212
- prep = request_prepared if Utils.ffi_supports_prepared_level_2
213
- prep ? prep.overlaps?(fg) : @fg_geom.overlaps?(fg)
214
- else
215
- false
216
- end
207
+ prep = request_prepared if Utils.ffi_supports_prepared_level2
208
+ prep ? prep.overlaps?(fg) : @fg_geom.overlaps?(fg)
217
209
  end
218
210
 
219
211
  def relate?(rhs, pattern)
220
212
  fg = factory.convert_to_fg_geometry(rhs)
221
- fg ? @fg_geom.relate_pattern(fg, pattern) : nil
213
+ @fg_geom.relate_pattern(fg, pattern)
222
214
  end
223
- alias relate relate? # DEPRECATED
224
215
 
225
216
  def distance(rhs)
226
217
  fg = factory.convert_to_fg_geometry(rhs)
227
- fg ? @fg_geom.distance(fg) : nil
218
+ @fg_geom.distance(fg)
228
219
  end
229
220
 
230
221
  def buffer(distance)
@@ -237,14 +228,14 @@ module RGeo
237
228
 
238
229
  def intersection(rhs)
239
230
  fg = factory.convert_to_fg_geometry(rhs)
240
- fg ? @factory.wrap_fg_geom(@fg_geom.intersection(fg), nil) : nil
231
+ @factory.wrap_fg_geom(@fg_geom.intersection(fg), nil)
241
232
  end
242
233
 
243
234
  alias * intersection
244
235
 
245
236
  def union(rhs)
246
237
  fg = factory.convert_to_fg_geometry(rhs)
247
- fg ? @factory.wrap_fg_geom(@fg_geom.union(fg), nil) : nil
238
+ @factory.wrap_fg_geom(@fg_geom.union(fg), nil)
248
239
  end
249
240
 
250
241
  alias + union
@@ -256,18 +247,18 @@ module RGeo
256
247
 
257
248
  def difference(rhs)
258
249
  fg = factory.convert_to_fg_geometry(rhs)
259
- fg ? @factory.wrap_fg_geom(@fg_geom.difference(fg), nil) : nil
250
+ @factory.wrap_fg_geom(@fg_geom.difference(fg), nil)
260
251
  end
261
252
 
262
253
  alias - difference
263
254
 
264
255
  def sym_difference(rhs)
265
256
  fg = factory.convert_to_fg_geometry(rhs)
266
- fg ? @factory.wrap_fg_geom(@fg_geom.sym_difference(fg), nil) : nil
257
+ @factory.wrap_fg_geom(@fg_geom.sym_difference(fg), nil)
267
258
  end
268
259
 
269
- def eql?(rhs)
270
- rep_equals?(rhs)
260
+ def eql?(other)
261
+ rep_equals?(other)
271
262
  end
272
263
 
273
264
  def detach_fg_geom
@@ -319,7 +310,7 @@ module RGeo
319
310
  end
320
311
 
321
312
  def rep_equals?(rhs)
322
- rhs.class == self.class && rhs.factory.eql?(@factory) &&
313
+ rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) &&
323
314
  Utils.ffi_coord_seqs_equal?(rhs.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
324
315
  end
325
316
 
@@ -348,14 +339,15 @@ module RGeo
348
339
  @fg_geom.num_points
349
340
  end
350
341
 
351
- def point_n(n)
352
- if n >= 0 && n < @fg_geom.num_points
353
- coord_seq = @fg_geom.coord_seq
354
- x = coord_seq.get_x(n)
355
- y = coord_seq.get_y(n)
356
- extra = @factory._has_3d ? [coord_seq.get_z(n)] : []
357
- @factory.point(x, y, *extra)
358
- end
342
+ def point_n(idx)
343
+ return unless idx >= 0 && idx < @fg_geom.num_points
344
+
345
+ coord_seq = @fg_geom.coord_seq
346
+ x = coord_seq.get_x(idx)
347
+ y = coord_seq.get_y(idx)
348
+ extra = @factory._has_3d ? [coord_seq.get_z(idx)] : []
349
+
350
+ @factory.point(x, y, *extra)
359
351
  end
360
352
 
361
353
  def start_point
@@ -381,22 +373,12 @@ module RGeo
381
373
  @fg_geom.closed?
382
374
  end
383
375
 
384
- def is_closed?
385
- warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
386
- closed?
387
- end
388
-
389
376
  def ring?
390
377
  @fg_geom.ring?
391
378
  end
392
379
 
393
- def is_ring?
394
- warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
395
- ring?
396
- end
397
-
398
380
  def rep_equals?(rhs)
399
- rhs.class == self.class && rhs.factory.eql?(@factory) &&
381
+ rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) &&
400
382
  Utils.ffi_coord_seqs_equal?(rhs.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
401
383
  end
402
384
 
@@ -450,10 +432,10 @@ module RGeo
450
432
  @fg_geom.num_interior_rings
451
433
  end
452
434
 
453
- def interior_ring_n(n)
454
- if n >= 0 && n < @fg_geom.num_interior_rings
455
- @factory.wrap_fg_geom(@fg_geom.interior_ring_n(n), FFILinearRingImpl)
456
- end
435
+ def interior_ring_n(idx)
436
+ return unless idx >= 0 && idx < @fg_geom.num_interior_rings
437
+
438
+ @factory.wrap_fg_geom(@fg_geom.interior_ring_n(idx), FFILinearRingImpl)
457
439
  end
458
440
 
459
441
  def interior_rings
@@ -463,7 +445,7 @@ module RGeo
463
445
  end
464
446
 
465
447
  def rep_equals?(rhs)
466
- if rhs.class == self.class && rhs.factory.eql?(@factory) &&
448
+ if rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) &&
467
449
  rhs.exterior_ring.rep_equals?(exterior_ring)
468
450
  sn = @fg_geom.num_interior_rings
469
451
  rn = rhs.num_interior_rings
@@ -479,8 +461,10 @@ module RGeo
479
461
 
480
462
  def hash
481
463
  @hash ||= begin
482
- hash = Utils.ffi_coord_seq_hash(@fg_geom.exterior_ring.coord_seq,
483
- [@factory, geometry_type].hash)
464
+ hash = Utils.ffi_coord_seq_hash(
465
+ @fg_geom.exterior_ring.coord_seq,
466
+ [@factory, geometry_type].hash
467
+ )
484
468
  @fg_geom.interior_rings.inject(hash) do |h, r|
485
469
  Utils.ffi_coord_seq_hash(r.coord_seq, h)
486
470
  end
@@ -498,7 +482,7 @@ module RGeo
498
482
  end
499
483
 
500
484
  def rep_equals?(rhs)
501
- if rhs.class == self.class && rhs.factory.eql?(@factory)
485
+ if rhs.instance_of?(self.class) && rhs.factory.eql?(@factory)
502
486
  size = @fg_geom.num_geometries
503
487
  if size == rhs.num_geometries
504
488
  size.times do |n|
@@ -515,35 +499,34 @@ module RGeo
515
499
  end
516
500
  alias size num_geometries
517
501
 
518
- def geometry_n(n)
519
- if n >= 0 && n < @fg_geom.num_geometries
520
- @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n),
521
- @_klasses ? @_klasses[n] : nil)
522
- end
502
+ def geometry_n(idx)
503
+ return unless idx >= 0 && idx < @fg_geom.num_geometries
504
+
505
+ @factory.wrap_fg_geom(
506
+ @fg_geom.get_geometry_n(idx),
507
+ @_klasses ? @_klasses[idx] : nil
508
+ )
523
509
  end
524
510
 
525
- def [](n)
526
- n += @fg_geom.num_geometries if n < 0
527
- if n >= 0 && n < @fg_geom.num_geometries
528
- @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n),
529
- @_klasses ? @_klasses[n] : nil)
530
- end
511
+ def [](idx)
512
+ idx += @fg_geom.num_geometries if idx < 0
513
+
514
+ return unless idx >= 0 && idx < @fg_geom.num_geometries
515
+
516
+ @factory.wrap_fg_geom(
517
+ @fg_geom.get_geometry_n(idx),
518
+ @_klasses ? @_klasses[idx] : nil
519
+ )
531
520
  end
532
521
 
533
522
  def hash
534
- @hash ||= begin
535
- hash = [@factory, geometry_type].hash
536
- (0...num_geometries).inject(hash) do |h, i|
537
- (1_664_525 * h + geometry_n(i).hash).hash
538
- end
539
- end
523
+ @hash ||= [@factory, geometry_type, *(0...num_geometries).map { |i| geometry_n(i) }].hash
540
524
  end
541
525
 
542
526
  def each
543
527
  if block_given?
544
528
  @fg_geom.num_geometries.times do |n|
545
- yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n),
546
- @_klasses ? @_klasses[n] : nil)
529
+ yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n), @_klasses ? @_klasses[n] : nil)
547
530
  end
548
531
  self
549
532
  else
@@ -581,11 +564,6 @@ module RGeo
581
564
  true
582
565
  end
583
566
 
584
- def is_closed?
585
- warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
586
- closed?
587
- end
588
-
589
567
  def coordinates
590
568
  each.map(&:coordinates)
591
569
  end
@@ -38,11 +38,6 @@ module RGeo
38
38
  ZMGeometryMethods === object && CAPIGeometryMethods === object.z_geometry)
39
39
  end
40
40
 
41
- def is_capi_geos?(object)
42
- warn "The is_capi_geos? method is deprecated, please use the capi_geos? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
43
- capi_geos?(object)
44
- end
45
-
46
41
  # Returns true if the given feature is an FFI GEOS feature, or if
47
42
  # the given factory is an FFI GEOS factory.
48
43
 
@@ -53,11 +48,6 @@ module RGeo
53
48
  ZMGeometryMethods === object && FFIGeometryMethods === object.z_geometry)
54
49
  end
55
50
 
56
- def is_ffi_geos?(object)
57
- warn "The is_ffi_geos? method is deprecated, please use the ffi_geos? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
58
- ffi_geos?(object)
59
- end
60
-
61
51
  # Returns true if the given feature is a GEOS feature, or if the given
62
52
  # factory is a GEOS factory. Does not distinguish between CAPI and FFI.
63
53
 
@@ -67,23 +57,17 @@ module RGeo
67
57
  ZMFactory === object || ZMGeometryMethods === object
68
58
  end
69
59
 
70
- def is_geos?(object)
71
- warn "The is_geos? method is deprecated, please use the geos? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
72
- geos?(object)
73
- end
74
-
75
60
  # Returns the GEOS library version as a string of the format "x.y.z".
76
61
  # Returns nil if GEOS is not available.
77
62
 
78
63
  def version
79
64
  unless defined?(@version)
80
- if RGeo::Geos::CAPI_SUPPORTED
81
- @version = RGeo::Geos::CAPIFactory._geos_version.freeze
82
- elsif RGeo::Geos::FFI_SUPPORTED
83
- @version = ::Geos::FFIGeos.GEOSversion.sub(/-CAPI-.*$/, "").freeze
84
- else
85
- @version = nil
86
- end
65
+ @version =
66
+ if RGeo::Geos::CAPI_SUPPORTED
67
+ RGeo::Geos::CAPIFactory._geos_version.freeze
68
+ elsif RGeo::Geos::FFI_SUPPORTED
69
+ ::Geos::FFIGeos.GEOSversion.sub(/-CAPI-.*$/, "").freeze
70
+ end
87
71
  end
88
72
  @version
89
73
  end
@@ -116,13 +100,6 @@ module RGeo
116
100
  # Specifies which native interface to use. Possible values are
117
101
  # <tt>:capi</tt> and <tt>:ffi</tt>. The default is the value
118
102
  # of the preferred_native_interface.
119
- # [<tt>:uses_lenient_multi_polygon_assertions</tt>]
120
- # If set to true, assertion checking on MultiPolygon is disabled.
121
- # This may speed up creation of MultiPolygon objects, at the
122
- # expense of not doing the proper checking for OGC MultiPolygon
123
- # compliance. See RGeo::Feature::MultiPolygon for details on
124
- # the MultiPolygon assertions. Default is false. Also called
125
- # <tt>:lenient_multi_polygon_assertions</tt>.
126
103
  # [<tt>:buffer_resolution</tt>]
127
104
  # The resolution of buffers around geometries created by this
128
105
  # factory. This controls the number of line segments used to
@@ -134,19 +111,14 @@ module RGeo
134
111
  # [<tt>:srid</tt>]
135
112
  # Set the SRID returned by geometries created by this factory.
136
113
  # Default is 0.
137
- # [<tt>:proj4</tt>]
138
- # The coordinate system in Proj4 format, either as a
139
- # CoordSys::Proj4 object or as a string or hash representing the
140
- # proj4 format. Optional.
141
114
  # [<tt>:coord_sys</tt>]
142
115
  # The coordinate system in OGC form, either as a subclass of
143
116
  # CoordSys::CS::CoordinateSystem, or as a string in WKT format.
144
- # Optional.
145
- # [<tt>:srs_database</tt>]
146
- # Optional. If provided, the object should respond to #get and
147
- # #clear_cache. If both this and an SRID are
148
- # provided, they are used to look up the proj4 and coord_sys
149
- # objects from a spatial reference system database.
117
+ # Optional. If not provided, but <tt>:srid</tt> is, a coord_sys
118
+ # will be created using the CS::CONFIG.default_coord_sys_class.
119
+ # [<tt>:coord_sys_class</tt>]
120
+ # The coordinate system implementation to use if you do not want to
121
+ # use the CS::CONFIG.default_coord_sys_class. Optional.
150
122
  # [<tt>:has_z_coordinate</tt>]
151
123
  # Support <tt>z_coordinate</tt>. Default is false.
152
124
  # [<tt>:has_m_coordinate</tt>]
@@ -190,28 +162,17 @@ module RGeo
190
162
  # never automatically generates a prepared geometry (unless you
191
163
  # generate one explicitly using the <tt>prepare!</tt> method).
192
164
  def factory(opts = {})
193
- if supported?
194
- native_interface = opts[:native_interface] || Geos.preferred_native_interface
195
- if opts[:has_z_coordinate] && opts[:has_m_coordinate]
196
- ZMFactory.new(opts)
197
- elsif native_interface == :ffi
198
- FFIFactory.new(opts)
199
- else
200
- CAPIFactory.create(opts)
201
- end
202
- end
203
- end
165
+ return unless supported?
204
166
 
205
- # Returns a Feature::FactoryGenerator that creates Geos-backed
206
- # factories. The given options are used as the default options.
207
- #
208
- # A common case for this is to provide the <tt>:srs_database</tt>
209
- # as a default. Then, the factory generator need only be passed
210
- # an SRID and it will automatically fetch the appropriate Proj4
211
- # and CoordSys objects.
167
+ native_interface = opts[:native_interface] || Geos.preferred_native_interface
212
168
 
213
- def factory_generator(defaults = {})
214
- proc { |c| factory(defaults.merge(c)) }
169
+ if opts[:has_z_coordinate] && opts[:has_m_coordinate]
170
+ ZMFactory.new(opts)
171
+ elsif native_interface == :ffi
172
+ FFIFactory.new(opts)
173
+ else
174
+ CAPIFactory.create(opts)
175
+ end
215
176
  end
216
177
  end
217
178
  end
@@ -49,17 +49,17 @@ module RGeo
49
49
  result
50
50
  end
51
51
 
52
- def ffi_coord_seq_hash(cs, hash = 0)
53
- (0...cs.length).inject(hash) do |h, i|
54
- [hash, cs.get_x(i), cs.get_y(i), cs.get_z(i)].hash
52
+ def ffi_coord_seq_hash(coord_seq, init_hash = 0)
53
+ (0...coord_seq.length).inject(init_hash) do |hash, i|
54
+ [hash, coord_seq.get_x(i), coord_seq.get_y(i), coord_seq.get_z(i)].hash
55
55
  end
56
56
  end
57
57
 
58
- def ffi_supports_prepared_level_1
58
+ def ffi_supports_prepared_level1
59
59
  FFI_SUPPORTED && ::Geos::FFIGeos.respond_to?(:GEOSPreparedContains_r)
60
60
  end
61
61
 
62
- def ffi_supports_prepared_level_2
62
+ def ffi_supports_prepared_level2
63
63
  FFI_SUPPORTED && ::Geos::FFIGeos.respond_to?(:GEOSPreparedDisjoint_r)
64
64
  end
65
65