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.
- checksums.yaml +5 -5
- data/.rubocop.yml +20 -0
- data/.travis.yml +7 -3
- data/Gemfile +1 -1
- data/Guardfile +4 -5
- data/ffi-geos.gemspec +1 -1
- data/lib/ffi-geos.rb +212 -196
- data/lib/ffi-geos/buffer_params.rb +9 -20
- data/lib/ffi-geos/coordinate_sequence.rb +342 -58
- data/lib/ffi-geos/geometry.rb +167 -178
- data/lib/ffi-geos/geometry_collection.rb +60 -12
- data/lib/ffi-geos/interrupt.rb +2 -4
- data/lib/ffi-geos/line_string.rb +146 -37
- 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 +69 -14
- data/lib/ffi-geos/polygon.rb +110 -21
- data/lib/ffi-geos/prepared_geometry.rb +11 -12
- data/lib/ffi-geos/strtree.rb +41 -52
- data/lib/ffi-geos/tools.rb +15 -18
- data/lib/ffi-geos/utils.rb +27 -44
- data/lib/ffi-geos/version.rb +1 -3
- data/lib/ffi-geos/wkb_reader.rb +4 -9
- data/lib/ffi-geos/wkb_writer.rb +14 -18
- data/lib/ffi-geos/wkt_reader.rb +2 -5
- data/lib/ffi-geos/wkt_writer.rb +17 -22
- data/test/.rubocop.yml +36 -0
- data/test/coordinate_sequence_tests.rb +263 -14
- data/test/geometry_collection_tests.rb +412 -1
- data/test/geometry_tests.rb +156 -86
- data/test/interrupt_tests.rb +2 -4
- data/test/line_string_tests.rb +212 -23
- data/test/linear_ring_tests.rb +1 -2
- data/test/misc_tests.rb +28 -29
- data/test/multi_line_string_tests.rb +0 -1
- data/test/point_tests.rb +158 -1
- data/test/polygon_tests.rb +284 -1
- data/test/prepared_geometry_tests.rb +1 -3
- data/test/strtree_tests.rb +9 -10
- data/test/test_helper.rb +49 -18
- data/test/tools_tests.rb +1 -3
- data/test/utils_tests.rb +22 -22
- data/test/wkb_reader_tests.rb +10 -9
- data/test/wkb_writer_tests.rb +5 -13
- data/test/wkt_reader_tests.rb +1 -2
- data/test/wkt_writer_tests.rb +9 -14
- metadata +6 -3
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,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,
|
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
|
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
|
-
|
62
|
+
alias normalize normalize!
|
64
63
|
|
65
64
|
def srid
|
66
|
-
FFIGeos.GEOSGetSRID_r(Geos.current_handle_pointer,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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(:
|
115
|
+
Geos::BufferParams.new(quad_segs: options)
|
119
116
|
else
|
120
|
-
raise ArgumentError
|
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,
|
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
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
153
|
+
alias symmetric_difference sym_difference
|
161
154
|
|
162
155
|
def boundary
|
163
|
-
cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle_pointer,
|
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,
|
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
|
177
|
-
|
167
|
+
if respond_to?(:unary_union)
|
168
|
+
unary_union
|
178
169
|
else
|
179
|
-
|
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,
|
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,
|
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,
|
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,
|
194
|
+
cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
|
208
195
|
end
|
209
|
-
|
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,
|
201
|
+
cast_geometry_ptr(FFIGeos.GEOSClipByRect_r(Geos.current_handle_pointer, ptr, xmin, ymin, xmax, ymax))
|
215
202
|
end
|
216
|
-
|
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,
|
207
|
+
cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
|
221
208
|
end
|
222
|
-
|
209
|
+
alias center centroid
|
223
210
|
|
224
211
|
def envelope
|
225
|
-
cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle_pointer,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
250
|
+
cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
|
264
251
|
end
|
265
|
-
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
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,
|
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
|
-
|
328
|
+
relate_pattern(geom, pattern)
|
342
329
|
end
|
343
330
|
end
|
344
331
|
end
|
345
332
|
|
346
|
-
def eql?(
|
347
|
-
check_geometry(
|
348
|
-
bool_result(FFIGeos.GEOSEquals_r(Geos.current_handle_pointer,
|
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
|
-
|
337
|
+
alias equals? eql?
|
351
338
|
|
352
|
-
def ==(
|
353
|
-
if
|
354
|
-
|
355
|
-
|
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?(
|
361
|
-
check_geometry(
|
362
|
-
bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer,
|
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
|
-
|
365
|
-
|
349
|
+
alias equals_exact? eql_exact?
|
350
|
+
alias exactly_equals? eql_exact?
|
366
351
|
|
367
|
-
def eql_almost?(
|
368
|
-
check_geometry(
|
369
|
-
bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer,
|
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
|
-
|
372
|
-
|
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,
|
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,
|
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,
|
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
|
-
# :
|
391
|
-
# :
|
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,
|
384
|
+
FFIGeos.GEOSisValidDetail_r(Geos.current_handle_pointer, ptr, flags, detail, location)
|
400
385
|
)
|
401
386
|
|
402
|
-
if
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
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,
|
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,
|
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,
|
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
|
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,
|
414
|
+
FFIGeos.GEOSProjectNormalized_r(Geos.current_handle_pointer, ptr, geom.ptr)
|
432
415
|
else
|
433
|
-
FFIGeos.GEOSProject_r(Geos.current_handle_pointer,
|
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
|
-
|
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,
|
427
|
+
FFIGeos.GEOSInterpolateNormalized_r(Geos.current_handle_pointer, ptr, d)
|
445
428
|
else
|
446
|
-
FFIGeos.GEOSInterpolate_r(Geos.current_handle_pointer,
|
429
|
+
FFIGeos.GEOSInterpolate_r(Geos.current_handle_pointer, ptr, d)
|
447
430
|
end
|
448
431
|
|
449
|
-
cast_geometry_ptr(ret, :
|
432
|
+
cast_geometry_ptr(ret, srid_copy: srid)
|
450
433
|
end
|
451
434
|
|
452
435
|
def interpolate_normalized(d)
|
453
|
-
|
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,
|
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,
|
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
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
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
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
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,
|
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,
|
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,
|
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
|
-
|
488
|
+
nearest_points_ptr = FFIGeos.GEOSNearestPoints_r(Geos.current_handle_pointer, ptr, geom.ptr)
|
510
489
|
|
511
|
-
|
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,
|
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
|
-
|
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,
|
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
|
-
# :
|
536
|
-
# :
|
537
|
-
# :
|
538
|
-
# :
|
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, :
|
552
|
-
dangles = cast_geometry_ptr(dangles.read_pointer, :
|
553
|
-
invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer, :
|
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
|
-
:
|
557
|
-
:
|
558
|
-
:
|
559
|
-
:
|
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([
|
534
|
+
ary.write_array_of_pointer([ ptr ])
|
566
535
|
|
567
|
-
cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle_pointer, ary, 1), :
|
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([
|
541
|
+
ary.write_array_of_pointer([ ptr ])
|
573
542
|
|
574
|
-
cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle_pointer, ary, 1), :
|
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,
|
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,
|
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::#{
|
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,
|
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
|
-
:
|
648
|
-
:
|
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,
|
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,
|
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
|
-
|
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,
|
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,
|
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
|