ffi-geos 2.2.0 → 2.4.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +49 -0
  3. data/.rubocop-minitest.yml +240 -0
  4. data/.rubocop.yml +497 -111
  5. data/.rubocop_todo.yml +100 -0
  6. data/Gemfile +3 -6
  7. data/MIT-LICENSE +1 -1
  8. data/README.rdoc +2 -0
  9. data/ffi-geos.gemspec +5 -0
  10. data/lib/ffi-geos/buffer_params.rb +1 -1
  11. data/lib/ffi-geos/coordinate_sequence.rb +32 -32
  12. data/lib/ffi-geos/geojson_reader.rb +35 -0
  13. data/lib/ffi-geos/geojson_writer.rb +49 -0
  14. data/lib/ffi-geos/geometry.rb +11 -5
  15. data/lib/ffi-geos/geometry_collection.rb +5 -5
  16. data/lib/ffi-geos/line_string.rb +11 -11
  17. data/lib/ffi-geos/multi_line_string.rb +1 -1
  18. data/lib/ffi-geos/point.rb +4 -4
  19. data/lib/ffi-geos/polygon.rb +5 -5
  20. data/lib/ffi-geos/prepared_geometry.rb +21 -1
  21. data/lib/ffi-geos/strtree.rb +1 -1
  22. data/lib/ffi-geos/version.rb +1 -1
  23. data/lib/ffi-geos/wkb_reader.rb +1 -1
  24. data/lib/ffi-geos/wkb_writer.rb +14 -2
  25. data/lib/ffi-geos/wkt_reader.rb +1 -1
  26. data/lib/ffi-geos/wkt_writer.rb +2 -2
  27. data/lib/ffi-geos.rb +92 -4
  28. data/sonar-project.properties +4 -4
  29. data/test/coordinate_sequence_tests.rb +6 -6
  30. data/test/geojson_reader_tests.rb +170 -0
  31. data/test/geojson_writer_tests.rb +103 -0
  32. data/test/geometry_collection_tests.rb +4 -4
  33. data/test/geometry_tests.rb +75 -32
  34. data/test/line_string_tests.rb +13 -5
  35. data/test/point_tests.rb +3 -3
  36. data/test/polygon_tests.rb +3 -3
  37. data/test/prepared_geometry_tests.rb +30 -0
  38. data/test/strtree_tests.rb +8 -8
  39. data/test/test_helper.rb +43 -12
  40. data/test/wkb_writer_tests.rb +20 -0
  41. metadata +15 -6
  42. data/.travis.yml +0 -32
@@ -13,7 +13,7 @@ class GeometryTests < Minitest::Test
13
13
  def test_intersection
