ffi-geos 1.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +49 -0
  3. data/.rubocop.yml +5117 -4
  4. data/FUNDING.yml +2 -0
  5. data/Gemfile +9 -16
  6. data/Guardfile +3 -4
  7. data/MIT-LICENSE +1 -1
  8. data/README.rdoc +2 -20
  9. data/Rakefile +3 -2
  10. data/ffi-geos.gemspec +7 -2
  11. data/lib/ffi-geos/buffer_params.rb +1 -1
  12. data/lib/ffi-geos/coordinate_sequence.rb +179 -177
  13. data/lib/ffi-geos/geometry.rb +118 -31
  14. data/lib/ffi-geos/geometry_collection.rb +26 -12
  15. data/lib/ffi-geos/interrupt.rb +11 -14
  16. data/lib/ffi-geos/line_string.rb +64 -49
  17. data/lib/ffi-geos/multi_line_string.rb +1 -1
  18. data/lib/ffi-geos/point.rb +18 -18
  19. data/lib/ffi-geos/polygon.rb +44 -30
  20. data/lib/ffi-geos/prepared_geometry.rb +1 -1
  21. data/lib/ffi-geos/strtree.rb +28 -30
  22. data/lib/ffi-geos/tools.rb +1 -1
  23. data/lib/ffi-geos/utils.rb +16 -23
  24. data/lib/ffi-geos/version.rb +1 -1
  25. data/lib/ffi-geos/wkb_reader.rb +1 -1
  26. data/lib/ffi-geos/wkb_writer.rb +4 -5
  27. data/lib/ffi-geos/wkt_reader.rb +1 -1
  28. data/lib/ffi-geos/wkt_writer.rb +7 -13
  29. data/lib/ffi-geos.rb +134 -48
  30. data/sonar-project.properties +16 -0
  31. data/test/coordinate_sequence_tests.rb +148 -126
  32. data/test/geometry_collection_tests.rb +41 -67
  33. data/test/geometry_tests.rb +341 -40
  34. data/test/interrupt_tests.rb +7 -7
  35. data/test/line_string_tests.rb +23 -15
  36. data/test/point_tests.rb +5 -5
  37. data/test/polygon_tests.rb +6 -7
  38. data/test/prepared_geometry_tests.rb +8 -8
  39. data/test/strtree_tests.rb +13 -12
  40. data/test/test_helper.rb +74 -56
  41. data/test/utils_tests.rb +69 -59
  42. data/test/wkb_reader_tests.rb +9 -9
  43. data/test/wkb_writer_tests.rb +14 -12
  44. data/test/wkt_reader_tests.rb +0 -1
  45. data/test/wkt_writer_tests.rb +2 -5
  46. metadata +12 -10
  47. data/.travis.yml +0 -21
@@ -13,12 +13,40 @@ class GeometryTests < Minitest::Test
13
13
  def test_intersection
14
14
  comparison_tester(
15
15
  :intersection,
16
- 'POLYGON ((5 10, 10 10, 10 5, 5 5, 5 10))',
16
+ if Geos::GEOS_NICE_VERSION > '030900'
17
+ 'POLYGON ((10 10, 10 5, 5 5, 5 10, 10 10))'
18
+ else
19
+ 'POLYGON ((5 10, 10 10, 10 5, 5 5, 5 10))'
20
+ end,
17
21
  'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))',
18
22
  'POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))'
19
23
  )
20
24
  end
21
25
 
26
+ def test_intersection_with_precision
27
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSIntersectionPrec_r)
28
+
29
+ comparison_tester(
30
+ :intersection,
31
+ 'GEOMETRYCOLLECTION (POLYGON ((1 2, 1 1, 0.5 1, 1 2)), POLYGON ((9.5 1, 2 1, 2 2, 9 2, 9.5 1)), LINESTRING (1 1, 2 1), LINESTRING (2 2, 1 2))',
32
+ 'MULTIPOLYGON(((0 0,5 10,10 0,0 0),(1 1,1 2,2 2,2 1,1 1),(100 100,100 102,102 102,102 100,100 100)))',
33
+ 'POLYGON((0 1,0 2,10 2,10 1,0 1))',
34
+ precision: 0
35
+ )
36
+
37
+ comparison_tester(
38
+ :intersection,
39
+ if Geos::GEOS_NICE_VERSION >= '031000'
40
+ 'GEOMETRYCOLLECTION (LINESTRING (2 0, 4 0), POINT (10 0), POINT (0 0))'
41
+ else
42
+ 'GEOMETRYCOLLECTION (LINESTRING (2 0, 4 0), POINT (0 0), POINT (10 0))'
43
+ end,
44
+ 'LINESTRING(0 0, 10 0)',
45
+ 'LINESTRING(9 0, 12 0, 12 20, 4 0, 2 0, 2 10, 0 10, 0 -10)',
46
+ precision: 2
47
+ )
48
+ end
49
+
22
50
  def test_buffer
