ffi-geos 1.2.1 → 1.2.2

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 (49) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +20 -0
  3. data/.travis.yml +7 -3
  4. data/Gemfile +1 -1
  5. data/Guardfile +4 -5
  6. data/ffi-geos.gemspec +1 -1
  7. data/lib/ffi-geos.rb +212 -196
  8. data/lib/ffi-geos/buffer_params.rb +9 -20
  9. data/lib/ffi-geos/coordinate_sequence.rb +342 -58
  10. data/lib/ffi-geos/geometry.rb +167 -178
  11. data/lib/ffi-geos/geometry_collection.rb +60 -12
  12. data/lib/ffi-geos/interrupt.rb +2 -4
  13. data/lib/ffi-geos/line_string.rb +146 -37
  14. data/lib/ffi-geos/linear_ring.rb +2 -3
  15. data/lib/ffi-geos/multi_line_string.rb +1 -2
  16. data/lib/ffi-geos/multi_point.rb +0 -1
  17. data/lib/ffi-geos/multi_polygon.rb +0 -1
  18. data/lib/ffi-geos/point.rb +69 -14
  19. data/lib/ffi-geos/polygon.rb +110 -21
  20. data/lib/ffi-geos/prepared_geometry.rb +11 -12
  21. data/lib/ffi-geos/strtree.rb +41 -52
  22. data/lib/ffi-geos/tools.rb +15 -18
  23. data/lib/ffi-geos/utils.rb +27 -44
  24. data/lib/ffi-geos/version.rb +1 -3
  25. data/lib/ffi-geos/wkb_reader.rb +4 -9
  26. data/lib/ffi-geos/wkb_writer.rb +14 -18
  27. data/lib/ffi-geos/wkt_reader.rb +2 -5
  28. data/lib/ffi-geos/wkt_writer.rb +17 -22
  29. data/test/.rubocop.yml +36 -0
  30. data/test/coordinate_sequence_tests.rb +263 -14
  31. data/test/geometry_collection_tests.rb +412 -1
  32. data/test/geometry_tests.rb +156 -86
  33. data/test/interrupt_tests.rb +2 -4
  34. data/test/line_string_tests.rb +212 -23
  35. data/test/linear_ring_tests.rb +1 -2
  36. data/test/misc_tests.rb +28 -29
  37. data/test/multi_line_string_tests.rb +0 -1
  38. data/test/point_tests.rb +158 -1
  39. data/test/polygon_tests.rb +284 -1
  40. data/test/prepared_geometry_tests.rb +1 -3
  41. data/test/strtree_tests.rb +9 -10
  42. data/test/test_helper.rb +49 -18
  43. data/test/tools_tests.rb +1 -3
  44. data/test/utils_tests.rb +22 -22
  45. data/test/wkb_reader_tests.rb +10 -9
  46. data/test/wkb_writer_tests.rb +5 -13
  47. data/test/wkt_reader_tests.rb +1 -2
  48. data/test/wkt_writer_tests.rb +9 -14
  49. metadata +6 -3
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Geos
@@ -17,7 +16,7 @@ module Geos
17
16
  # WktReader and the various Geos.create_* methods.
18
17
  def initialize(ptr, options = {})
19
18
  options = {
20
- :auto_free => true
19
+ auto_free: true
21
20
  }.merge(options)
22
21
 