14
14
  comparison_tester(
15
15
  :intersection,
16
- if Geos::GEOS_VERSION > '3.9.0'
16
+ if Geos::GEOS_NICE_VERSION > '030900'
17
17
  'POLYGON ((10 10, 10 5, 5 5, 5 10, 10 10))'
18
18
  else
19
19
  'POLYGON ((5 10, 10 10, 10 5, 5 5, 5 10))'
@@ -36,7 +36,11 @@ class GeometryTests < Minitest::Test
36
36
 
37
37
  comparison_tester(
38
38
  :intersection,
39
- 'GEOMETRYCOLLECTION (LINESTRING (2 0, 4 0), POINT (0 0), POINT (10 0))',
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,
40
44
  'LINESTRING(0 0, 10 0)',
41
45
  'LINESTRING(9 0, 12 0, 12 20, 4 0, 2 0, 2 10, 0 10, 0 -10)',
42
46
  precision: 2
@@ -119,7 +123,11 @@ class GeometryTests < Minitest::Test
119
123
 
120
124
  snapped_tester(
121
125
  :buffer,
122
- '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,
123
131
  'LINESTRING(0 0, 100 0, 100 100)',
124
132
  10,
125
133
  quad_segs: 2, join: :mitre, mitre_limit: 1.0
@@ -206,7 +214,7 @@ class GeometryTests < Minitest::Test
206
214
 
207
215
  comparison_tester(
208
216
  :difference,
209
- if Geos::GEOS_VERSION > '3.9.0'
217
+ if Geos::GEOS_NICE_VERSION > '030900'
210
218
  'POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10))'
211
219
  else
212
220
  'POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0))'
@@ -217,7 +225,7 @@ class GeometryTests < Minitest::Test
217
225
 
218
226
  comparison_tester(
219
227
  :difference,
220
- if Geos::GEOS_VERSION > '3.9.0'
228
+ if Geos::GEOS_NICE_VERSION > '030900'
221
229
  'POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10))'
222
230
  else
223
231
  'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))'
@@ -228,7 +236,7 @@ class GeometryTests < Minitest::Test
228
236
 
229
237
  comparison_tester(
230
238
  :difference,
231
- if Geos::GEOS_VERSION > '3.9.0'
239
+ if Geos::GEOS_NICE_VERSION > '030900'
232
240
  'POLYGON ((0 10, 10 10, 10 5, 5 5, 5 0, 0 0, 0 10))'
233
241
  else
234
242
  'POLYGON ((0 0, 0 10, 10 10, 10 5, 5 5, 5 0, 0 0))'
@@ -303,7 +311,7 @@ class GeometryTests < Minitest::Test
303
311
 
304
312
  comparison_tester(
305
313
  method,
306
- if Geos::GEOS_VERSION > '3.9.0'
314
+ if Geos::GEOS_NICE_VERSION > '030900'
307
315
  'GEOMETRYCOLLECTION (POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10)), LINESTRING (5 -10, 5 0))'
308
316
  else
309
317
  'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0)))'
@@ -314,7 +322,7 @@ class GeometryTests < Minitest::Test
314
322
 
315
323
  comparison_tester(
316
324
  method,
317
- if Geos::GEOS_VERSION > '3.9.0'
325
+ if Geos::GEOS_NICE_VERSION > '030900'
318
326
  'GEOMETRYCOLLECTION (POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10)), LINESTRING (10 0, 20 0))'
319
327
  else
320
328
  'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0)))'
@@ -325,7 +333,7 @@ class GeometryTests < Minitest::Test
325
333
 
326
334
  comparison_tester(
327
335
  method,
328
- if Geos::GEOS_VERSION > '3.9.0'
336
+ if Geos::GEOS_NICE_VERSION > '030900'
329
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)))'
330
338
  else
331
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)))'
@@ -420,7 +428,7 @@ class GeometryTests < Minitest::Test
420
428
 
421
429
  comparison_tester(
422
430
  :union,
423
- if Geos::GEOS_VERSION > '3.9.0'
431
+ if Geos::GEOS_NICE_VERSION > '030900'
424
432
  'GEOMETRYCOLLECTION (POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10)), LINESTRING (5 -10, 5 0))'
425
433
  else
426
434
  'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0)))'
@@ -431,7 +439,7 @@ class GeometryTests < Minitest::Test
431
439
 
432
440
  comparison_tester(
433
441
  :union,
434
- if Geos::GEOS_VERSION > '3.9.0'
442
+ if Geos::GEOS_NICE_VERSION > '030900'
435
443
  'GEOMETRYCOLLECTION (POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10)), LINESTRING (10 0, 20 0))'
436
444
  else
437
445
  'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0)))'
@@ -442,7 +450,7 @@ class GeometryTests < Minitest::Test
442
450
 
443
451
  comparison_tester(
444
452
  :union,
445
- if Geos::GEOS_VERSION > '3.9.0'
453
+ if Geos::GEOS_NICE_VERSION > '030900'
446
454
  'POLYGON ((0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0, 0 0, 0 10))'
447
455
  else
448
456
  'POLYGON ((0 0, 0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0, 0 0))'
@@ -468,7 +476,7 @@ class GeometryTests < Minitest::Test
468
476
 
469
477
  simple_tester(
470
478
  :union_cascaded,
471
- if Geos::GEOS_VERSION > '3.9.0'
479
+ if Geos::GEOS_NICE_VERSION > '030900'
472
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))'
473
481
  else
474
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))'
@@ -487,7 +495,7 @@ class GeometryTests < Minitest::Test
487
495
 
488
496
  simple_tester(
489
497
  :union_cascaded,
490
- if Geos::GEOS_VERSION > '3.9.0'
498
+ if Geos::GEOS_NICE_VERSION > '030900'
491
499
  'POLYGON ((0 1, 1 1, 2 1, 2 0, 1 0, 0 0, 0 1))'
492
500
  else
493
501
  'POLYGON ((0 0, 0 1, 1 1, 2 1, 2 0, 1 0, 0 0))'
@@ -504,7 +512,7 @@ class GeometryTests < Minitest::Test
504
512
 
505
513
  simple_tester(
506
514
  :unary_union,
507
- if Geos::GEOS_VERSION > '3.9.0'
515
+ if Geos::GEOS_NICE_VERSION > '030900'
508
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))'
509
517
  else
510
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))'
@@ -547,7 +555,7 @@ class GeometryTests < Minitest::Test
547
555
  def test_union_without_arguments
548
556
  simple_tester(
549
557
  :union,
550
- if Geos::GEOS_VERSION > '3.9.0'
558
+ if Geos::GEOS_NICE_VERSION > '030900'
551
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))'
552
560
  else
553
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))'
@@ -955,7 +963,13 @@ class GeometryTests < Minitest::Test
955
963
  }