23
51
  simple_tester(
24
52
  :buffer,
@@ -95,7 +123,11 @@ class GeometryTests < Minitest::Test
95
123
 
96
124
  snapped_tester(
97
125
  :buffer,
98
- 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 109 -5, 105 -9, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
126
+ if Geos::GEOS_NICE_VERSION >= '031100'
127
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 -4, 104 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
128
+ else
129
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 109 -5, 105 -9, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
130
+ end,
99
131
  'LINESTRING(0 0, 100 0, 100 100)',
100
132
  10,
101
133
  quad_segs: 2, join: :mitre, mitre_limit: 1.0
@@ -133,7 +165,7 @@ class GeometryTests < Minitest::Test
133
165
  def test_difference
134
166
  comparison_tester(
135
167
  :difference,
136
- 'GEOMETRYCOLLECTION EMPTY',
168
+ EMPTY_GEOMETRY,
137
169
  'POINT(0 0)',
138
170
  'POINT(0 0)'
139
171
  )
@@ -154,7 +186,7 @@ class GeometryTests < Minitest::Test
154
186
 
155
187
  comparison_tester(
156
188
  :difference,
157
- 'GEOMETRYCOLLECTION EMPTY',
189
+ EMPTY_GEOMETRY,
158
190
  'POINT(5 0)',
159
191
  'LINESTRING(0 0, 10 0)'
160
192
  )
@@ -182,31 +214,55 @@ class GeometryTests < Minitest::Test
182
214
 
183
215
  comparison_tester(
184
216
  :difference,
185
- 'POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0))',
217
+ if Geos::GEOS_NICE_VERSION > '030900'
218
+ 'POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10))'
219
+ else
220
+ 'POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0))'
221
+ end,
186
222
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
187
223
  'LINESTRING(5 -10, 5 10)'
188
224
  )
189
225
 
190
226
  comparison_tester(
191
227
  :difference,
192
- 'POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0))',
228
+ if Geos::GEOS_NICE_VERSION > '030900'
229
+ 'POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10))'
230
+ else
231
+ 'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))'
232
+ end,
193
233
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
194
234
  'LINESTRING(10 0, 20 0)'
195
235
  )
196
236
 
197
237
  comparison_tester(
198
238
  :difference,
199
- 'POLYGON ((5 0, 0 0, 0 10, 10 10, 10 5, 5 5, 5 0))',
239
+ if Geos::GEOS_NICE_VERSION > '030900'
240
+ 'POLYGON ((0 10, 10 10, 10 5, 5 5, 5 0, 0 0, 0 10))'
241
+ else
242
+ 'POLYGON ((0 0, 0 10, 10 10, 10 5, 5 5, 5 0, 0 0))'
243
+ end,
200
244
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
201
245
  'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))'
202
246
  )
203
247
  end
204
248
 
249
+ def test_difference_with_precision
250
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSDifferencePrec_r)
251
+
252
+ comparison_tester(
253
+ :difference,
254
+ 'MULTILINESTRING ((2 8, 4 8), (6 8, 10 8))',
255
+ 'LINESTRING (2 8, 10 8)',
256
+ 'LINESTRING (3.9 8.1, 6.1 7.9)',
257
+ precision: 2
258
+ )
259
+ end
260
+
205
261
  def test_sym_difference
206
262
  %w{ sym_difference symmetric_difference }.each do |method|
207
263
  comparison_tester(
208
264
  method,
209
- 'GEOMETRYCOLLECTION EMPTY',
265
+ EMPTY_GEOMETRY,
210
266
  'POINT(0 0)',
211
267
  'POINT(0 0)'
212
268
  )
@@ -255,27 +311,51 @@ class GeometryTests < Minitest::Test
255
311
 
256
312
  comparison_tester(
257
313
  method,
258
- 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0)))',
314
+ if Geos::GEOS_NICE_VERSION > '030900'
315
+ 'GEOMETRYCOLLECTION (POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10)), LINESTRING (5 -10, 5 0))'
316
+ else
317
+ 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0)))'
318
+ end,
259
319
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
260
320
  'LINESTRING(5 -10, 5 10)'
261
321
  )
262
322
 
263
323
  comparison_tester(
264
324
  method,
265
- 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0)))',
325
+ if Geos::GEOS_NICE_VERSION > '030900'
326
+ 'GEOMETRYCOLLECTION (POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10)), LINESTRING (10 0, 20 0))'
327
+ else
328
+ 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0)))'
329
+ end,
266
330
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
267
331
  'LINESTRING(10 0, 20 0)'
268
332
  )
269
333
 
270
334
  comparison_tester(
271
335
  method,
272
- 'MULTIPOLYGON (((5 0, 0 0, 0 10, 10 10, 10 5, 5 5, 5 0)), ((5 0, 10 0, 10 5, 15 5, 15 -5, 5 -5, 5 0)))',
336
+ if Geos::GEOS_NICE_VERSION > '030900'
337
+ 'MULTIPOLYGON (((0 10, 10 10, 10 5, 5 5, 5 0, 0 0, 0 10)), ((10 0, 10 5, 15 5, 15 -5, 5 -5, 5 0, 10 0)))'
338
+ else
339
+ 'MULTIPOLYGON (((0 0, 0 10, 10 10, 10 5, 5 5, 5 0, 0 0)), ((5 0, 10 0, 10 5, 15 5, 15 -5, 5 -5, 5 0)))'
340
+ end,
273
341
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
274
342
  'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))'
275
343
  )