23
22
  @ptr = FFI::AutoPointer.new(
@@ -45,52 +44,50 @@ module Geos
45
44
 
46
45
  # Returns the name of the Geometry type, i.e. "Point", "Polygon", etc.
47
46
  def geom_type
48
- FFIGeos.GEOSGeomType_r(Geos.current_handle_pointer, self.ptr)
47
+ FFIGeos.GEOSGeomType_r(Geos.current_handle_pointer, ptr)
49
48
  end
50
49
 
51
50
  # Returns one of the values from Geos::GeomTypes.
52
51
  def type_id
53
- FFIGeos.GEOSGeomTypeId_r(Geos.current_handle_pointer, self.ptr)
52
+ FFIGeos.GEOSGeomTypeId_r(Geos.current_handle_pointer, ptr)
54
53
  end
55
54
 
56
55
  def normalize!
57
- if FFIGeos.GEOSNormalize_r(Geos.current_handle_pointer, self.ptr) == -1
58
- raise Geos::Geometry::CouldntNormalizeError.new(self.class)
56
+ if FFIGeos.GEOSNormalize_r(Geos.current_handle_pointer, ptr) == -1
57
+ raise Geos::Geometry::CouldntNormalizeError, self.class
59
58
  end
60
59
 
61
60
  self
62
61
  end
63
- alias_method :normalize, :normalize!
62
+ alias normalize normalize!
64
63
 
65
64
  def srid
66
- FFIGeos.GEOSGetSRID_r(Geos.current_handle_pointer, self.ptr)
65
+ FFIGeos.GEOSGetSRID_r(Geos.current_handle_pointer, ptr)
67
66
  end
68
67
 
69
68
  def srid=(s)
70
- FFIGeos.GEOSSetSRID_r(Geos.current_handle_pointer, self.ptr, s)
69
+ FFIGeos.GEOSSetSRID_r(Geos.current_handle_pointer, ptr, s)
71
70
  end
72
71
 
73
72
  def dimensions
74
- FFIGeos.GEOSGeom_getDimensions_r(Geos.current_handle_pointer, self.ptr)
73
+ FFIGeos.GEOSGeom_getDimensions_r(Geos.current_handle_pointer, ptr)
75
74
  end
76
75
 
77
76
  def num_geometries
78
- FFIGeos.GEOSGetNumGeometries_r(Geos.current_handle_pointer, self.ptr)
77
+ FFIGeos.GEOSGetNumGeometries_r(Geos.current_handle_pointer, ptr)
79
78
  end
80
79
 
81
80
  def num_coordinates
82
- FFIGeos.GEOSGetNumCoordinates_r(Geos.current_handle_pointer, self.ptr)
81
+ FFIGeos.GEOSGetNumCoordinates_r(Geos.current_handle_pointer, ptr)
83
82
  end
84
83
 
85
84
  def coord_seq
86
- CoordinateSequence.new(FFIGeos.GEOSGeom_getCoordSeq_r(Geos.current_handle_pointer, self.ptr), false, self)
85
+ CoordinateSequence.new(FFIGeos.GEOSGeom_getCoordSeq_r(Geos.current_handle_pointer, ptr), false, self)
87
86
  end
88
87
 
89
88
  def intersection(geom)
90
89
  check_geometry(geom)
91
- cast_geometry_ptr(FFIGeos.GEOSIntersection_r(Geos.current_handle_pointer, self.ptr, geom.ptr), {
92
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
93
- })
90
+ cast_geometry_ptr(FFIGeos.GEOSIntersection_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
94
91
  end
95
92
 
96
93
  if FFIGeos.respond_to?(:GEOSBufferWithParams_r)
@@ -115,12 +112,12 @@ module Geos
115
112
  when Geos::BufferParams
116
113
  options
117
114
  when Numeric
118
- Geos::BufferParams.new(:quad_segs => options)
115
+ Geos::BufferParams.new(quad_segs: options)
119
116
  else
120
- raise ArgumentError.new("Expected Geos::BufferParams, a Hash or a Numeric")
117
+ raise ArgumentError, 'Expected Geos::BufferParams, a Hash or a Numeric'
121
118
  end
122
119
 
123
- cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle_pointer, self.ptr, params.ptr, width), :srid_copy => self.srid)
120
+ cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle_pointer, ptr, params.ptr, width), srid_copy: srid)
124
121
  end
125
122
  else
126
123
  def buffer(width, options = nil)
@@ -133,34 +130,30 @@ module Geos
133
130
  when Numeric
134
131
  options
135
132
  else
136
- raise ArgumentError.new("Expected Geos::BufferParams, a Hash or a Numeric")
133
+ raise ArgumentError, 'Expected Geos::BufferParams, a Hash or a Numeric'
137
134
  end
138
135
 
139
- cast_geometry_ptr(FFIGeos.GEOSBuffer_r(Geos.current_handle_pointer, self.ptr, width, quad_segs), :srid_copy => self.srid)
136
+ cast_geometry_ptr(FFIGeos.GEOSBuffer_r(Geos.current_handle_pointer, ptr, width, quad_segs), srid_copy: srid)
140
137
  end
141
138
  end
142
139
 
143
140
  def convex_hull