956
964
 
957
965
  assert_nil(read('POINT(0 0)').valid_detail)
958
- 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
+
959
973
  tester['Self-intersection', 'POINT (2.5 5)', 'POLYGON((0 0, 0 5, 5 5, 5 10, 0 0))', 0]
960
974
 
961
975
  tester['Ring Self-intersection', 'POINT (0 0)', 'POLYGON((0 0, -10 10, 10 10, 0 0, 4 5, -4 5, 0 0)))', 0]
@@ -1371,7 +1385,7 @@ class GeometryTests < Minitest::Test
1371
1385
  ]
1372
1386
 
1373
1387
  tester[
1374
- if Geos::GEOS_VERSION > '3.8'
1388
+ if Geos::GEOS_NICE_VERSION >= '030800'
1375
1389
  '5.0 5.0, 8.0 8.0'
1376
1390
  else
1377
1391
  '5.0 5.0 NaN, 8.0 8.0 NaN'
@@ -1471,7 +1485,11 @@ class GeometryTests < Minitest::Test
1471
1485
  def test_polygonize_full
1472
1486
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_full)
1473
1487
 
1474
- writer.rounding_precision = 3
1488
+ writer.rounding_precision = if Geos::GEOS_NICE_VERSION >= '031000'
1489
+ 0
1490
+ else
1491
+ 3
1492
+ end
1475
1493
 
1476
1494
  geom_a = read(
1477
1495
  'GEOMETRYCOLLECTION(
@@ -1556,7 +1574,7 @@ class GeometryTests < Minitest::Test
1556
1574
  geom = read('POLYGON((0 0, 1 1, 0 1, 1 0, 0 0))')
1557
1575
 
1558
1576
  assert_equal(
1559
- if Geos::GEOS_VERSION > '3.9.0'
1577
+ if Geos::GEOS_NICE_VERSION > '030900'
1560
1578
  'MULTIPOLYGON (((1 0, 0 0, 0.5 0.5, 1 0)), ((1 1, 0.5 0.5, 0 1, 1 1)))'
1561
1579
  else
1562
1580
  'MULTIPOLYGON (((0 0, 0.5 0.5, 1 0, 0 0)), ((0.5 0.5, 0 1, 1 1, 0.5 0.5)))'
@@ -1807,8 +1825,8 @@ class GeometryTests < Minitest::Test
1807
1825
  # polygon with a hole
1808
1826
  tester[
1809
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)), ' \
1810
- '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)), ' \
1811
- '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)))',
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)))',
1812
1830
  'POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2)))',
1813
1831
  0
1814
1832
  ]
@@ -1827,6 +1845,24 @@ class GeometryTests < Minitest::Test
1827
1845
  tester['MULTILINESTRING ((10 0, 10 10), (0 0, 10 10), (0 0, 10 0))', 'MULTIPOINT(0 0, 10 0, 10 10, 11 10)', tolerance: 2.0, only_edges: true]
1828
1846
  end
1829
1847
 
1848
+ def test_constrained_delaunay_triangulation
1849
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:constrained_delaunay_triangulation)
1850
+
1851
+ tester = lambda { |expected, geom|
1852
+ geom = read(geom)
1853
+ geom_tri = geom.constrained_delaunay_triangulation
1854
+ geom_tri.normalize!
1855
+
1856
+ assert_equal(write(read(expected).normalize), write(geom_tri))
1857
+ }
1858
+
1859
+ writer.trim = true
1860
+
1861
+ tester['GEOMETRYCOLLECTION EMPTY', 'POLYGON EMPTY']
1862
+ tester['GEOMETRYCOLLECTION EMPTY', 'POINT(0 0)']
1863
+ tester['GEOMETRYCOLLECTION (POLYGON ((10 10, 20 40, 90 10, 10 10)), POLYGON ((90 90, 20 40, 90 10, 90 90)))', 'POLYGON ((10 10, 20 40, 90 90, 90 10, 10 10))']
1864
+ end
1865
+
1830
1866
  def test_voronoi_diagram
1831
1867
  skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:voronoi_diagram)
1832
1868
 
@@ -1842,7 +1878,7 @@ class GeometryTests < Minitest::Test
1842
1878
  geom = 'MULTIPOINT(0 0, 100 0, 100 100, 0 100)'
1843
1879
 
1844
1880
  tester[
1845
- if Geos::GEOS_VERSION > '3.9.0'
1881
+ if Geos::GEOS_NICE_VERSION > '030900'
1846
1882
  '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)))'
1847
1883
  else
1848
1884
  '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)))'
@@ -1858,9 +1894,16 @@ class GeometryTests < Minitest::Test
1858
1894
  ]
1859
1895
 
1860
1896
  # Allows a tolerance for the first argument