276
344
  end
277
345
  end
278
346
 
347
+ def test_sym_difference_with_precision
348
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSSymDifferencePrec_r)
349
+
350
+ comparison_tester(
351
+ :sym_difference,
352
+ 'GEOMETRYCOLLECTION (POLYGON ((0 10, 6 10, 10 10, 10 0, 6 0, 0 0, 0 10)), LINESTRING (6 -10, 6 0))',
353
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
354
+ 'LINESTRING(5 -10, 5 10)',
355
+ precision: 2
356
+ )
357
+ end
358
+
279
359
  def test_boundary
280
360
  simple_tester(
281
361
  :boundary,
@@ -348,32 +428,59 @@ class GeometryTests < Minitest::Test
348
428
 
349
429
  comparison_tester(
350
430
  :union,
351
- 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0)))',
431
+ if Geos::GEOS_NICE_VERSION > '030900'
432
+ 'GEOMETRYCOLLECTION (POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10)), LINESTRING (5 -10, 5 0))'
433
+ else
434
+ 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0)))'
435
+ end,
352
436
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
353
437
  'LINESTRING(5 -10, 5 10)'
354
438
  )
355
439
 
356
440
  comparison_tester(
357
441
  :union,
358
- 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0)))',
442
+ if Geos::GEOS_NICE_VERSION > '030900'
443
+ 'GEOMETRYCOLLECTION (POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10)), LINESTRING (10 0, 20 0))'
444
+ else
445
+ 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0)))'
446
+ end,
359
447
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
360
448
  'LINESTRING(10 0, 20 0)'
361
449
  )
362
450
 
363
451
  comparison_tester(
364
452
  :union,
365
- 'POLYGON ((5 0, 0 0, 0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0))',
453
+ if Geos::GEOS_NICE_VERSION > '030900'
454
+ 'POLYGON ((0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0, 0 0, 0 10))'
455
+ else
456
+ 'POLYGON ((0 0, 0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0, 0 0))'
457
+ end,
366
458
  'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
367
459
  'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))'
368
460
  )
369
461
  end
370
462
 
463
+ def test_union_with_precision
464
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSUnionPrec_r)
465
+
466
+ geom_a = read('POINT (1.9 8.2)')
467
+ geom_b = read('POINT (4.1 9.8)')
468
+
469
+ result = geom_a.union(geom_b, precision: 2)
470
+
471
+ assert_equal('MULTIPOINT (2 8, 4 10)', write(result))
472
+ end
473
+
371
474
  def test_union_cascaded
372
475
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:union_cascaded)
373
476
 
374
477
  simple_tester(
375
478
  :union_cascaded,
376
- 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))',
479
+ if Geos::GEOS_NICE_VERSION > '030900'
480
+ 'POLYGON ((0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0, 0 0), (12 12, 11 12, 11 11, 12 11, 12 12))'
481
+ else
482
+ 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))'
483
+ end,
377
484
  'MULTIPOLYGON(
378
485
  ((0 0, 1 0, 1 1, 0 1, 0 0)),
379
486
  ((10 10, 10 14, 14 14, 14 10, 10 10),
@@ -383,12 +490,33 @@ class GeometryTests < Minitest::Test
383
490
  )
384
491
  end
385
492
 
493
+ def test_coverage_union
494
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:coverage_union)
495
+
496
+ simple_tester(
497
+ :union_cascaded,
498
+ if Geos::GEOS_NICE_VERSION > '030900'
499
+ 'POLYGON ((0 1, 1 1, 2 1, 2 0, 1 0, 0 0, 0 1))'
500
+ else
501
+ 'POLYGON ((0 0, 0 1, 1 1, 2 1, 2 0, 1 0, 0 0))'
502
+ end,
503
+ 'MULTIPOLYGON(
504
+ ((0 0, 0 1, 1 1, 1 0, 0 0)),
505
+ ((1 0, 1 1, 2 1, 2 0, 1 0))
506
+ ))'
507
+ )
508
+ end
509
+
386
510
  def test_unary_union
387
511
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:unary_union)
388
512
 
389
513
  simple_tester(
390
514
  :unary_union,
391
- 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))',
515
+ if Geos::GEOS_NICE_VERSION > '030900'
516
+ 'POLYGON ((0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0, 0 0), (12 12, 11 12, 11 11, 12 11, 12 12))'
517
+ else
518
+ 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))'
519
+ end,
392
520
  'MULTIPOLYGON(
393
521
  ((0 0, 1 0, 1 1, 0 1, 0 0)),
394
522
  ((10 10, 10 14, 14 14, 14 10, 10 10),
@@ -398,6 +526,22 @@ class GeometryTests < Minitest::Test
398
526
  )
399
527
  end
400
528
 
