ffi-geos 1.2.1 → 1.2.2

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