1861
- @writer.rounding_precision = 3
1897
+ writer.rounding_precision = if Geos::GEOS_NICE_VERSION >= '031000'
1898
+ 0
1899
+ else
1900
+ 3
1901
+ end
1902
+
1903
+ writer.trim = true
1904
+
1862
1905
  tester[
1863
- if Geos::GEOS_VERSION > '3.9.0'
1906
+ if Geos::GEOS_NICE_VERSION > '030900'
1864
1907
  '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)))'
1865
1908
  else
1866
1909
  '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)))'
@@ -1941,12 +1984,12 @@ class GeometryTests < Minitest::Test
1941
1984
  tester[
1942
1985
  'LINESTRING (-112.712119 33.575919, -112.712127 33.575885)',
1943
1986
  '0106000000010000000103000000010000001a00000035d42824992d5cc01b834e081dca404073b9c150872d5cc03465a71fd4c940400ec00644882d5cc03b8a' \
1944
- '73d4d1c94040376dc669882d5cc0bf9cd9aed0c940401363997e892d5cc002f4fbfecdc94040ca4e3fa88b2d5cc0a487a1d5c9c940408f1ce90c8c2d5cc06989' \
1945
- '95d1c8c94040fab836548c2d5cc0bd175fb4c7c940409f1f46088f2d5cc0962023a0c2c940407b15191d902d5cc068041bd7bfc940400397c79a912d5cc0287d' \
1946
- '21e4bcc940403201bf46922d5cc065e3c116bbc940409d9d0c8e922d5cc0060fd3beb9c940400ef7915b932d5cc09012bbb6b7c940404fe61f7d932d5cc0e4a0' \
1947
- '8499b6c94040fc71fbe5932d5cc0ea9106b7b5c94040eaec6470942d5cc0c2323674b3c94040601dc70f952d5cc043588d25acc94040aea06989952d5cc03ecf' \
1948
- '9f36aac94040307f85cc952d5cc0e5eb32fca7c94040dd0a6135962d5cc01b615111a7c9404048a7ae7c962d5cc00a2aaa7ea5c94040f4328ae5962d5cc05eb8' \
1949
- '7361a4c94040c49448a2972d5cc04d81cccea2c940407c80eecb992d5cc06745d4449fc9404035d42824992d5cc01b834e081dca4040'
1987
+ '73d4d1c94040376dc669882d5cc0bf9cd9aed0c940401363997e892d5cc002f4fbfecdc94040ca4e3fa88b2d5cc0a487a1d5c9c940408f1ce90c8c2d5cc06989' \
1988
+ '95d1c8c94040fab836548c2d5cc0bd175fb4c7c940409f1f46088f2d5cc0962023a0c2c940407b15191d902d5cc068041bd7bfc940400397c79a912d5cc0287d' \
1989
+ '21e4bcc940403201bf46922d5cc065e3c116bbc940409d9d0c8e922d5cc0060fd3beb9c940400ef7915b932d5cc09012bbb6b7c940404fe61f7d932d5cc0e4a0' \
1990
+ '8499b6c94040fc71fbe5932d5cc0ea9106b7b5c94040eaec6470942d5cc0c2323674b3c94040601dc70f952d5cc043588d25acc94040aea06989952d5cc03ecf' \
1991
+ '9f36aac94040307f85cc952d5cc0e5eb32fca7c94040dd0a6135962d5cc01b615111a7c9404048a7ae7c962d5cc00a2aaa7ea5c94040f4328ae5962d5cc05eb8' \
1992
+ '7361a4c94040c49448a2972d5cc04d81cccea2c940407c80eecb992d5cc06745d4449fc9404035d42824992d5cc01b834e081dca4040'
1950
1993
  ]
1951
1994
  tester['LINESTRING EMPTY', 'POLYGON EMPTY']
1952
1995
  end
@@ -2038,7 +2081,7 @@ class GeometryTests < Minitest::Test
2038
2081
  simple_tester(:reverse, 'MULTIPOINT (100 100, 10 100, 30 100)', 'MULTIPOINT (100 100, 10 100, 30 100)')
2039
2082
  simple_tester(:reverse, 'LINESTRING (200 200, 200 100)', 'LINESTRING (200 100, 200 200)')
2040
2083
 
2041
- if Geos::GEOS_VERSION >= '3.8.1'
2084
+ if Geos::GEOS_NICE_VERSION >= '030801'
2042
2085
  simple_tester(:reverse, 'MULTILINESTRING ((3 3, 4 4), (1 1, 2 2))', 'MULTILINESTRING ((4 4, 3 3), (2 2, 1 1))')
2043
2086
  else
2044
2087
  simple_tester(:reverse, 'MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))', 'MULTILINESTRING ((4 4, 3 3), (2 2, 1 1))')
@@ -80,7 +80,11 @@ class LineStringTests < Minitest::Test
80
80
  # straight right
81
81
  simple_tester(
82
82
  :offset_curve,
83
- 'LINESTRING (10 -2, 0 -2)',
83
+ if Geos::GEOS_NICE_VERSION >= '031100'
84
+ 'LINESTRING (0 -2, 10 -2)'
85
+ else
86
+ 'LINESTRING (10 -2, 0 -2)'
87
+ end,
84
88
  'LINESTRING (0 0, 10 0)',
85
89
  -2,
86
90
  quad_segs: 0,
@@ -91,7 +95,11 @@ class LineStringTests < Minitest::Test
91
95
  # outside curve
92
96
  simple_tester(
93
97
  :offset_curve,
94
- 'LINESTRING (12 10, 12 0, 10 -2, 0 -2)',
98
+ if Geos::GEOS_NICE_VERSION >= '031100'
99
+ 'LINESTRING (0 -2, 10 -2, 12 0, 12 10)'
100
+ else
101
+ 'LINESTRING (12 10, 12 0, 10 -2, 0 -2)'
102
+ end,
95
103
  'LINESTRING (0 0, 10 0, 10 10)',
96
104
  -2,
97
105
  quad_segs: 1,
@@ -264,7 +272,7 @@ class LineStringTests < Minitest::Test
264
272
 
265
273
  affine_tester(:rotate_x, 'LINESTRING Z (1 -1 -1, 10 -10 -10)', wkt, Math::PI)
266
274
  affine_tester(:rotate_x, 'LINESTRING Z (1 -1 1, 10 -10 10)', wkt, Math::PI / 2)
267
- affine_tester(:rotate_x, 'LINESTRING Z (1 1 -1, 10 10 -10)', wkt, Math::PI + Math::PI / 2)
275
+ affine_tester(:rotate_x, 'LINESTRING Z (1 1 -1, 10 10 -10)', wkt, Math::PI + (Math::PI / 2))
268
276
  affine_tester(:rotate_x, wkt, wkt, Math::PI * 2)
269
277
  end
270
278
 
@@ -276,7 +284,7 @@ class LineStringTests < Minitest::Test
276
284
 
277
285
  affine_tester(:rotate_y, 'LINESTRING Z (-1 1 -1, -10 10 -10)', wkt, Math::PI)
278
286
  affine_tester(:rotate_y, 'LINESTRING Z (1 1 -1, 10 10 -10)', wkt, Math::PI / 2)
279
- affine_tester(:rotate_y, 'LINESTRING Z (-1 1 1, -10 10 10)', wkt, Math::PI + Math::PI / 2)
287
+ affine_tester(:rotate_y, 'LINESTRING Z (-1 1 1, -10 10 10)', wkt, Math::PI + (Math::PI / 2))
280
288
  affine_tester(:rotate_y, wkt, wkt, Math::PI * 2)
281
289
  end
282
290
 
@@ -287,7 +295,7 @@ class LineStringTests < Minitest::Test
287
295
 
288
296
  affine_tester(:rotate_z, 'LINESTRING (-1 -1, -10 -10)', wkt, Math::PI)
289
297
  affine_tester(:rotate_z, 'LINESTRING (-1 1, -10 10)', wkt, Math::PI / 2)
290
- affine_tester(:rotate_z, 'LINESTRING (1 -1, 10 -10)', wkt, Math::PI + Math::PI / 2)
298
+ affine_tester(:rotate_z, 'LINESTRING (1 -1, 10 -10)', wkt, Math::PI + (Math::PI / 2))
291
299
  affine_tester(:rotate_z, wkt, wkt, Math::PI * 2)
292
300
  end
293
301
 
data/test/point_tests.rb CHANGED
@@ -177,7 +177,7 @@ class PointTests < Minitest::Test
177
177
 
178
178
  affine_tester(:rotate_x, 'POINT Z (1 -1 -1)', wkt, Math::PI)
179
179
  affine_tester(:rotate_x, 'POINT Z (1 -1 1)', wkt, Math::PI / 2)
180
- affine_tester(:rotate_x, 'POINT Z (1 1 -1)', wkt, Math::PI + Math::PI / 2)
180
+ affine_tester(:rotate_x, 'POINT Z (1 1 -1)', wkt, Math::PI + (Math::PI / 2))
181
181
  affine_tester(:rotate_x, wkt, wkt, Math::PI * 2)
182
182
  end
183
183
 
@@ -189,7 +189,7 @@ class PointTests < Minitest::Test
189
189
 
190
190
  affine_tester(:rotate_y, 'POINT Z (-1 1 -1)', wkt, Math::PI)
191
191
  affine_tester(:rotate_y, 'POINT Z (1 1 -1)', wkt, Math::PI / 2)
192
- affine_tester(:rotate_y, 'POINT Z (-1 1 1)', wkt, Math::PI + Math::PI / 2)
192
+ affine_tester(:rotate_y, 'POINT Z (-1 1 1)', wkt, Math::PI + (Math::PI / 2))
193
193
  affine_tester(:rotate_y, wkt, wkt, Math::PI * 2)
194
194
  end
195
195
 
@@ -200,7 +200,7 @@ class PointTests < Minitest::Test
200
200
 
201
201
  affine_tester(:rotate_z, 'POINT (-1 -1)', wkt, Math::PI)
202
202
  affine_tester(:rotate_z, 'POINT (-1 1)', wkt, Math::PI / 2)
203
- affine_tester(:rotate_z, 'POINT (1 -1)', wkt, Math::PI + Math::PI / 2)
203
+ affine_tester(:rotate_z, 'POINT (1 -1)', wkt, Math::PI + (Math::PI / 2))
204
204
  affine_tester(:rotate_z, wkt, wkt, Math::PI * 2)
205
205
  end
206
206
 
@@ -147,7 +147,7 @@ class PolygonTests < Minitest::Test
147
147
  affine_tester(:rotate_x,
148
148
  'POLYGON Z ((0 0 0, 5 0 0, 5 0 -5, 0 0 -5, 0 0 0))',
149
149
  wkt,
150
- Math::PI + Math::PI / 2)
150
+ Math::PI + (Math::PI / 2))
151
151
 
152
152
  affine_tester(:rotate_x,
153
153
  wkt,
@@ -173,7 +173,7 @@ class PolygonTests < Minitest::Test
173
173
  affine_tester(:rotate_y,
174
174
  'POLYGON Z ((0 0 0, 0 0 5, 0 5 5, 0 5 0, 0 0 0))',
175
175
  wkt,
176
- Math::PI + Math::PI / 2)
176
+ Math::PI + (Math::PI / 2))
177
177
 
178
178
  affine_tester(:rotate_y,
179
179
  wkt,
@@ -195,7 +195,7 @@ class PolygonTests < Minitest::Test
195
195
  affine_tester(:rotate_z,
196
196
  'POLYGON ((0 0, 0 -5, 5 -5, 5 0, 0 0))',
197
197
  'POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))',
198
- Math::PI + Math::PI / 2)
198
+ Math::PI + (Math::PI / 2))
199
199
 
200
200
  affine_tester(:rotate_z,
201
201
  'POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0))',
@@ -70,6 +70,12 @@ class PreparedGeometryTests < Minitest::Test
70
70
  relationship_tester(:contains?, true, false, false, false, false, true, false, false)
71
71
  end
72
72
 
73
+ def test_contains_properly
74
+ skip unless ENV['FORCE_TESTS'] || defined?(Geos::PreparedGeometry)
75
+
76
+ relationship_tester(:contains_properly?, true, false, false, false, false, false, false, false)
77
+ end
78
+
73
79
  def test_overlaps
74
80
  skip unless ENV['FORCE_TESTS'] || defined?(Geos::PreparedGeometry)
75
81
 
@@ -111,4 +117,28 @@ class PreparedGeometryTests < Minitest::Test
111
117
  Geos::PreparedGeometry.new('hello world')
112
118
  end
113
119
  end
120
+
121
+ def test_distance
122
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::PreparedGeometry) && Geos::FFIGeos.respond_to?(:GEOSPreparedDistance_r))
123
+
124
+ assert_equal(5.0, read(POINT_A).to_prepared.distance(read(POINT_B)))
125
+ end
126
+
127
+ def test_distance_within
128
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::PreparedGeometry) && Geos::FFIGeos.respond_to?(:GEOSPreparedDistanceWithin_r))
129
+
130
+ assert(read(POINT_A).to_prepared.distance_within?(read(POINT_B), 30.0))
131
+ refute(read(POINT_A).to_prepared.distance_within?(read(POINT_B), 3.0))
132
+ end
133
+
134
+ def test_nearest_points
135
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::PreparedGeometry) && Geos::FFIGeos.respond_to?(:GEOSPreparedNearestPoints_r))
136
+
137
+ coord_seq = read('POLYGON((1 1, 1 5, 5 5, 5 1, 1 1))').to_prepared.nearest_points(read('POLYGON((8 8, 9 9, 9 10, 8 8))'))
138
+
139
+ assert_equal(5.0, coord_seq.x[0])
140
+ assert_equal(5.0, coord_seq.y[0])
141
+ assert_equal(8.0, coord_seq.x[1])
142
+ assert_equal(8.0, coord_seq.y[1])
143
+ end
114
144
  end