529
+ def test_unary_union_with_precision
530
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSUnaryUnionPrec_r)
531
+
532
+ simple_tester(
533
+ :unary_union,
534
+ 'POLYGON ((0 0, 0 12, 9 12, 9 15, 15 15, 15 9, 12 9, 12 0, 0 0))',
535
+ 'MULTIPOLYGON(
536
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
537
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
538
+ (11 11, 11 12, 12 12, 12 11, 11 11)),
539
+ ((0 0, 11 0, 11 11, 0 11, 0 0))
540
+ ))',
541
+ 3
542
+ )
543
+ end
544
+
401
545
  def test_node
402
546
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:node)
403
547
 
@@ -411,7 +555,11 @@ class GeometryTests < Minitest::Test
411
555
  def test_union_without_arguments
412
556
  simple_tester(
413
557
  :union,
414
- 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))',
558
+ if Geos::GEOS_NICE_VERSION > '030900'
559
+ 'POLYGON ((0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0, 0 0), (12 12, 11 12, 11 11, 12 11, 12 12))'
560
+ else
561
+ 'POLYGON ((1 0, 0 0, 0 1, 0 11, 10 11, 10 14, 14 14, 14 10, 11 10, 11 0, 1 0), (11 11, 12 11, 12 12, 11 12, 11 11))'
562
+ end,
415
563
  'MULTIPOLYGON(
416
564
  ((0 0, 1 0, 1 1, 0 1, 0 0)),
417
565
  ((10 10, 10 14, 14 14, 14 10, 10 10),
@@ -515,6 +663,17 @@ class GeometryTests < Minitest::Test
515
663
  end
516
664
  end
517
665
 
666
+ def test_minimum_bounding_circle
667
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:minimum_bounding_circle)
668
+
669
+ geom = read('LINESTRING(0 10, 0 20)')
670
+
671
+ assert_equal(
672
+ 'POLYGON ((5 15, 5 14, 5 13, 4 12, 4 11, 3 11, 2 10, 1 10, 0 10, -1 10, -2 10, -3 11, -4 11, -4 12, -5 13, -5 14, -5 15, -5 16, -5 17, -4 18, -4 19, -3 19, -2 20, -1 20, 0 20, 1 20, 2 20, 3 19, 4 19, 4 18, 5 17, 5 16, 5 15))',
673
+ write(geom.minimum_bounding_circle.snap_to_grid(1))
674
+ )
675
+ end
676
+
518
677
  def test_envelope
519
678
  simple_tester(
520
679
  :envelope,
@@ -649,7 +808,7 @@ class GeometryTests < Minitest::Test
649
808
  tests.each do |test|
650
809
  expected, method, args = test
651
810
  if ENV['FORCE_TESTS'] || geom_a.respond_to?(method)
652
- value = geom_a.send(method, *([ geom_b ] + Array(args)))
811
+ value = geom_a.send(method, *([geom_b] + Array(args)))
653
812
  assert_equal(expected, value)
654
813
  end
655
814
  end
@@ -804,7 +963,13 @@ class GeometryTests < Minitest::Test
804
963
  }
805
964
 
806
965
  assert_nil(read('POINT(0 0)').valid_detail)
807
- tester['Invalid Coordinate', 'POINT (0 nan)', 'POINT(0 NaN)', 0]
966
+
967
+ if Geos::GEOS_NICE_VERSION >= '031000'
968
+ tester['Invalid Coordinate', 'POINT (0 NaN)', 'POINT(0 NaN)', 0]
969
+ else
970
+ tester['Invalid Coordinate', 'POINT (0 nan)', 'POINT(0 NaN)', 0]
971
+ end
972
+
808
973
  tester['Self-intersection', 'POINT (2.5 5)', 'POLYGON((0 0, 0 5, 5 5, 5 10, 0 0))', 0]
809
974
 
810
975
  tester['Ring Self-intersection', 'POINT (0 0)', 'POLYGON((0 0, -10 10, 10 10, 0 0, 4 5, -4 5, 0 0)))', 0]
@@ -951,7 +1116,7 @@ class GeometryTests < Minitest::Test
951
1116
  def test_interior_rings
952
1117
  array_tester(
953
1118
  :interior_rings,
954
- [ 'LINEARRING (11 11, 11 12, 12 12, 12 11, 11 11)' ],
1119
+ ['LINEARRING (11 11, 11 12, 12 12, 12 11, 11 11)'],
955
1120
  'POLYGON(
956
1121
  (10 10, 10 14, 14 14, 14 10, 10 10),
957
1122
  (11 11, 11 12, 12 12, 12 11, 11 11)
@@ -1154,12 +1319,22 @@ class GeometryTests < Minitest::Test
1154
1319
  simple_tester(:distance, 2.0, geom, read('LINESTRING (3 0 , 10 0)'))
1155
1320
  end
1156
1321
 
1322
+ def test_distance_indexed
1323
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:distance_indexed)
1324
+
1325
+ geom_a = read('POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))')
1326
+ geom_b = read('POLYGON ((20 30, 10 10, 13 14, 7 8, 20 30))')
1327
+
1328
+ assert_in_delta(9.219544457292887, geom_a.distance_indexed(geom_b), TOLERANCE)
1329
+ assert_in_delta(9.219544457292887, geom_b.distance_indexed(geom_a), TOLERANCE)
1330
+ end
1331
+
1157
1332
  def test_hausdorff_distance
