ffi-geos 1.2.0 → 2.2.0
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.
- 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
|