@@ -233,7 +233,7 @@ class STRtreeTests < Minitest::Test
233
233
  end
234
234
 
235
235
  def test_nearest
236
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
236
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
237
237
 
238
238
  geom_1 = read('POINT (3 3)')
239
239
  geom_2 = read('POINT (2 7)')
@@ -250,7 +250,7 @@ class STRtreeTests < Minitest::Test
250
250
  end
251
251
 
252
252
  def test_nearest_with_depth
253
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
253
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
254
254
 
255
255
  number_of_geoms = 100
256
256
  geoms = []
@@ -284,7 +284,7 @@ class STRtreeTests < Minitest::Test
284
284
  end
285
285
 
286
286
  def test_nearest_with_empty_tree
287
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
287
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
288
288
 
289
289
  tree = Geos::STRtree.new(10)
290
290
  geom_1 = read('POINT (3 3)')
@@ -294,7 +294,7 @@ class STRtreeTests < Minitest::Test
294
294
  end
295
295
 
296
296
  def test_nearest_with_some_empty_geometries
297
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
297
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
298
298
 
299
299
  geom_1 = read('LINESTRING EMPTY')
300
300
  geom_2 = read('POINT (2 7)')
@@ -312,8 +312,8 @@ class STRtreeTests < Minitest::Test
312
312
  end
