ffi-geos 2.3.1 → 2.5.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +2 -2
  3. data/.rbenv-vars +1 -0
  4. data/.rubocop-minitest.yml +40 -17
  5. data/.rubocop.yml +664 -120
  6. data/.rubocop_todo.yml +30 -19
  7. data/MIT-LICENSE +1 -1
  8. data/README.rdoc +2 -0
  9. data/ffi-geos.gemspec +2 -2
  10. data/lib/ffi-geos/coordinate_sequence.rb +2 -1
  11. data/lib/ffi-geos/geojson_reader.rb +35 -0
  12. data/lib/ffi-geos/geojson_writer.rb +49 -0
  13. data/lib/ffi-geos/geometry.rb +101 -1
  14. data/lib/ffi-geos/geometry_collection.rb +1 -1
  15. data/lib/ffi-geos/line_string.rb +1 -1
  16. data/lib/ffi-geos/point.rb +9 -0
  17. data/lib/ffi-geos/polygon.rb +1 -1
  18. data/lib/ffi-geos/prepared_geometry.rb +20 -0
  19. data/lib/ffi-geos/version.rb +1 -1
  20. data/lib/ffi-geos/wkb_writer.rb +12 -0
  21. data/lib/ffi-geos.rb +156 -3
  22. data/test/coordinate_sequence_tests.rb +22 -4
  23. data/test/geojson_reader_tests.rb +174 -0
  24. data/test/geojson_writer_tests.rb +103 -0
  25. data/test/geometry/area_tests.rb +18 -0
  26. data/test/geometry/boundary_tests.rb +36 -0
  27. data/test/geometry/buffer_tests.rb +116 -0
  28. data/test/geometry/build_area_tests.rb +20 -0
  29. data/test/geometry/centroid_tests.rb +37 -0
  30. data/test/geometry/clip_by_rect_tests.rb +56 -0
  31. data/test/geometry/clone_tests.rb +29 -0
  32. data/test/geometry/concave_hull_of_polygons_tests.rb +28 -0
  33. data/test/geometry/concave_hull_tests.rb +38 -0
  34. data/test/geometry/convex_hull_tests.rb +26 -0
  35. data/test/geometry/coord_seq_tests.rb +27 -0
  36. data/test/geometry/delaunay_triangulation_tests.rb +82 -0
  37. data/test/geometry/densify_tests.rb +95 -0
  38. data/test/geometry/difference_tests.rb +108 -0
  39. data/test/geometry/dimensions_tests.rb +46 -0
  40. data/test/geometry/distance_tests.rb +29 -0
  41. data/test/geometry/dump_points_tests.rb +60 -0
  42. data/test/geometry/dup_tests.rb +29 -0
  43. data/test/geometry/empty_tests.rb +23 -0
  44. data/test/geometry/envelope_tests.rb +26 -0
  45. data/test/geometry/equal_identical_tests.rb +78 -0
  46. data/test/geometry/equal_tests.rb +62 -0
  47. data/test/geometry/exterior_ring_tests.rb +27 -0
  48. data/test/geometry/extract_unique_points_tests.rb +41 -0
  49. data/test/geometry/frecet_distance_tests.rb +24 -0
  50. data/test/geometry/get_geometry_n_tests.rb +21 -0
  51. data/test/geometry/hausdorff_distance_tests.rb +46 -0
  52. data/test/geometry/hilbert_code_tests.rb +45 -0
  53. data/test/geometry/interior_ring_n_tests.rb +64 -0
  54. data/test/geometry/interior_rings_tests.rb +36 -0
  55. data/test/geometry/interpolate_tests.rb +49 -0
  56. data/test/geometry/intersection_tests.rb +49 -0
  57. data/test/geometry/largest_empty_circle_tests.rb +26 -0
  58. data/test/geometry/length_tests.rb +18 -0
  59. data/test/geometry/line_merge_directed_tests.rb +28 -0
  60. data/test/geometry/line_merge_tests.rb +25 -0
  61. data/test/geometry/line_string_enumerator_tests.rb +20 -0
  62. data/test/geometry/line_substring_tests.rb +76 -0
  63. data/test/geometry/make_valid_tests.rb +27 -0
  64. data/test/geometry/maximum_inscribed_circle_tests.rb +21 -0
  65. data/test/geometry/minimum_bounding_circle_tests.rb +23 -0
  66. data/test/geometry/minimum_clearance_tests.rb +58 -0
  67. data/test/geometry/minimum_rotated_rectangle_tests.rb +28 -0
  68. data/test/geometry/minimum_width_tests.rb +26 -0
  69. data/test/geometry/misc_tests.rb +24 -0
  70. data/test/geometry/nearest_points_tests.rb +46 -0
  71. data/test/geometry/node_tests.rb +22 -0
  72. data/test/geometry/normalize_tests.rb +34 -0
  73. data/test/geometry/num_coordinates_tests.rb +39 -0
  74. data/test/geometry/num_goemetries_tests.rb +35 -0
  75. data/test/geometry/num_interior_rings_tests.rb +28 -0
  76. data/test/geometry/orient_polygons_tests.rb +101 -0
  77. data/test/geometry/point_on_surface_tests.rb +37 -0
  78. data/test/geometry/polygon_hull_simplify_tests.rb +55 -0
  79. data/test/geometry/polygonize_tests.rb +173 -0
  80. data/test/geometry/precision_tests.rb +42 -0
  81. data/test/geometry/project_tests.rb +56 -0
  82. data/test/geometry/relate_tests.rb +73 -0
  83. data/test/geometry/relationships_tests.rb +138 -0
  84. data/test/geometry/reverse_tests.rb +44 -0
  85. data/test/geometry/ring_tests.rb +18 -0
  86. data/test/geometry/shared_path_tests.rb +31 -0
  87. data/test/geometry/simple_tests.rb +18 -0
  88. data/test/geometry/simplify_tests.rb +21 -0
  89. data/test/geometry/snap_tests.rb +20 -0
  90. data/test/geometry/srid_copy_policy_tests.rb +94 -0
  91. data/test/geometry/start_and_end_point_tests.rb +24 -0
  92. data/test/geometry/sym_difference_tests.rb +114 -0
  93. data/test/geometry/topology_preserve_simplify_tests.rb +21 -0
  94. data/test/geometry/union_tests.rb +216 -0
  95. data/test/geometry/valid_tests.rb +56 -0
  96. data/test/geometry/voronoi_diagram_tests.rb +62 -0
  97. data/test/geometry_collection_tests.rb +14 -2
  98. data/test/interrupt_tests.rb +1 -1
  99. data/test/line_string_tests.rb +24 -3
  100. data/test/misc_tests.rb +1 -1
  101. data/test/point/has_m_tests.rb +43 -0
  102. data/test/point/x_y_z_m_tests.rb +51 -0
  103. data/test/point_tests.rb +25 -3
  104. data/test/polygon_tests.rb +14 -1
  105. data/test/prepared_geometry_tests.rb +31 -0
  106. data/test/strtree_tests.rb +11 -18
  107. data/test/test_helper.rb +2 -0
  108. data/test/tools_tests.rb +7 -0
  109. data/test/utils_tests.rb +14 -3
  110. data/test/wkb_reader_tests.rb +1 -0
  111. data/test/wkb_writer_tests.rb +46 -5
  112. data/test/wkt_reader_tests.rb +2 -0
  113. data/test/wkt_writer_tests.rb +20 -2
  114. metadata +160 -7
  115. data/test/geometry_tests.rb +0 -2096
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryAreaTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_area
14
+ simple_tester(:area, 1.0, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))')
15
+ simple_tester(:area, 0.0, 'POINT (0 0)')
16
+ simple_tester(:area, 0.0, 'LINESTRING (0 0 , 10 0)')
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryBoundaryTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_boundary
14
+ simple_tester(
15
+ :boundary,
16
+ 'GEOMETRYCOLLECTION EMPTY',
17
+ 'POINT(0 0)'
18
+ )
19
+
20
+ simple_tester(
21
+ :boundary,
22
+ if Geos::GEOS_NICE_VERSION >= '031200'
23
+ 'MULTIPOINT ((0 0), (10 10))'
24
+ else
25
+ 'MULTIPOINT (0 0, 10 10)'
26
+ end,
27
+ 'LINESTRING(0 0, 10 10)'
28
+ )
29
+
30
+ simple_tester(
31
+ :boundary,
32
+ 'MULTILINESTRING ((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 5 6, 6 6, 6 5, 5 5))',
33
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),( 5 5, 5 6, 6 6, 6 5, 5 5))'
34
+ )
35
+ end
36
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryBufferTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_buffer
14
+ simple_tester(
15
+ :buffer,
16
+ 'POLYGON EMPTY',
17
+ 'POINT(0 0)',
18
+ 0
19
+ )
20
+
21
+ snapped_tester(
22
+ :buffer,
23
+ 'POLYGON ((10 0, 10 -2, 9 -4, 8 -6, 7 -7, 6 -8, 4 -9, 2 -10, 0 -10, -2 -10, -4 -9, -6 -8, -7 -7, -8 -6, -9 -4, -10 -2, -10 0, -10 2, -9 4, -8 6, -7 7, -6 8, -4 9, -2 10, 0 10, 2 10, 4 9, 6 8, 7 7, 8 6, 9 4, 10 2, 10 0))',
24
+ 'POINT(0 0)',
25
+ 10
26
+ )
27
+
28
+ # One segment per quadrant
29
+ snapped_tester(
30
+ :buffer,
31
+ 'POLYGON ((10 0, 0 -10, -10 0, 0 10, 10 0))',
32
+ 'POINT(0 0)',
33
+ 10,
34
+ quad_segs: 1
35
+ )
36
+
37
+ # End cap styles
38
+ snapped_tester(
39
+ :buffer,
40
+ 'POLYGON ((100 10, 110 0, 100 -10, 0 -10, -10 0, 0 10, 100 10))',
41
+ 'LINESTRING(0 0, 100 0)',
42
+ 10,
43
+ quad_segs: 1, endcap: :round
44
+ )
45
+
46
+ snapped_tester(
47
+ :buffer,
48
+ 'POLYGON ((100 10, 100 -10, 0 -10, 0 10, 100 10))',
49
+ 'LINESTRING(0 0, 100 0)',
50
+ 10,
51
+ quad_segs: 1, endcap: :flat
52
+ )
53
+
54
+ snapped_tester(
55
+ :buffer,
56
+ 'POLYGON ((100 10, 110 10, 110 -10, 0 -10, -10 -10, -10 10, 100 10))',
57
+ 'LINESTRING(0 0, 100 0)',
58
+ 10,
59
+ quad_segs: 1, endcap: :square
60
+ )
61
+
62
+ # Join styles
63
+ snapped_tester(
64
+ :buffer,
65
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 107 -7, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
66
+ 'LINESTRING(0 0, 100 0, 100 100)',
67
+ 10,
68
+ quad_segs: 2, join: :round
69
+ )
70
+
71
+ snapped_tester(
72
+ :buffer,
73
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
74
+ 'LINESTRING(0 0, 100 0, 100 100)',
75
+ 10,
76
+ quad_segs: 2, join: :bevel
77
+ )
78
+
79
+ snapped_tester(
80
+ :buffer,
81
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
82
+ 'LINESTRING(0 0, 100 0, 100 100)',
83
+ 10,
84
+ quad_segs: 2, join: :mitre
85
+ )
86
+
87
+ snapped_tester(
88
+ :buffer,
89
+ if Geos::GEOS_NICE_VERSION >= '031100'
90
+ '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))'
91
+ else
92
+ '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))'
93
+ end,
94
+ 'LINESTRING(0 0, 100 0, 100 100)',
95
+ 10,
96
+ quad_segs: 2, join: :mitre, mitre_limit: 1.0
97
+ )
98
+
99
+ # Single-sided buffering
100
+ snapped_tester(
101
+ :buffer,
102
+ 'POLYGON ((100 0, 0 0, 0 10, 100 10, 100 0))',
103
+ 'LINESTRING(0 0, 100 0)',
104
+ 10,
105
+ single_sided: true
106
+ )
107
+
108
+ snapped_tester(
109
+ :buffer,
110
+ 'POLYGON ((0 0, 100 0, 100 -10, 0 -10, 0 0))',
111
+ 'LINESTRING(0 0, 100 0)',
112
+ -10,
113
+ single_sided: true
114
+ )
115
+ end
116
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryBuildAreaTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_build_area
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:build_area)
15
+
16
+ geom = read('GEOMETRYCOLLECTION (LINESTRING(0 0, 0 1, 1 1), LINESTRING (1 1, 1 0, 0 0))')
17
+
18
+ assert_equal('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))', write(geom.build_area))
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryCentroidTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_centroid_and_center
14
+ %w{
15
+ centroid
16
+ center
17
+ }.each do |method|
18
+ simple_tester(
19
+ method,
20
+ 'POINT (0 0)',
21
+ 'POINT(0 0)'
22
+ )
23
+
24
+ simple_tester(
25
+ method,
26
+ 'POINT (5 5)',
27
+ 'LINESTRING(0 0, 10 10)'
28
+ )
29
+
30
+ snapped_tester(
31
+ method,
32
+ 'POINT (5 4)',
33
+ 'POLYGON((0 0, 0 10, 5 5, 10 10, 10 0, 0 0))'
34
+ )
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryClipByRectTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_clip_by_rect
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:clip_by_rect)
15
+
16
+ %w{
17
+ clip_by_rect
18
+ clip_by_rectangle
19
+ }.each do |method|
20
+ simple_tester(
21
+ method,
22
+ 'POINT (0 0)',
23
+ 'POINT (0 0)',
24
+ -1, -1, 1, 1
25
+ )
26
+
27
+ simple_tester(
28
+ method,
29
+ 'GEOMETRYCOLLECTION EMPTY',
30
+ 'POINT (0 0)',
31
+ 0, 0, 2, 2
32
+ )
33
+
34
+ simple_tester(
35
+ method,
36
+ 'LINESTRING (1 0, 2 0)',
37
+ 'LINESTRING (0 0, 10 0)',
38
+ 1, -1, 2, 1
39
+ )
40
+
41
+ simple_tester(
42
+ method,
43
+ 'POLYGON ((1 1, 1 5, 5 5, 5 1, 1 1))',
44
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))',
45
+ 1, 1, 5, 5
46
+ )
47
+
48
+ simple_tester(
49
+ method,
50
+ 'POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))',
51
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))',
52
+ -1, -1, 5, 5
53
+ )
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryCloneTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_clone
14
+ geom_a = read('POINT(0 0)')
15
+ geom_b = geom_a.clone
16
+
17
+ assert_equal(geom_a, geom_b)
18
+ end
19
+
20
+ def test_clone_srid
21
+ srid = 4326
22
+ geom_a = read('POINT(0 0)')
23
+ geom_a.srid = srid
24
+ geom_b = geom_a.clone
25
+
26
+ assert_equal(geom_a, geom_b)
27
+ assert_equal(srid, geom_b.srid)
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Concave Hull Of Polygons Tests' do
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ it 'handles empty polygons' do
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:concave_hull_of_polygons)
15
+
16
+ geom = read('POLYGON EMPTY')
17
+
18
+ assert(geom.concave_hull_of_polygons(0.7).eql?(read('POLYGON EMPTY')))
19
+ end
20
+
21
+ it 'handles a multipolygon' do
22
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:concave_hull_of_polygons)
23
+
24
+ geom = read('MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))')
25
+
26
+ assert(geom.concave_hull_of_polygons(0.7).eql?(read('MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))')))
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Geometry Concave Hull Tests' do
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def tester(expected, geom, **options)
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:concave_hull)
15
+
16
+ simple_tester(
17
+ :concave_hull,
18
+ expected,
19
+ geom,
20
+ **options
21
+ )
22
+ end
23
+
24
+ it 'returns a concave hull' do
25
+ tester(
26
+ 'POLYGON ((30 70, 10 90, 60 72, 90 90, 90 60, 90 10, 60 30, 10 10, 40 40, 60 50, 47 66, 40 60, 30 70))',
27
+ 'MULTIPOINT ((10 90), (10 10), (90 10), (90 90), (40 40), (60 30), (30 70), (40 60), (60 50), (60 72), (47 66), (90 60))'
28
+ )
29
+ end
30
+
31
+ it 'handles a concave hull by length' do
32
+ tester(
33
+ 'POLYGON ((30 70, 10 90, 60 72, 90 90, 90 60, 90 10, 60 30, 10 10, 40 40, 30 70))',
34
+ 'MULTIPOINT ((10 90), (10 10), (90 10), (90 90), (40 40), (60 30), (30 70), (40 60), (60 50), (60 72), (47 66), (90 60))',
35
+ length: 50
36
+ )
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryConvexHullTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_convex_hull
14
+ geom = read('POINT(0 0)')
15
+
16
+ assert_geom_eql_exact(read('POINT(0 0)'), geom.convex_hull)
17
+
18
+ geom = read('LINESTRING(0 0, 10 10)')
19
+
20
+ assert_geom_eql_exact(read('LINESTRING(0 0, 10 10)'), geom.convex_hull)
21
+
22
+ geom = read('POLYGON((0 0, 0 10, 5 5, 10 10, 10 0, 0 0))')
23
+
24
+ assert_geom_eql_exact(read('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), geom.convex_hull)
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryCoordSeqTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_coord_seq
14
+ tester = lambda { |expected, g|
15
+ geom = read(g)
16
+ cs = geom.coord_seq
17
+ expected.each_with_index do |c, i|
18
+ assert_equal(c[0], cs.get_x(i))
19
+ assert_equal(c[1], cs.get_y(i))
20
+ end
21
+ }
22
+
23
+ tester[[[0, 0]], 'POINT(0 0)']
24
+ tester[[[0, 0], [2, 3]], 'LINESTRING (0 0, 2 3)']
25
+ tester[[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]], 'LINEARRING(0 0, 0 5, 5 5, 5 0, 0 0)']
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryDelaunayTriangulationTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_delaunay_triangulation
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:delaunay_triangulation)
15
+
16
+ tester = lambda { |expected, geom, *args|
17
+ geom = read(geom)
18
+ geom_tri = geom.delaunay_triangulation(*args)
19
+ geom_tri.normalize!
20
+
21
+ assert_equal(expected, write(geom_tri))
22
+ }
23
+
24
+ writer.trim = true
25
+
26
+ # empty polygon
27
+ tester['GEOMETRYCOLLECTION EMPTY', 'POLYGON EMPTY', 0]
28
+ tester['MULTILINESTRING EMPTY', 'POLYGON EMPTY', 0, only_edges: true]
29
+
30
+ # single point
31
+ tester['GEOMETRYCOLLECTION EMPTY', 'POINT (0 0)', 0]
32
+ tester['MULTILINESTRING EMPTY', 'POINT (0 0)', 0, only_edges: true]
33
+
34
+ # three collinear points
35
+ tester['GEOMETRYCOLLECTION EMPTY', 'MULTIPOINT(0 0, 5 0, 10 0)', 0]
36
+ tester['MULTILINESTRING ((5 0, 10 0), (0 0, 5 0))', 'MULTIPOINT(0 0, 5 0, 10 0)', 0, only_edges: true]
37
+
38
+ # three points
39
+ tester['GEOMETRYCOLLECTION (POLYGON ((0 0, 10 10, 5 0, 0 0)))', 'MULTIPOINT(0 0, 5 0, 10 10)', 0]
40
+ tester['MULTILINESTRING ((5 0, 10 10), (0 0, 10 10), (0 0, 5 0))', 'MULTIPOINT(0 0, 5 0, 10 10)', 0, only_edges: true]
41
+
42
+ # polygon with a hole
43
+ tester[
44
+ '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)), ' \
45
+ '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)), ' \
46
+ '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)))',
47
+ 'POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2))',
48
+ 0
49
+ ]
50
+
51
+ tester[
52
+ 'MULTILINESTRING ((8.5 1, 10 10), (8 2, 10 10), (8 2, 8.5 1), (7 8, 10 10), (7 8, 8 2), (3 8, 10 10), (3 8, 7 8), (2 2, 8.5 1), (2 2, 8 2), (2 2, 7 8), (2 2, 3 8), (0.5 9, 10 10), (0.5 9, 3 8), (0.5 9, 2 2), (0 0, 8.5 1), (0 0, 2 2), (0 0, 0.5 9))',
53
+ 'POLYGON((0 0, 8.5 1, 10 10, 0.5 9, 0 0),(2 2, 3 8, 7 8, 8 2, 2 2))',
54
+ 0,
55
+ only_edges: true
56
+ ]
57
+
58
+ # four points with a tolerance making one collapse
59
+ tester['MULTILINESTRING ((10 0, 10 10), (0 0, 10 10), (0 0, 10 0))', 'MULTIPOINT(0 0, 10 0, 10 10, 11 10)', 2.0, only_edges: true]
60
+
61
+ # tolerance as an option
62
+ 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]
63
+ end
64
+
65
+ def test_constrained_delaunay_triangulation
66
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:constrained_delaunay_triangulation)
67
+
68
+ tester = lambda { |expected, geom|
69
+ geom = read(geom)
70
+ geom_tri = geom.constrained_delaunay_triangulation
71
+ geom_tri.normalize!
72
+
73
+ assert_equal(write(read(expected).normalize), write(geom_tri))
74
+ }
75
+
76
+ writer.trim = true
77
+
78
+ tester['GEOMETRYCOLLECTION EMPTY', 'POLYGON EMPTY']
79
+ tester['GEOMETRYCOLLECTION EMPTY', 'POINT(0 0)']
80
+ 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))']
81
+ end
82
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe 'Geometry Densify Tests' do
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def tester(expected, geom, tolerence)
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:densify)
15
+
16
+ simple_tester(
17
+ :densify,
18
+ expected,
19
+ geom,
20
+ tolerence
21
+ )
22
+ end
23
+
24
+ it 'can densify with tolerance greater than or equal to length of all edges' do
25
+ tester(
26
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))',
27
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))',
28
+ 10.0
29
+ )
30
+ end
31
+
32
+ it 'can densify with a tolerance that evenly subdivides all outer and inner edges' do
33
+ tester(
34
+ 'POLYGON ((0 0, 5 0, 10 0, 10 5, 10 10, 5 10, 0 10, 0 5, 0 0), (1 1, 1 4, 1 7, 4 7, 7 7, 7 4, 7 1, 4 1, 1 1))',
35
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 7, 7 7, 7 1, 1 1))',
36
+ 5.0
37
+ )
38
+ end
39
+
40
+ it 'can densify a LINESTRING' do
41
+ tester(
42
+ 'LINESTRING (0 0, 0 3, 0 6)',
43
+ 'LINESTRING (0 0, 0 6 )',
44
+ 3.0
45
+ )
46
+ end
47
+
48
+ it 'can ensure that tolerance results in the right number of subdivisions' do
49
+ tester(
50
+ 'LINESTRING (0 0, 0 2, 0 4, 0 6)',
51
+ 'LINESTRING (0 0, 0 6 )',
52
+ 2.9999999
53
+ )
54
+ end
55
+
56
+ it 'can densify a LINEARRING' do
57
+ tester(
58
+ 'LINEARRING (0 0, 0 3, 0 6, 3 6, 6 6, 4 4, 2 2, 0 0)',
59
+ 'LINEARRING (0 0, 0 6, 6 6, 0 0)',
60
+ 3.0
61
+ )
62
+ end
63
+
64
+ it 'can densify a POINT' do
65
+ tester(
66
+ 'POINT (0 0)',
67
+ 'POINT (0 0)',
68
+ 3.0
69
+ )
70
+ end
71
+
72
+ it 'can densify a MULTIPOINT' do
73
+ tester(
74
+ 'MULTIPOINT ((0 0), (10 10))',
75
+ 'MULTIPOINT ((0 0), (10 10))',
76
+ 3.0
77
+ )
78
+ end
79
+
80
+ it 'can densify an empty polygon' do
81
+ tester(
82
+ 'POLYGON EMPTY',
83
+ 'POLYGON EMPTY',
84
+ 3.0
85
+ )
86
+ end
87
+
88
+ it 'densify with an invalid tolerances should fail' do
89
+ geom = read('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))')
90
+
91
+ assert_raises(Geos::GEOSException, 'IllegalArgumentException: Tolerance must be positive') do
92
+ geom.densify(-1.0)
93
+ end
94
+ end
95
+ end