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