ffi-geos 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +2 -2
  3. data/.rbenv-vars +1 -0
  4. data/.rubocop.yml +538 -92
  5. data/.rubocop_todo.yml +28 -18
  6. data/ffi-geos.gemspec +2 -2
  7. data/lib/ffi-geos/coordinate_sequence.rb +2 -1
  8. data/lib/ffi-geos/geometry.rb +95 -1
  9. data/lib/ffi-geos/point.rb +9 -0
  10. data/lib/ffi-geos/version.rb +1 -1
  11. data/lib/ffi-geos.rb +78 -3
  12. data/test/coordinate_sequence_tests.rb +22 -4
  13. data/test/geojson_reader_tests.rb +6 -2
  14. data/test/geometry/area_tests.rb +18 -0
  15. data/test/geometry/boundary_tests.rb +36 -0
  16. data/test/geometry/buffer_tests.rb +116 -0
  17. data/test/geometry/build_area_tests.rb +20 -0
  18. data/test/geometry/centroid_tests.rb +37 -0
  19. data/test/geometry/clip_by_rect_tests.rb +56 -0
  20. data/test/geometry/clone_tests.rb +29 -0
  21. data/test/geometry/concave_hull_of_polygons_tests.rb +28 -0
  22. data/test/geometry/concave_hull_tests.rb +38 -0
  23. data/test/geometry/convex_hull_tests.rb +26 -0
  24. data/test/geometry/coord_seq_tests.rb +27 -0
  25. data/test/geometry/delaunay_triangulation_tests.rb +82 -0
  26. data/test/geometry/densify_tests.rb +95 -0
  27. data/test/geometry/difference_tests.rb +108 -0
  28. data/test/geometry/dimensions_tests.rb +46 -0
  29. data/test/geometry/distance_tests.rb +29 -0
  30. data/test/geometry/dump_points_tests.rb +60 -0
  31. data/test/geometry/dup_tests.rb +29 -0
  32. data/test/geometry/empty_tests.rb +23 -0
  33. data/test/geometry/envelope_tests.rb +26 -0
  34. data/test/geometry/equal_identical_tests.rb +78 -0
  35. data/test/geometry/equal_tests.rb +62 -0
  36. data/test/geometry/exterior_ring_tests.rb +27 -0
  37. data/test/geometry/extract_unique_points_tests.rb +41 -0
  38. data/test/geometry/frecet_distance_tests.rb +24 -0
  39. data/test/geometry/get_geometry_n_tests.rb +21 -0
  40. data/test/geometry/hausdorff_distance_tests.rb +46 -0
  41. data/test/geometry/hilbert_code_tests.rb +45 -0
  42. data/test/geometry/interior_ring_n_tests.rb +64 -0
  43. data/test/geometry/interior_rings_tests.rb +36 -0
  44. data/test/geometry/interpolate_tests.rb +49 -0
  45. data/test/geometry/intersection_tests.rb +49 -0
  46. data/test/geometry/largest_empty_circle_tests.rb +26 -0
  47. data/test/geometry/length_tests.rb +18 -0
  48. data/test/geometry/line_merge_directed_tests.rb +28 -0
  49. data/test/geometry/line_merge_tests.rb +25 -0
  50. data/test/geometry/line_string_enumerator_tests.rb +20 -0
  51. data/test/geometry/line_substring_tests.rb +76 -0
  52. data/test/geometry/make_valid_tests.rb +27 -0
  53. data/test/geometry/maximum_inscribed_circle_tests.rb +21 -0
  54. data/test/geometry/minimum_bounding_circle_tests.rb +23 -0
  55. data/test/geometry/minimum_clearance_tests.rb +58 -0
  56. data/test/geometry/minimum_rotated_rectangle_tests.rb +28 -0
  57. data/test/geometry/minimum_width_tests.rb +26 -0
  58. data/test/geometry/misc_tests.rb +24 -0
  59. data/test/geometry/nearest_points_tests.rb +46 -0
  60. data/test/geometry/node_tests.rb +22 -0
  61. data/test/geometry/normalize_tests.rb +34 -0
  62. data/test/geometry/num_coordinates_tests.rb +39 -0
  63. data/test/geometry/num_goemetries_tests.rb +35 -0
  64. data/test/geometry/num_interior_rings_tests.rb +28 -0
  65. data/test/geometry/orient_polygons_tests.rb +101 -0
  66. data/test/geometry/point_on_surface_tests.rb +37 -0
  67. data/test/geometry/polygon_hull_simplify_tests.rb +55 -0
  68. data/test/geometry/polygonize_tests.rb +173 -0
  69. data/test/geometry/precision_tests.rb +42 -0
  70. data/test/geometry/project_tests.rb +56 -0
  71. data/test/geometry/relate_tests.rb +73 -0
  72. data/test/geometry/relationships_tests.rb +138 -0
  73. data/test/geometry/reverse_tests.rb +44 -0
  74. data/test/geometry/ring_tests.rb +18 -0
  75. data/test/geometry/shared_path_tests.rb +31 -0
  76. data/test/geometry/simple_tests.rb +18 -0
  77. data/test/geometry/simplify_tests.rb +21 -0
  78. data/test/geometry/snap_tests.rb +20 -0
  79. data/test/geometry/srid_copy_policy_tests.rb +94 -0
  80. data/test/geometry/start_and_end_point_tests.rb +24 -0
  81. data/test/geometry/sym_difference_tests.rb +114 -0
  82. data/test/geometry/topology_preserve_simplify_tests.rb +21 -0
  83. data/test/geometry/union_tests.rb +216 -0
  84. data/test/geometry/valid_tests.rb +56 -0
  85. data/test/geometry/voronoi_diagram_tests.rb +62 -0
  86. data/test/geometry_collection_tests.rb +14 -2
  87. data/test/interrupt_tests.rb +1 -1
  88. data/test/line_string_tests.rb +24 -3
  89. data/test/misc_tests.rb +1 -1
  90. data/test/point/has_m_tests.rb +43 -0
  91. data/test/point/x_y_z_m_tests.rb +51 -0
  92. data/test/point_tests.rb +25 -3
  93. data/test/polygon_tests.rb +14 -1
  94. data/test/prepared_geometry_tests.rb +6 -5
  95. data/test/strtree_tests.rb +11 -18
  96. data/test/test_helper.rb +2 -0
  97. data/test/tools_tests.rb +7 -0
  98. data/test/utils_tests.rb +14 -3
  99. data/test/wkb_reader_tests.rb +1 -0
  100. data/test/wkb_writer_tests.rb +26 -5
  101. data/test/wkt_reader_tests.rb +2 -0
  102. data/test/wkt_writer_tests.rb +20 -2
  103. metadata +154 -7
  104. data/test/geometry_tests.rb +0 -2114