144
- cast_geometry_ptr(FFIGeos.GEOSConvexHull_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
141
+ cast_geometry_ptr(FFIGeos.GEOSConvexHull_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
145
142
  end
146
143
 
147
144
  def difference(geom)
148
145
  check_geometry(geom)
149
- cast_geometry_ptr(FFIGeos.GEOSDifference_r(Geos.current_handle_pointer, self.ptr, geom.ptr), {
150
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
151
- })
146
+ cast_geometry_ptr(FFIGeos.GEOSDifference_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
152
147
  end
153
148
 
154
149
  def sym_difference(geom)
155
150
  check_geometry(geom)
156
- cast_geometry_ptr(FFIGeos.GEOSSymDifference_r(Geos.current_handle_pointer, self.ptr, geom.ptr), {
157
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
158
- })
151
+ cast_geometry_ptr(FFIGeos.GEOSSymDifference_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
159
152
  end
160
- alias_method :symmetric_difference, :sym_difference
153
+ alias symmetric_difference sym_difference
161
154
 
162
155
  def boundary
163
- cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
156
+ cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
164
157
  end
165
158
 
166
159
  # Calling without a geom argument is equivalent to calling unary_union when
@@ -169,73 +162,67 @@ module Geos
169
162
  def union(geom = nil)
170
163
  if geom
171
164
  check_geometry(geom)
172
- cast_geometry_ptr(FFIGeos.GEOSUnion_r(Geos.current_handle_pointer, self.ptr, geom.ptr), {
173
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
174
- })
165
+ cast_geometry_ptr(FFIGeos.GEOSUnion_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
175
166
  else
176
- if self.respond_to?(:unary_union)
177
- self.unary_union
167
+ if respond_to?(:unary_union)
168
+ unary_union
178
169
  else
179
- self.union_cascaded
170
+ union_cascaded
180
171
  end
181
172
  end
182
173
  end
183
174
 
184
175
  def union_cascaded
185
- cast_geometry_ptr(FFIGeos.GEOSUnionCascaded_r(Geos.current_handle_pointer, self.ptr), {
186
- :srid_copy => self.srid
187
- })
176
+ cast_geometry_ptr(FFIGeos.GEOSUnionCascaded_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
188
177
  end
189
178
 
190
179
  if FFIGeos.respond_to?(:GEOSUnaryUnion_r)
191
180
  # Available in GEOS 3.3+
192
181
  def unary_union
193
- cast_geometry_ptr(FFIGeos.GEOSUnaryUnion_r(Geos.current_handle_pointer, self.ptr), {
194
- :srid_copy => self.srid
195
- })
182
+ cast_geometry_ptr(FFIGeos.GEOSUnaryUnion_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
196
183
  end
197
184
  end
198
185
 
199
186
  if FFIGeos.respond_to?(:GEOSNode_r)
200
187
  # Available in GEOS 3.3.4+
201
188
  def node
202
- cast_geometry_ptr(FFIGeos.GEOSNode_r(Geos.current_handle_pointer, self.ptr))
189
+ cast_geometry_ptr(FFIGeos.GEOSNode_r(Geos.current_handle_pointer, ptr))
203
190
  end
204
191
  end
205
192
 
206
193
  def point_on_surface
207
- cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
194
+ cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
208
195
  end
209
- alias_method :representative_point, :point_on_surface
196
+ alias representative_point point_on_surface
210
197
 
211
198
  if FFIGeos.respond_to?(:GEOSClipByRect_r)
212
199
  # Available in GEOS 3.5.0+.
213
200
  def clip_by_rect(xmin, ymin, xmax, ymax)
214
- cast_geometry_ptr(FFIGeos.GEOSClipByRect_r(Geos.current_handle_pointer, self.ptr, xmin, ymin, xmax, ymax))
201
+ cast_geometry_ptr(FFIGeos.GEOSClipByRect_r(Geos.current_handle_pointer, ptr, xmin, ymin, xmax, ymax))
215
202
  end
216
- alias_method :clip_by_rectangle, :clip_by_rect
203
+ alias clip_by_rectangle clip_by_rect
217
204
  end
218
205
 
219
206
  def centroid
220
- cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
207
+ cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
221
208
  end
222
- alias_method :center, :centroid
209
+ alias center centroid
223
210
 
224
211
  def envelope
225
- cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
212
+ cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
226
213
  end
227
214
 
228
215
  # Returns the Dimensionally Extended Nine-Intersection Model (DE-9IM)
229
216
  # matrix of the geometries as a String.
230
217
  def relate(geom)
231
218
  check_geometry(geom)
232
- FFIGeos.GEOSRelate_r(Geos.current_handle_pointer, self.ptr, geom.ptr)
219
+ FFIGeos.GEOSRelate_r(Geos.current_handle_pointer, ptr, geom.ptr)
233
220
  end
234
221
 
235
222
  # Checks the DE-9IM pattern against the geoms.
236
223
  def relate_pattern(geom, pattern)
237
224
  check_geometry(geom)
238
- bool_result(FFIGeos.GEOSRelatePattern_r(Geos.current_handle_pointer, self.ptr, geom.ptr, pattern))
225
+ bool_result(FFIGeos.GEOSRelatePattern_r(Geos.current_handle_pointer, ptr, geom.ptr, pattern))
239
226
  end
240
227
 
241
228
  if FFIGeos.respond_to?(:GEOSRelateBoundaryNodeRule_r)
@@ -243,60 +230,60 @@ module Geos
243
230
  def relate_boundary_node_rule(geom, bnr = :mod2)
244
231
  check_geometry(geom)
245
232
  check_enum_value(Geos::RelateBoundaryNodeRules, bnr)
246
- FFIGeos.GEOSRelateBoundaryNodeRule_r(Geos.current_handle_pointer, self.ptr, geom.ptr, bnr)
233
+ FFIGeos.GEOSRelateBoundaryNodeRule_r(Geos.current_handle_pointer, ptr, geom.ptr, bnr)
247
234
  end
248
235
  end
249
236
 
250
237
  def line_merge
251
- cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
238
+ cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
252
239
  end
253
240
 
254
241
  def simplify(tolerance)
255
- cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle_pointer, self.ptr, tolerance), :srid_copy => self.srid)
242
+ cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid)
256
243
  end
257
244
 
258
245
  def topology_preserve_simplify(tolerance)
259
- cast_geometry_ptr(FFIGeos.GEOSTopologyPreserveSimplify_r(Geos.current_handle_pointer, self.ptr, tolerance), :srid_copy => self.srid)
246
+ cast_geometry_ptr(FFIGeos.GEOSTopologyPreserveSimplify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid)
260
247
  end
261
248
 
262
249
  def extract_unique_points
263
- cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
250
+ cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
264
251
  end
265
- alias_method :unique_points, :extract_unique_points
252
+ alias unique_points extract_unique_points
266
253
 
267
254
  def disjoint?(geom)
268
255
  check_geometry(geom)
269
- bool_result(FFIGeos.GEOSDisjoint_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
256
+ bool_result(FFIGeos.GEOSDisjoint_r(Geos.current_handle_pointer, ptr, geom.ptr))
270
257
  end
271
258
 
272
259
  def touches?(geom)
273
260
  check_geometry(geom)
274
- bool_result(FFIGeos.GEOSTouches_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
261
+ bool_result(FFIGeos.GEOSTouches_r(Geos.current_handle_pointer, ptr, geom.ptr))
275
262
  end
276
263
 
277
264
  def intersects?(geom)
278
265
  check_geometry(geom)
279
- bool_result(FFIGeos.GEOSIntersects_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
266
+ bool_result(FFIGeos.GEOSIntersects_r(Geos.current_handle_pointer, ptr, geom.ptr))
280
267
  end
281
268
 
282
269
  def crosses?(geom)
283
270
  check_geometry(geom)
284
- bool_result(FFIGeos.GEOSCrosses_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
271
+ bool_result(FFIGeos.GEOSCrosses_r(Geos.current_handle_pointer, ptr, geom.ptr))
285
272
  end
286
273
 
287
274
  def within?(geom)
288
275
  check_geometry(geom)
289
- bool_result(FFIGeos.GEOSWithin_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
276
+ bool_result(FFIGeos.GEOSWithin_r(Geos.current_handle_pointer, ptr, geom.ptr))
290
277
  end
291
278
 
292
279
  def contains?(geom)
293
280
  check_geometry(geom)
294
- bool_result(FFIGeos.GEOSContains_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
281
+ bool_result(FFIGeos.GEOSContains_r(Geos.current_handle_pointer, ptr, geom.ptr))
295
282
  end
296
283
 
297
284
  def overlaps?(geom)
298
285
  check_geometry(geom)
299
- bool_result(FFIGeos.GEOSOverlaps_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
286
+ bool_result(FFIGeos.GEOSOverlaps_r(Geos.current_handle_pointer, ptr, geom.ptr))
300
287
  end
301
288
 
302
289
  if FFIGeos.respond_to?(:GEOSCovers_r)
@@ -305,7 +292,7 @@ module Geos
305
292
  # implementation.
306
293
  def covers?(geom)
307
294
  check_geometry(geom)
308
- bool_result(FFIGeos.GEOSCovers_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
295
+ bool_result(FFIGeos.GEOSCovers_r(Geos.current_handle_pointer, ptr, geom.ptr))
309
296
  end
310
297
  else
311
298
  def covers?(geom) #:nodoc:
@@ -316,7 +303,7 @@ module Geos
316
303
  ***T**FF*
317
304
  ****T*FF*
318
305
  }.detect do |pattern|
319
- self.relate_pattern(geom, pattern)
306
+ relate_pattern(geom, pattern)
320
307
  end
321
308
  end
322
309
  end
@@ -327,7 +314,7 @@ module Geos
327
314
  # implementation.
328
315
  def covered_by?(geom)
329
316
  check_geometry(geom)
330
- bool_result(FFIGeos.GEOSCoveredBy_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
317
+ bool_result(FFIGeos.GEOSCoveredBy_r(Geos.current_handle_pointer, ptr, geom.ptr))
331
318
  end
332
319
  else
333
320
  def covered_by?(geom) #:nodoc:
@@ -338,57 +325,55 @@ module Geos
338
325
  **FT*F***
339
326
  **F*TF***
340
327
  }.detect do |pattern|
341
- self.relate_pattern(geom, pattern)
328
+ relate_pattern(geom, pattern)
342
329
  end
343
330
  end
344
331
  end
345
332
 
346
- def eql?(geom)
347
- check_geometry(geom)
348
- bool_result(FFIGeos.GEOSEquals_r(Geos.current_handle_pointer, self.ptr, geom.ptr))
333
+ def eql?(other)
334
+ check_geometry(other)
335
+ bool_result(FFIGeos.GEOSEquals_r(Geos.current_handle_pointer, ptr, other.ptr))
349
336
  end
350
- alias_method :equals?, :eql?
337
+ alias equals? eql?
351
338
 
352
- def ==(geom)
353
- if geom.is_a?(Geos::Geometry)
354
- self.eql?(geom)
355
- else
356
- false
357
- end
339
+ def ==(other)
340
+ return eql?(other) if other.is_a?(Geos::Geometry)
341
+
342
+ false
358
343
  end
359
344
 
360
- def eql_exact?(geom, tolerance)
361
- check_geometry(geom)
362
- bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, self.ptr, geom.ptr, tolerance))
345
+ def eql_exact?(other, tolerance)
346
+ check_geometry(other)
347
+ bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, ptr, other.ptr, tolerance))
363
348
  end
364
- alias_method :equals_exact?, :eql_exact?
365
- alias_method :exactly_equals?, :eql_exact?
349
+ alias equals_exact? eql_exact?
350
+ alias exactly_equals? eql_exact?
366
351
 
367
- def eql_almost?(geom, decimal = 6)
368
- check_geometry(geom)
369
- bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, self.ptr, geom.ptr, 0.5 * 10 ** (-decimal)))
352
+ def eql_almost?(other, decimal = 6)
353
+ check_geometry(other)
354
+ bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, ptr, other.ptr, 0.5 * 10 ** -decimal))
370
355
  end
371
- alias_method :equals_almost?, :eql_almost?
372
- alias_method :almost_equals?, :eql_almost?
356
+ alias equals_almost? eql_almost?
357
+ alias almost_equals? eql_almost?
373
358
 
374
359
  def empty?
375
- bool_result(FFIGeos.GEOSisEmpty_r(Geos.current_handle_pointer, self.ptr))
360
+ bool_result(FFIGeos.GEOSisEmpty_r(Geos.current_handle_pointer, ptr))
376
361
  end
377
362
 
378
363
  def valid?
379
- bool_result(FFIGeos.GEOSisValid_r(Geos.current_handle_pointer, self.ptr))
364
+ bool_result(FFIGeos.GEOSisValid_r(Geos.current_handle_pointer, ptr))
380
365
  end
381
366
 
382
367
  # Returns a String describing whether or not the Geometry is valid.
383
368
  def valid_reason
384
- FFIGeos.GEOSisValidReason_r(Geos.current_handle_pointer, self.ptr)
369
+ FFIGeos.GEOSisValidReason_r(Geos.current_handle_pointer, ptr)
385
370
  end
386
371
 
387
372
  # Returns a Hash containing the following structure on invalid geometries:
388
373
  #
389
374
  # {
390
- # :detail => "String explaining the problem",
391
- # :location => Geos::Point # centered on the problem
375
+ # detail: "String explaining the problem",
376
+ # location: Geos::Point # centered on the problem
392
377
  # }
393
378
  #
394
379
  # If the Geometry is valid, returns nil.
@@ -396,95 +381,89 @@ module Geos
396
381
  detail = FFI::MemoryPointer.new(:pointer)
397
382
  location = FFI::MemoryPointer.new(:pointer)
398
383
  valid = bool_result(
399
- FFIGeos.GEOSisValidDetail_r(Geos.current_handle_pointer, self.ptr, flags, detail, location)
384
+ FFIGeos.GEOSisValidDetail_r(Geos.current_handle_pointer, ptr, flags, detail, location)
400
385
  )
401
386
 
402
- if !valid
403
- {
404
- :detail => detail.read_pointer.read_string,
405
- :location => cast_geometry_ptr(location.read_pointer, {
406
- :srid_copy => self.srid
407
- })
408
- }
409
- end
387
+ return if valid
388
+
389
+ {
390
+ detail: detail.read_pointer.read_string,
391
+ location: cast_geometry_ptr(location.read_pointer, srid_copy: srid)
392
+ }
410
393
  end
411
394
 
412
395
  def simple?
413
- bool_result(FFIGeos.GEOSisSimple_r(Geos.current_handle_pointer, self.ptr))
396
+ bool_result(FFIGeos.GEOSisSimple_r(Geos.current_handle_pointer, ptr))
414
397
  end
415
398
 
416
399
  def ring?
417
- bool_result(FFIGeos.GEOSisRing_r(Geos.current_handle_pointer, self.ptr))
400
+ bool_result(FFIGeos.GEOSisRing_r(Geos.current_handle_pointer, ptr))
418
401
  end
419
402
 
420
403
  def has_z?
421
- bool_result(FFIGeos.GEOSHasZ_r(Geos.current_handle_pointer, self.ptr))
404
+ bool_result(FFIGeos.GEOSHasZ_r(Geos.current_handle_pointer, ptr))
422
405
  end
423
406
 
424
407
  # GEOS versions prior to 3.3.0 didn't handle exceptions and can crash on
425
408
  # bad input.
426
409
  if FFIGeos.respond_to?(:GEOSProject_r) && Geos::GEOS_VERSION >= '3.3.0'
427
410
  def project(geom, normalized = false)
428
- raise TypeError.new("Expected Geos::Point type") if !geom.is_a?(Geos::Point)
411
+ raise TypeError, 'Expected Geos::Point type' unless geom.is_a?(Geos::Point)
429
412
 
430
413
  if normalized
431
- FFIGeos.GEOSProjectNormalized_r(Geos.current_handle_pointer, self.ptr, geom.ptr)
414
+ FFIGeos.GEOSProjectNormalized_r(Geos.current_handle_pointer, ptr, geom.ptr)
432
415
  else
433
- FFIGeos.GEOSProject_r(Geos.current_handle_pointer, self.ptr, geom.ptr)
416
+ FFIGeos.GEOSProject_r(Geos.current_handle_pointer, ptr, geom.ptr)
434
417
  end
435
418
  end
436
419
 
437
420
  def project_normalized(geom)
438
- self.project(geom, true)
421
+ project(geom, true)
439
422
  end
440
423
  end
441
424
 
442
425
  def interpolate(d, normalized = false)
443
426
  ret = if normalized
444
- FFIGeos.GEOSInterpolateNormalized_r(Geos.current_handle_pointer, self.ptr, d)
427
+ FFIGeos.GEOSInterpolateNormalized_r(Geos.current_handle_pointer, ptr, d)
445
428
  else
446
- FFIGeos.GEOSInterpolate_r(Geos.current_handle_pointer, self.ptr, d)
429
+ FFIGeos.GEOSInterpolate_r(Geos.current_handle_pointer, ptr, d)
447
430
  end
448
431
 
449
- cast_geometry_ptr(ret, :srid_copy => self.srid)
432
+ cast_geometry_ptr(ret, srid_copy: srid)
450
433
  end
451
434
 
452
435
  def interpolate_normalized(d)
453
- self.interpolate(d, true)
436
+ interpolate(d, true)
454
437
  end
455
438
 
456
439
  def start_point
457
- cast_geometry_ptr(FFIGeos.GEOSGeomGetStartPoint_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
440
+ cast_geometry_ptr(FFIGeos.GEOSGeomGetStartPoint_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
458
441
  end
459
442
 
460
443
  def end_point
461
- cast_geometry_ptr(FFIGeos.GEOSGeomGetEndPoint_r(Geos.current_handle_pointer, self.ptr), :srid_copy => self.srid)
444
+ cast_geometry_ptr(FFIGeos.GEOSGeomGetEndPoint_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
462
445
  end
463
446
 
464
447
  def area
465
- if self.empty?
466
- 0
467
- else
468
- double_ptr = FFI::MemoryPointer.new(:double)
469
- FFIGeos.GEOSArea_r(Geos.current_handle_pointer, self.ptr, double_ptr)
470
- double_ptr.read_double
471
- end
448
+ return 0 if empty?
449
+
450
+ double_ptr = FFI::MemoryPointer.new(:double)
451
+ FFIGeos.GEOSArea_r(Geos.current_handle_pointer, ptr, double_ptr)
452
+ double_ptr.read_double
472
453
  end
473
454
 
474
455
  def length
475
- if self.empty?
476
- 0
477
- else
478
- double_ptr = FFI::MemoryPointer.new(:double)
479
- FFIGeos.GEOSLength_r(Geos.current_handle_pointer, self.ptr, double_ptr)
480
- double_ptr.read_double
481
- end
456
+ return 0 if empty?
457
+
458
+ double_ptr = FFI::MemoryPointer.new(:double)
459
+ FFIGeos.GEOSLength_r(Geos.current_handle_pointer, ptr, double_ptr)
460
+ double_ptr.read_double
482
461
  end
483
462
 
484
463
  def distance(geom)
485
464
  check_geometry(geom)
486
465
  double_ptr = FFI::MemoryPointer.new(:double)
487
- FFIGeos.GEOSDistance_r(Geos.current_handle_pointer, self.ptr, geom.ptr, double_ptr)
466
+ FFIGeos.GEOSDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
488
467
  double_ptr.read_double
489
468
  end
490
469
 
@@ -494,9 +473,9 @@ module Geos
494
473
  double_ptr = FFI::MemoryPointer.new(:double)
495
474
 
496
475
  if densify_frac
497
- FFIGeos.GEOSHausdorffDistanceDensify_r(Geos.current_handle_pointer, self.ptr, geom.ptr, densify_frac, double_ptr)
476
+ FFIGeos.GEOSHausdorffDistanceDensify_r(Geos.current_handle_pointer, ptr, geom.ptr, densify_frac, double_ptr)
498
477
  else
499
- FFIGeos.GEOSHausdorffDistance_r(Geos.current_handle_pointer, self.ptr, geom.ptr, double_ptr)
478
+ FFIGeos.GEOSHausdorffDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
500
479
  end
501
480
 
502
481
  double_ptr.read_double
@@ -506,72 +485,62 @@ module Geos
506
485
  # Available in GEOS 3.4+.
507
486
  def nearest_points(geom)
508
487
  check_geometry(geom)
509
- ptr = FFIGeos.GEOSNearestPoints_r(Geos.current_handle_pointer, self.ptr, geom.ptr)
488
+ nearest_points_ptr = FFIGeos.GEOSNearestPoints_r(Geos.current_handle_pointer, ptr, geom.ptr)
510
489
 
511
- if !ptr.null?
512
- CoordinateSequence.new(ptr)
513
- end
490
+ return CoordinateSequence.new(nearest_points_ptr) unless nearest_points_ptr.null?
514
491
  end
515
492
  end
516
493
 
517
494
  def snap(geom, tolerance)
518
495
  check_geometry(geom)
519
- cast_geometry_ptr(FFIGeos.GEOSSnap_r(Geos.current_handle_pointer, self.ptr, geom.ptr, tolerance), {
520
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
521
- })
496
+ cast_geometry_ptr(FFIGeos.GEOSSnap_r(Geos.current_handle_pointer, ptr, geom.ptr, tolerance), srid_copy: pick_srid_from_geoms(srid, geom.srid))
522
497
  end
523
- alias_method :snap_to, :snap
498
+ alias snap_to snap
524
499
 
525
500
  def shared_paths(geom)
526
501
  check_geometry(geom)
527
- cast_geometry_ptr(FFIGeos.GEOSSharedPaths_r(Geos.current_handle_pointer, self.ptr, geom.ptr), {
528
- :srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
529
- }).to_a
502
+ cast_geometry_ptr(FFIGeos.GEOSSharedPaths_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid)).to_a
530
503
  end
531
504
 
532
505
  # Returns a Hash with the following structure:
533
506
  #
534
507
  # {
535
- # :rings => [ ... ],
536
- # :cuts => [ ... ],
537
- # :dangles => [ ... ],
538
- # :invalid_rings => [ ... ]
508
+ # rings: [ ... ],
509
+ # cuts: [ ... ],
510
+ # dangles: [ ... ],
511
+ # invalid_rings: [ ... ]
539
512
  # }
540
513
  def polygonize_full
541
514
  cuts = FFI::MemoryPointer.new(:pointer)
542
515
  dangles = FFI::MemoryPointer.new(:pointer)
543
516
  invalid_rings = FFI::MemoryPointer.new(:pointer)
544
517
 
545
- rings = cast_geometry_ptr(
546
- FFIGeos.GEOSPolygonize_full_r(Geos.current_handle_pointer, self.ptr, cuts, dangles, invalid_rings), {
547
- :srid_copy => self.srid
548
- }
549
- )
518
+ rings = cast_geometry_ptr(FFIGeos.GEOSPolygonize_full_r(Geos.current_handle_pointer, ptr, cuts, dangles, invalid_rings), srid_copy: srid)
550
519
 
551
- cuts = cast_geometry_ptr(cuts.read_pointer, :srid_copy => self.srid)
552
- dangles = cast_geometry_ptr(dangles.read_pointer, :srid_copy => self.srid)
553
- invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer, :srid_copy => self.srid)
520
+ cuts = cast_geometry_ptr(cuts.read_pointer, srid_copy: srid)
521
+ dangles = cast_geometry_ptr(dangles.read_pointer, srid_copy: srid)
522
+ invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer, srid_copy: srid)
554
523
 
555
524
  {
556
- :rings => rings.to_a,
557
- :cuts => cuts.to_a,
558
- :dangles => dangles.to_a,
559
- :invalid_rings => invalid_rings.to_a
525
+ rings: rings.to_a,
526
+ cuts: cuts.to_a,
527
+ dangles: dangles.to_a,
528
+ invalid_rings: invalid_rings.to_a
560
529
  }
561
530
  end
562
531
 
563
532
  def polygonize
564
533
  ary = FFI::MemoryPointer.new(:pointer)
565
- ary.write_array_of_pointer([ self.ptr ])
534
+ ary.write_array_of_pointer([ ptr ])
566
535
 
567
- cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle_pointer, ary, 1), :srid_copy => self.srid).to_a
536
+ cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle_pointer, ary, 1), srid_copy: srid).to_a
568
537
  end