1158
1333
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:hausdorff_distance)
1159
1334
 
1160
- tester = lambda { |expected, g1, g2|
1161
- geom_1 = read(g1)
1162
- geom_2 = read(g2)
1335
+ tester = lambda { |expected, g_1, g_2|
1336
+ geom_1 = read(g_1)
1337
+ geom_2 = read(g_2)
1163
1338
  assert_in_delta(expected, geom_1.hausdorff_distance(geom_2), TOLERANCE)
1164
1339
  }
1165
1340
 
@@ -1173,9 +1348,9 @@ class GeometryTests < Minitest::Test
1173
1348
  def test_hausdorff_distance_with_densify_fract
1174
1349
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:hausdorff_distance)
1175
1350
 
1176
- tester = lambda { |expected, g1, g2|
1177
- geom_1 = read(g1)
1178
- geom_2 = read(g2)
1351
+ tester = lambda { |expected, g_1, g_2|
1352
+ geom_1 = read(g_1)
1353
+ geom_2 = read(g_2)
1179
1354
  assert_in_delta(expected, geom_1.hausdorff_distance(geom_2, 0.001), TOLERANCE)
1180
1355
  }
1181
1356
 
@@ -1189,14 +1364,18 @@ class GeometryTests < Minitest::Test
1189
1364
  def test_nearest_points
1190
1365
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:nearest_points)
1191
1366
 
1192
- tester = lambda { |expected, g1, g2|
1193
- geom_1 = read(g1)
1194
- geom_2 = read(g2)
1367
+ tester = lambda { |expected, g_1, g_2|
1368
+ geom_1 = read(g_1)
1369
+ geom_2 = read(g_2)
1195
1370
 
1196
1371
  cs = geom_1.nearest_points(geom_2)
1197
1372
  result = cs.to_s if cs
1198
1373
 
1199
- assert_equal(expected, result)
1374
+ if expected.nil?
1375
+ assert_nil(result)
1376
+ else
1377
+ assert_equal(expected, result)
1378
+ end
1200
1379
  }
1201
1380
 
1202
1381
  tester[
@@ -1206,7 +1385,11 @@ class GeometryTests < Minitest::Test
1206
1385
  ]
1207
1386
 
1208
1387
  tester[
1209
- '5.0 5.0 NaN, 8.0 8.0 NaN',
1388
+ if Geos::GEOS_NICE_VERSION >= '030800'
1389
+ '5.0 5.0, 8.0 8.0'
1390
+ else
1391
+ '5.0 5.0 NaN, 8.0 8.0 NaN'
1392
+ end,
1210
1393
  'POLYGON((1 1, 1 5, 5 5, 5 1, 1 1))',
1211
1394
  'POLYGON((8 8, 9 9, 9 10, 8 8))'
1212
1395
  ]
@@ -1246,6 +1429,41 @@ class GeometryTests < Minitest::Test
1246
1429
  )
1247
1430
  end
1248
1431
 
1432
+ def test_polygonize_with_geometry_arguments
1433
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize)
1434
+
1435
+ geom_a = read('LINESTRING (100 100, 100 300, 300 300, 300 100, 100 100)')
1436
+ geom_b = read('LINESTRING (150 150, 150 250, 250 250, 250 150, 150 150)')
1437
+
1438
+ polygonized = geom_a.polygonize(geom_b)
1439
+ assert_equal(2, polygonized.length)
1440
+ assert_equal(
1441
+ 'POLYGON ((100 100, 100 300, 300 300, 300 100, 100 100), (150 150, 250 150, 250 250, 150 250, 150 150))',
1442
+ write(polygonized[0].snap_to_grid(0.1))
1443
+ )
1444
+ assert_equal(
1445
+ 'POLYGON ((150 150, 150 250, 250 250, 250 150, 150 150))',
1446
+ write(polygonized[1].snap_to_grid(0.1))
1447
+ )
1448
+ end
1449
+
1450
+ def test_polygonize_valid
1451
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_valid)
1452
+
1453
+ geom_a = read(
1454
+ 'GEOMETRYCOLLECTION(
1455
+ LINESTRING (100 100, 100 300, 300 300, 300 100, 100 100),
1456
+ LINESTRING (150 150, 150 250, 250 250, 250 150, 150 150)
1457
+ )'
1458
+ )
1459
+
1460
+ polygonized = geom_a.polygonize_valid
1461
+ assert_equal(
1462
+ 'POLYGON ((100 100, 100 300, 300 300, 300 100, 100 100), (150 150, 250 150, 250 250, 150 250, 150 150))',
1463
+ write(polygonized.snap_to_grid(0.1))
1464
+ )
1465
+ end
1466
+
1249
1467
  def test_polygonize_cut_edges
1250
1468
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_cut_edges)
1251
1469
 