@@ -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
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryDifferenceTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_difference
14
+ comparison_tester(
15
+ :difference,
16
+ EMPTY_GEOMETRY,
17
+ 'POINT(0 0)',
18
+ 'POINT(0 0)'
19
+ )
20
+
21
+ comparison_tester(
22
+ :difference,
23
+ 'POINT (0 0)',
24
+ 'POINT(0 0)',
25
+ 'POINT(1 0)'
26
+ )
27
+
28
+ comparison_tester(
29
+ :difference,
30
+ 'LINESTRING (0 0, 10 0)',
31
+ 'LINESTRING(0 0, 10 0)',
32
+ 'POINT(5 0)'
33
+ )
34
+
35
+ comparison_tester(
36
+ :difference,
37
+ EMPTY_GEOMETRY,
38
+ 'POINT(5 0)',
39
+ 'LINESTRING(0 0, 10 0)'
40
+ )
41
+
42
+ comparison_tester(
43
+ :difference,
44
+ 'POINT (5 0)',
45
+ 'POINT(5 0)',
46
+ 'LINESTRING(0 1, 10 1)'
47
+ )
48
+
49
+ comparison_tester(
50
+ :difference,
51
+ 'MULTILINESTRING ((0 0, 5 0), (5 0, 10 0))',
52
+ 'LINESTRING(0 0, 10 0)',
53
+ 'LINESTRING(5 -10, 5 10)'
54
+ )
55
+
56
+ comparison_tester(
57
+ :difference,
58
+ 'LINESTRING (0 0, 5 0)',
59
+ 'LINESTRING(0 0, 10 0)',
60
+ 'LINESTRING(5 0, 20 0)'
61
+ )
62
+
63
+ comparison_tester(
64
+ :difference,
65
+ if Geos::GEOS_NICE_VERSION > '030900'
66
+ 'POLYGON ((0 10, 5 10, 10 10, 10 0, 5 0, 0 0, 0 10))'
67
+ else
68
+ 'POLYGON ((0 0, 0 10, 5 10, 10 10, 10 0, 5 0, 0 0))'
69
+ end,
70
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
71
+ 'LINESTRING(5 -10, 5 10)'
72
+ )
73
+
74
+ comparison_tester(
75
+ :difference,
76
+ if Geos::GEOS_NICE_VERSION > '030900'
77
+ 'POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10))'
78
+ else
79
+ 'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))'
80
+ end,
81
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
82
+ 'LINESTRING(10 0, 20 0)'
83
+ )
84
+
85
+ comparison_tester(
86
+ :difference,
87
+ if Geos::GEOS_NICE_VERSION > '030900'
88
+ 'POLYGON ((0 10, 10 10, 10 5, 5 5, 5 0, 0 0, 0 10))'
89
+ else
90
+ 'POLYGON ((0 0, 0 10, 10 10, 10 5, 5 5, 5 0, 0 0))'
91
+ end,
92
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
93
+ 'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))'
94
+ )
95
+ end
96
+
97
+ def test_difference_with_precision
98
+ skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSDifferencePrec_r)
99
+
100
+ comparison_tester(
101
+ :difference,
102
+ 'MULTILINESTRING ((2 8, 4 8), (6 8, 10 8))',
103
+ 'LINESTRING (2 8, 10 8)',
104
+ 'LINESTRING (3.9 8.1, 6.1 7.9)',
105
+ precision: 2
106
+ )
107
+ end
108
+ end