569
538
 
570
539
  def polygonize_cut_edges
571
540
  ary = FFI::MemoryPointer.new(:pointer)
572
- ary.write_array_of_pointer([ self.ptr ])
541
+ ary.write_array_of_pointer([ ptr ])
573
542
 
574
- cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle_pointer, ary, 1), :srid_copy => self.srid).to_a
543
+ cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle_pointer, ary, 1), srid_copy: srid).to_a
575
544
  end
576
545
 
577
546
  if FFIGeos.respond_to?(:GEOSDelaunayTriangulation_r)
@@ -589,7 +558,7 @@ module Geos
589
558
  tolerance = args.first || options[:tolerance] || 0.0
590
559
  only_edges = bool_to_int(options[:only_edges])
591
560
 
592
- cast_geometry_ptr(FFIGeos.GEOSDelaunayTriangulation_r(Geos.current_handle_pointer, self.ptr, tolerance, only_edges))
561
+ cast_geometry_ptr(FFIGeos.GEOSDelaunayTriangulation_r(Geos.current_handle_pointer, ptr, tolerance, only_edges))
593
562
  end
594
563
  end
595
564
 
@@ -617,7 +586,7 @@ module Geos
617
586
 
618
587
  only_edges = bool_to_int(options[:only_edges])
619
588
 