313
313
 
314
314
  def test_nearest_with_only_empty_geometries
315
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
316
- skip if Geos::GEOS_VERSION > '3.9.0'
315
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
316
+ skip if Geos::GEOS_NICE_VERSION > '030900'
317
317
 
318
318
  geom_1 = read('LINESTRING EMPTY')
319
319
  geom_2 = read('POINT (2 7)')
@@ -327,7 +327,7 @@ class STRtreeTests < Minitest::Test
327
327
  end
328
328
 
329
329
  def test_disallowed_inserts_on_nearest
330
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest)
330
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest))
331
331
 
332
332
  setup_tree
333
333
 
@@ -339,7 +339,7 @@ class STRtreeTests < Minitest::Test
339
339
  end
340
340
 
341
341
  def test_nearest_item
342
- skip unless ENV['FORCE_TESTS'] || defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest_item)
342
+ skip unless ENV['FORCE_TESTS'] || (defined?(Geos::STRtree) && Geos::STRtree.method_defined?(:nearest_item))
343
343
 
344
344
  geom_1 = read('POINT (3 3)')
345
345
  geom_2 = read('POINT (2 7)')
data/test/test_helper.rb CHANGED
@@ -9,6 +9,12 @@ SimpleCov.start do
9
9
  add_filter '/.bundle/'