@@ -1267,7 +1485,11 @@ class GeometryTests < Minitest::Test
1267
1485
  def test_polygonize_full
1268
1486
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_full)
1269
1487
 
1270
- writer.rounding_precision = 3
1488
+ writer.rounding_precision = if Geos::GEOS_NICE_VERSION >= '031000'
1489
+ 0
1490
+ else
1491
+ 3
1492
+ end
1271
1493
 
1272
1494
  geom_a = read(
1273
1495
  'GEOMETRYCOLLECTION(
@@ -1338,6 +1560,29 @@ class GeometryTests < Minitest::Test
1338
1560
  end
1339
1561
  end
1340
1562
 
1563
+ def test_build_area
1564
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:build_area)
1565
+
1566
+ geom = read('GEOMETRYCOLLECTION (LINESTRING(0 0, 0 1, 1 1), LINESTRING (1 1, 1 0, 0 0))')
1567
+
1568
+ assert_equal('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))', write(geom.build_area))
1569
+ end
1570
+
1571
+ def test_make_valid
1572
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:make_valid)
1573
+
1574
+ geom = read('POLYGON((0 0, 1 1, 0 1, 1 0, 0 0))')
1575
+
1576
+ assert_equal(
1577
+ if Geos::GEOS_NICE_VERSION > '030900'
1578
+ 'MULTIPOLYGON (((1 0, 0 0, 0.5 0.5, 1 0)), ((1 1, 0.5 0.5, 0 1, 1 1)))'
1579
+ else
1580
+ 'MULTIPOLYGON (((0 0, 0.5 0.5, 1 0, 0 0)), ((0.5 0.5, 0 1, 1 1, 0.5 0.5)))'
1581
+ end,
1582
+ write(geom.make_valid)
1583
+ )
1584
+ end
1585
+
1341
1586
  def test_shared_paths
1342
1587
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:shared_paths)
1343
1588
 
@@ -1393,7 +1638,7 @@ class GeometryTests < Minitest::Test
1393
1638
  geom = read('LINESTRING(0 0, 10 10))')
1394
1639
  assert_kind_of(Enumerable, geom.each)
1395
1640
  assert_kind_of(Enumerable, geom.to_enum)
1396
- assert_equal(geom, geom.each {})
1641
+ assert_equal(geom, geom.each(&EMPTY_BLOCK))
1397
1642
  end
1398
1643
 
1399
1644
  def test_normalize
@@ -1507,7 +1752,7 @@ class GeometryTests < Minitest::Test
1507
1752
  assert_raises(Geos::MixedSRIDsError) do
1508
1753
  Geos.srid_copy_policy = :strict
1509
1754
  geom_c = geom.intersection(geom_b)
1510
- assert_equal(231231, geom_c.srid)
1755
+ assert_equal(231_231, geom_c.srid)
1511
1756
  end
1512
1757
  ensure
1513
1758
  Geos.srid_copy_policy = :default
@@ -1579,7 +1824,9 @@ class GeometryTests < Minitest::Test
1579
1824
 
1580
1825
  # polygon with a hole
1581
1826
  tester[
1582
- 'GEOMETRYCOLLECTION (POLYGON ((8 2, 10 10, 8.5 1, 8 2)), POLYGON ((7 8, 10 10, 8 2, 7 8)), POLYGON ((3 8, 10 10, 7 8, 3 8)), POLYGON ((2 2, 8 2, 8.5 1, 2 2)), POLYGON ((2 2, 7 8, 8 2, 2 2)), POLYGON ((2 2, 3 8, 7 8, 2 2)), POLYGON ((0.5 9, 10 10, 3 8, 0.5 9)), POLYGON ((0.5 9, 3 8, 2 2, 0.5 9)), POLYGON ((0 0, 2 2, 8.5 1, 0 0)), POLYGON ((0 0, 0.5 9, 2 2, 0 0)))',
1827
+ 'GEOMETRYCOLLECTION (POLYGON ((8 2, 10 10, 8.5 1, 8 2)), POLYGON ((7 8, 10 10, 8 2, 7 8)), POLYGON ((3 8, 10 10, 7 8, 3 8)), ' \
1828
+ 'POLYGON ((2 2, 8 2, 8.5 1, 2 2)), POLYGON ((2 2, 7 8, 8 2, 2 2)), POLYGON ((2 2, 3 8, 7 8, 2 2)), POLYGON ((0.5 9, 10 10, 3 8, 0.5 9)), ' \
1829
+ 'POLYGON ((0.5 9, 3 8, 2 2, 0.5 9)), POLYGON ((0 0, 2 2, 8.5 1, 0 0)), POLYGON ((0 0, 0.5 9, 2 2, 0 0)))',
1583
1830
  'POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2)))',
1584
1831
  0
1585
1832
  ]
@@ -1612,7 +1859,14 @@ class GeometryTests < Minitest::Test
1612
1859
 
1613
1860
  geom = 'MULTIPOINT(0 0, 100 0, 100 100, 0 100)'
1614
1861
 