620
- cast_geometry_ptr(FFIGeos.GEOSVoronoiDiagram_r(Geos.current_handle_pointer, self.ptr, envelope_ptr, tolerance, only_edges))
589
+ cast_geometry_ptr(FFIGeos.GEOSVoronoiDiagram_r(Geos.current_handle_pointer, ptr, envelope_ptr, tolerance, only_edges))
621
590
  end
622
591
  end
623
592
 
@@ -628,24 +597,22 @@ module Geos
628
597
  def to_s
629
598
  writer = WktWriter.new
630
599
  wkt = writer.write(self)
631
- if wkt.length > 120
632
- wkt = "#{wkt[0...120]} ... "
633
- end
600
+ wkt = "#{wkt[0...120]} ... " if wkt.length > 120
634
601
 
635
- "#<Geos::#{self.geom_type}: #{wkt}>"
602
+ "#<Geos::#{geom_type}: #{wkt}>"
636
603
  end
637
604
 
638
605
  if FFIGeos.respond_to?(:GEOSGeom_getPrecision_r)
639
606
  def precision
640
- FFIGeos.GEOSGeom_getPrecision_r(Geos.current_handle_pointer, self.ptr)
607
+ FFIGeos.GEOSGeom_getPrecision_r(Geos.current_handle_pointer, ptr)
641
608
  end