10
10
  end
11
11
 
12
+ if ENV['CI']
13
+ require 'simplecov_json_formatter'
14
+
15
+ SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
16
+ end
17
+
12
18
  require 'rubygems'
13
19
  require 'minitest/autorun'
14
20
  require 'minitest/reporters'
@@ -23,25 +29,26 @@ puts "Ruby version #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} - #{RbConfig::CONFIG['RUB
23
29
  puts "ffi version #{Gem.loaded_specs['ffi'].version}" if Gem.loaded_specs['ffi']
24
30
 
25
31
  if Geos.respond_to?(:version)
26
- puts "GEOS version #{Geos.version}"
32
+ puts "GEOS version #{Geos.version} (#{Geos::GEOS_NICE_VERSION})"
27
33
  else
28
- puts "GEOS version #{Geos::GEOS_VERSION}"
34
+ puts "GEOS version #{Geos::GEOS_VERSION} (#{Geos::GEOS_NICE_VERSION})"
29
35
  end
30
36
 
31
37
  puts "ffi-geos version #{Geos::VERSION}" if defined?(Geos::VERSION)
32
38
  puts "Using #{Geos::FFIGeos.geos_library_path}" if defined?(Geos::FFIGeos)
39
+ puts "Process #{$PID}"
33
40
 
34
41
  module TestHelper
35
42
  TOLERANCE = 0.0000000000001
36
43
 
37
- EMPTY_GEOMETRY = if Geos::GEOS_VERSION > '3.8'
44
+ EMPTY_GEOMETRY = if Geos::GEOS_NICE_VERSION >= '030800'
38
45
  'POINT EMPTY'
39
46
  else
40
47
  'GEOMETRYCOLLECTION EMPTY'
41
48
  end
42
49
 
43
50
  EMPTY_BLOCK = proc do
44
- nil
51
+ # no-op
45
52
  end
46
53
 
47
54
  def self.included(base)
@@ -81,7 +88,8 @@ module TestHelper
81
88
  geom = read(wkt)
82
89
  geom.srid = 4326
83
90
  Geos.srid_copy_policy = srid_policy