1615
- tester['GEOMETRYCOLLECTION (POLYGON ((50 200, 200 200, 200 50, 50 50, 50 200)), POLYGON ((-100 50, -100 200, 50 200, 50 50, -100 50)), POLYGON ((50 -100, -100 -100, -100 50, 50 50, 50 -100)), POLYGON ((200 50, 200 -100, 50 -100, 50 50, 200 50)))', geom]
1862
+ tester[
1863
+ if Geos::GEOS_NICE_VERSION > '030900'
1864
+ 'GEOMETRYCOLLECTION (POLYGON ((200 200, 200 50, 50 50, 50 200, 200 200)), POLYGON ((-100 200, 50 200, 50 50, -100 50, -100 200)), POLYGON ((-100 -100, -100 50, 50 50, 50 -100, -100 -100)), POLYGON ((200 -100, 50 -100, 50 50, 200 50, 200 -100)))'
1865
+ else
1866
+ 'GEOMETRYCOLLECTION (POLYGON ((50 200, 200 200, 200 50, 50 50, 50 200)), POLYGON ((-100 50, -100 200, 50 200, 50 50, -100 50)), POLYGON ((50 -100, -100 -100, -100 50, 50 50, 50 -100)), POLYGON ((200 50, 200 -100, 50 -100, 50 50, 200 50)))'
1867
+ end,
1868
+ geom
1869
+ ]
1616
1870
 
1617
1871
  tester['MULTILINESTRING ((50 50, 50 200), (200 50, 50 50), (50 50, -100 50), (50 50, 50 -100))', geom, tolerance: 0, only_edges: true]
1618
1872
 
@@ -1622,8 +1876,23 @@ class GeometryTests < Minitest::Test
1622
1876
  ]
1623
1877
 
1624
1878
  # Allows a tolerance for the first argument
1625
- @writer.rounding_precision = 3
1626
- tester['GEOMETRYCOLLECTION (POLYGON ((290 252, 290 140, 185 140, 185 215, 188 235, 290 252)), POLYGON ((80 215, 80 340, 101 340, 188 235, 185 215, 80 215)), POLYGON ((185 140, 80 140, 80 215, 185 215, 185 140)), POLYGON ((101 340, 290 340, 290 252, 188 235, 101 340)))', "MULTIPOINT ((150 210), (210 270), (150 220), (220 210), (215 269))", 10]
1879
+ writer.rounding_precision = if Geos::GEOS_NICE_VERSION >= '031000'
1880
+ 0
1881
+ else
1882
+ 3
1883
+ end
1884
+
1885
+ writer.trim = true
1886
+
1887
+ tester[
1888
+ if Geos::GEOS_NICE_VERSION > '030900'
1889
+ 'GEOMETRYCOLLECTION (POLYGON ((290 140, 185 140, 185 215, 188 235, 290 252, 290 140)), POLYGON ((80 340, 101 340, 188 235, 185 215, 80 215, 80 340)), POLYGON ((80 140, 80 215, 185 215, 185 140, 80 140)), POLYGON ((290 340, 290 252, 188 235, 101 340, 290 340)))'
1890
+ else
1891
+ 'GEOMETRYCOLLECTION (POLYGON ((290 252, 290 140, 185 140, 185 215, 188 235, 290 252)), POLYGON ((80 215, 80 340, 101 340, 188 235, 185 215, 80 215)), POLYGON ((185 140, 80 140, 80 215, 185 215, 185 140)), POLYGON ((101 340, 290 340, 290 252, 188 235, 101 340)))'
1892
+ end,
1893
+ 'MULTIPOINT ((150 210), (210 270), (150 220), (220 210), (215 269))',
1894
+ 10
1895
+ ]
1627
1896
  end
1628
1897
 
1629
1898
  def test_precision
@@ -1696,11 +1965,37 @@ class GeometryTests < Minitest::Test
1696
1965
  tester['LINESTRING (200 200, 200 100)', 'POLYGON ((100 100, 300 100, 200 200, 100 100))']