642
609
  end
643
610
 
644
611
  if FFIGeos.respond_to?(:GEOSGeom_setPrecision_r)
645
612
  def with_precision(grid_size, options = {})
646
613
  options = {
647
- :no_topology => false,
648
- :keep_collapsed => false
614
+ no_topology: false,
615
+ keep_collapsed: false
649
616
  }.merge(options)
650
617
 
651
618
  flags = options.reduce(0) do |memo, (key, value)|
@@ -653,33 +620,55 @@ module Geos
653
620
  memo
654
621
  end
655
622
 
656
- cast_geometry_ptr(FFIGeos.GEOSGeom_setPrecision_r(Geos.current_handle_pointer, self.ptr, grid_size, flags))
623
+ cast_geometry_ptr(FFIGeos.GEOSGeom_setPrecision_r(Geos.current_handle_pointer, ptr, grid_size, flags))
657
624
  end
658
625
  end
659
626
 
660
627
  if FFIGeos.respond_to?(:GEOSMinimumRotatedRectangle_r)
661
628
  def minimum_rotated_rectangle
662
- cast_geometry_ptr(FFIGeos.GEOSMinimumRotatedRectangle_r(Geos.current_handle_pointer, self.ptr))
629
+ cast_geometry_ptr(FFIGeos.GEOSMinimumRotatedRectangle_r(Geos.current_handle_pointer, ptr))
663
630
  end