84
- geom_b = geom.send(method, *args, **options)
91
+
92
+ geom_b = geom.__safe_send__(method, *args, **options)
85
93
  assert_equal(4326, geom.srid)
86
94
  assert_equal(expected_srid, geom_b.srid)
87
95
  assert_equal(expected, write(geom_b))
@@ -115,13 +123,14 @@ module TestHelper
115
123
  def snapped_tester(method, expected, geom, *args, **options)
116
124
  geom = geom_from_geom_or_wkt(geom)
117
125
 
118
- result = geom.send(method, *args, **options)
126
+ result = geom.__safe_send__(method, *args, **options)
119
127
  assert_equal(expected, write(result.snap_to_grid(1)))
120
128
  end
121
129
 
122
130
  def simple_tester(method, expected, geom, *args, **options)
123
131
  geom = geom_from_geom_or_wkt(geom)
124
- result = geom.send(method, *args, **options)
132
+
133
+ result = geom.__safe_send__(method, *args, **options)
125
134
  result = write(result) if result.is_a?(Geos::Geometry)
126
135
 
127
136
  if expected.nil?
@@ -133,13 +142,13 @@ module TestHelper
133
142
 
134
143
  def simple_bang_tester(method, expected, wkt, *args, **options)
135
144
  geom = read(wkt)
136
- result = geom.send(method, *args, **options)
145
+ result = geom.__safe_send__(method, *args, **options)
137
146
 
138
147
  assert_equal(wkt, write(geom))
139
148
  assert_equal(expected, write(result))
140
149
 
141
150
  geom = read(wkt)
142
- geom.send("#{method}!", *args, **options)
151
+ geom.__safe_send__("#{method}!", *args, **options)
143
152
 
144
153
  assert_equal(expected, write(geom))
145
154
  end
@@ -153,7 +162,7 @@ module TestHelper
153
162
 
154
163
  def array_tester(method, expected, geom, *args, **options)
155
164
  geom = geom_from_geom_or_wkt(geom)
156
- result = geom.send(method, *args, **options)
165
+ result = geom.__safe_send__(method, *args, **options)
157
166
 
158
167
  case result
159
168
  when Geos::Geometry
@@ -171,16 +180,38 @@ module TestHelper
171
180
  writer.trim = true
172
181
 
173
182
  geom = read(wkt)
174
- geom.send("#{method}!", *args, **options).snap_to_grid!(0.1)
183
+ geom.__safe_send__("#{method}!", *args, **options).snap_to_grid!(0.1)
175
184
 
176
185
  assert_equal(expected, write(geom))
177
186
 
178
187
  geom = read(wkt)
179
- geom_2 = geom.send(method, *args, **options).snap_to_grid(0.1)
188
+ geom_2 = geom.__safe_send__(method, *args, **options).snap_to_grid(0.1)
180
189
 
181
190
  assert_equal(wkt, write(geom))
182
191
  assert_equal(expected, write(geom_2, trim: true))
183
192
  end
184
193
  end
185
194
 
195
+ class Object
196
+ if RUBY_VERSION >= '2.7'
197
+ def __safe_send__(method_name, *args, **kwargs)
198
+ send(method_name, *args, **kwargs)
199
+ end
200
+ else
201
+ def __safe_send__(method_name, *args, **kwargs)
202
+ raise NoMethodError unless respond_to?(method_name)
203
+
204
+ arity = method(method_name).arity
205
+
206
+ if arity.zero?
207
+ send(method_name)
208
+ elsif arity.negative? && !kwargs.empty?
209
+ send(method_name, *args, **kwargs)
210
+ else
211
+ send(method_name, *args)
212
+ end
213
+ end
214
+ end
215
+ end
216
+
186
217
  Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
@@ -466,4 +466,24 @@ class WkbWriterTests < Minitest::Test
466
466
  @wkb_writer.output_dimensions = 0
467
467
  end
468
468
  end
469
+
470
+ def test_wkb_flavor_extended
471
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSWKBWriter_setFlavor_r)
472
+
473
+ @wkb_writer.output_dimensions = 3
474
+ @wkb_writer.flavor = :extended
475
+
476
+ assert_equal('010200008003000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000002240',
477
+ @wkb_writer.write_hex(read('LINESTRING Z (1 2 3, 4 5 6, 7 8 9)')))
478
+ end
479
+
480
+ def test_wkb_flavor_iso
481
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSWKBWriter_setFlavor_r)
482
+
483
+ @wkb_writer.output_dimensions = 3
484
+ @wkb_writer.flavor = :iso
485
+
486
+ assert_equal('01EA03000003000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000002240',
487
+ @wkb_writer.write_hex(read('LINESTRING Z (1 2 3, 4 5 6, 7 8 9)')))
488
+ end
469
489
  end