1697
1966
  tester[
1698
1967
  'LINESTRING (-112.712119 33.575919, -112.712127 33.575885)',
1699
- '0106000000010000000103000000010000001a00000035d42824992d5cc01b834e081dca404073b9c150872d5cc03465a71fd4c940400ec00644882d5cc03b8a73d4d1c94040376dc669882d5cc0bf9cd9aed0c940401363997e892d5cc002f4fbfecdc94040ca4e3fa88b2d5cc0a487a1d5c9c940408f1ce90c8c2d5cc0698995d1c8c94040fab836548c2d5cc0bd175fb4c7c940409f1f46088f2d5cc0962023a0c2c940407b15191d902d5cc068041bd7bfc940400397c79a912d5cc0287d21e4bcc940403201bf46922d5cc065e3c116bbc940409d9d0c8e922d5cc0060fd3beb9c940400ef7915b932d5cc09012bbb6b7c940404fe61f7d932d5cc0e4a08499b6c94040fc71fbe5932d5cc0ea9106b7b5c94040eaec6470942d5cc0c2323674b3c94040601dc70f952d5cc043588d25acc94040aea06989952d5cc03ecf9f36aac94040307f85cc952d5cc0e5eb32fca7c94040dd0a6135962d5cc01b615111a7c9404048a7ae7c962d5cc00a2aaa7ea5c94040f4328ae5962d5cc05eb87361a4c94040c49448a2972d5cc04d81cccea2c940407c80eecb992d5cc06745d4449fc9404035d42824992d5cc01b834e081dca4040'
1968
+ '0106000000010000000103000000010000001a00000035d42824992d5cc01b834e081dca404073b9c150872d5cc03465a71fd4c940400ec00644882d5cc03b8a' \
1969
+ '73d4d1c94040376dc669882d5cc0bf9cd9aed0c940401363997e892d5cc002f4fbfecdc94040ca4e3fa88b2d5cc0a487a1d5c9c940408f1ce90c8c2d5cc06989' \
1970
+ '95d1c8c94040fab836548c2d5cc0bd175fb4c7c940409f1f46088f2d5cc0962023a0c2c940407b15191d902d5cc068041bd7bfc940400397c79a912d5cc0287d' \
1971
+ '21e4bcc940403201bf46922d5cc065e3c116bbc940409d9d0c8e922d5cc0060fd3beb9c940400ef7915b932d5cc09012bbb6b7c940404fe61f7d932d5cc0e4a0' \
1972
+ '8499b6c94040fc71fbe5932d5cc0ea9106b7b5c94040eaec6470942d5cc0c2323674b3c94040601dc70f952d5cc043588d25acc94040aea06989952d5cc03ecf' \
1973
+ '9f36aac94040307f85cc952d5cc0e5eb32fca7c94040dd0a6135962d5cc01b615111a7c9404048a7ae7c962d5cc00a2aaa7ea5c94040f4328ae5962d5cc05eb8' \
1974
+ '7361a4c94040c49448a2972d5cc04d81cccea2c940407c80eecb992d5cc06745d4449fc9404035d42824992d5cc01b834e081dca4040'
1700
1975
  ]
1701
1976
  tester['LINESTRING EMPTY', 'POLYGON EMPTY']
1702
1977
  end
1703
1978
 
1979
+ def test_maximum_inscribed_circle
1980
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:maximum_inscribed_circle)
1981
+
1982
+ geom = read('POLYGON ((100 200, 200 200, 200 100, 100 100, 100 200))')
1983
+ output = geom.maximum_inscribed_circle(0.001)
1984
+ assert_equal('LINESTRING (150 150, 150 200)', write(output))
1985
+ end
1986
+
1987
+ def test_largest_empty_circle
1988
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:largest_empty_circle)
1989
+
1990
+ geom = read('MULTIPOINT ((100 100), (100 200), (200 200), (200 100))')
1991
+ output = geom.largest_empty_circle(0.001)
1992
+ assert_equal('LINESTRING (150 150, 100 100)', write(output))
1993
+
1994
+ geom = read('MULTIPOINT ((100 100), (100 200), (200 200), (200 100))')
1995
+ output = geom.largest_empty_circle(0.001, boundary: read('MULTIPOINT ((100 100), (100 200), (200 200), (200 100))'))
1996
+ assert_equal('LINESTRING (100 100, 100 100)', write(output))
1997
+ end
1998
+
1704
1999
  def test_minimum_width
1705
2000
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:minimum_width)
1706
2001
 
@@ -1767,7 +2062,13 @@ class GeometryTests < Minitest::Test
1767
2062
  simple_tester(:reverse, 'POINT (3 5)', 'POINT (3 5)')
1768
2063
  simple_tester(:reverse, 'MULTIPOINT (100 100, 10 100, 30 100)', 'MULTIPOINT (100 100, 10 100, 30 100)')
1769
2064
  simple_tester(:reverse, 'LINESTRING (200 200, 200 100)', 'LINESTRING (200 100, 200 200)')
1770
- simple_tester(:reverse, 'MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))', 'MULTILINESTRING ((4 4, 3 3), (2 2, 1 1))')
2065
+
2066
+ if Geos::GEOS_NICE_VERSION >= '030801'
2067
+ simple_tester(:reverse, 'MULTILINESTRING ((3 3, 4 4), (1 1, 2 2))', 'MULTILINESTRING ((4 4, 3 3), (2 2, 1 1))')
2068
+ else
2069
+ simple_tester(:reverse, 'MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))', 'MULTILINESTRING ((4 4, 3 3), (2 2, 1 1))')
2070
+ end
2071
+
1771
2072
  simple_tester(:reverse, 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))', 'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))')
1772
2073
  simple_tester(:reverse, 'MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), ((100 100, 100 200, 200 200, 100 100)))', 'MULTIPOLYGON (((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1)), ((100 100, 200 200, 100 200, 100 100)))')
1773
2074
  simple_tester(:reverse, 'GEOMETRYCOLLECTION (LINESTRING (1 1, 2 2), GEOMETRYCOLLECTION (LINESTRING (3 5, 2 9)))', 'GEOMETRYCOLLECTION (LINESTRING (2 2, 1 1), GEOMETRYCOLLECTION(LINESTRING (2 9, 3 5)))')