664
631
  end
665
632
 
666
633
  if FFIGeos.respond_to?(:GEOSMinimumClearance_r)
667
634
  def minimum_clearance
668
635
  double_ptr = FFI::MemoryPointer.new(:double)
669
- ret = FFIGeos.GEOSMinimumClearance_r(Geos.current_handle_pointer, self.ptr, double_ptr)
636
+ FFIGeos.GEOSMinimumClearance_r(Geos.current_handle_pointer, ptr, double_ptr)
670
637
  double_ptr.read_double
671
638
  end
672
639
  end
673
640
 
674
641
  if FFIGeos.respond_to?(:GEOSMinimumClearanceLine_r)
675
642
  def minimum_clearance_line
676
- cast_geometry_ptr(FFIGeos.GEOSMinimumClearanceLine_r(Geos.current_handle_pointer, self.ptr))
643
+ cast_geometry_ptr(FFIGeos.GEOSMinimumClearanceLine_r(Geos.current_handle_pointer, ptr))
677
644
  end
678
645
  end
679
646
 
680
647
  if FFIGeos.respond_to?(:GEOSMinimumWidth_r)
681
648
  def minimum_width
682
- cast_geometry_ptr(FFIGeos.GEOSMinimumWidth_r(Geos.current_handle_pointer, self.ptr))
649
+ cast_geometry_ptr(FFIGeos.GEOSMinimumWidth_r(Geos.current_handle_pointer, ptr))
650
+ end
651
+ end
652
+
653
+ if FFIGeos.respond_to?(:GEOSReverse_r)
654
+ def reverse
655
+ cast_geometry_ptr(FFIGeos.GEOSReverse_r(Geos.current_handle_pointer, ptr))
656
+ end
657
+ end
658
+
659
+ if FFIGeos.respond_to?(:GEOSFrechetDistance_r)
660
+ def frechet_distance(geom, densify_frac = nil)
661
+ check_geometry(geom)
662
+
663
+ double_ptr = FFI::MemoryPointer.new(:double)
664
+
665
+ if densify_frac
666
+ FFIGeos.GEOSFrechetDistanceDensify_r(Geos.current_handle_pointer, ptr, geom.ptr, densify_frac, double_ptr)
667
+ else
668
+ FFIGeos.GEOSFrechetDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
669
+ end
670
+
671
+ double_ptr.read_double
683
672
  end
684
673
  end
685
674
  end