rgeo 2.3.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
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