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,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryNormalizeTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_normalize
14
+ geom = read('POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))')
15
+ geom.normalize
16
+
17
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(geom))
18
+
19
+ geom = read('POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))').normalize
20
+
21
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(geom))
22
+ end
23
+
24
+ def test_normalize_bang
25
+ geom = read('POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))')
26
+ geom.normalize!
27
+
28
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(geom))
29
+
30
+ geom = read('POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))').normalize!
31
+
32
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(geom))
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryNumCoordinatesTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_num_coordinates
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:num_coordinates)
15
+
16
+ simple_tester(:num_coordinates, 1, 'POINT(0 0)')
17
+ simple_tester(:num_coordinates, 2, 'MULTIPOINT (0 1, 2 3)')
18
+ simple_tester(:num_coordinates, 2, 'LINESTRING (0 0, 2 3)')
19
+ simple_tester(:num_coordinates, 4, 'MULTILINESTRING ((0 1, 2 3), (10 10, 3 4))')
20
+ simple_tester(:num_coordinates, 5, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))')
21
+ simple_tester(:num_coordinates, 15, 'MULTIPOLYGON (
22
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
23
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
24
+ (11 11, 11 12, 12 12, 12 11, 11 11))
25
+ )')
26
+ simple_tester(:num_coordinates, 29, 'GEOMETRYCOLLECTION (
27
+ MULTIPOLYGON (
28
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
29
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
30
+ (11 11, 11 12, 12 12, 12 11, 11 11))
31
+ ),
32
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
33
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
34
+ LINESTRING (0 0, 2 3),
35
+ MULTIPOINT ((0 0), (2 3)),
36
+ POINT (9 0)
37
+ )')
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_num_geometries
14
+ simple_tester(:num_geometries, 1, 'POINT(0 0)')
15
+ simple_tester(:num_geometries, 2, 'MULTIPOINT (0 1, 2 3)')
16
+ simple_tester(:num_geometries, 1, 'LINESTRING (0 0, 2 3)')
17
+ simple_tester(:num_geometries, 2, 'MULTILINESTRING ((0 1, 2 3), (10 10, 3 4))')
18
+ simple_tester(:num_geometries, 1, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))')
19
+ simple_tester(:num_geometries, 2, 'MULTIPOLYGON(
20
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
21
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
22
+ (11 11, 11 12, 12 12, 12 11, 11 11)))')
23
+ simple_tester(:num_geometries, 6, 'GEOMETRYCOLLECTION (
24
+ MULTIPOLYGON (
25
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
26
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
27
+ (11 11, 11 12, 12 12, 12 11, 11 11))
28
+ ),
29
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
30
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
31
+ LINESTRING (0 0, 2 3),
32
+ MULTIPOINT (0 0, 2 3),
33
+ POINT (9 0))')
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryNumInteriorRingsTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_num_interior_rings
14
+ simple_tester(:num_interior_rings, 0, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))')
15
+ simple_tester(:num_interior_rings, 1, 'POLYGON (
16
+ (10 10, 10 14, 14 14, 14 10, 10 10),
17
+ (11 11, 11 12, 12 12, 12 11, 11 11)
18
+ )')
19
+ simple_tester(:num_interior_rings, 2, 'POLYGON (
20
+ (10 10, 10 14, 14 14, 14 10, 10 10),
21
+ (11 11, 11 12, 12 12, 12 11, 11 11),
22
+ (13 11, 13 12, 13.5 12, 13.5 11, 13 11))')
23
+
24
+ assert_raises(NoMethodError) do
25
+ read('POINT (0 0)').num_interior_rings
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe '#orient_polygons' do
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ it 'does not overwrite the original geometry' do
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
15
+
16
+ geom = read('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))')
17
+
18
+ result = geom.orient_polygons(true)
19
+
20
+ assert_equal('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))', write(geom))
21
+ assert_equal('POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))', write(result))
22
+ refute_same(geom, result)
23
+ end
24
+
25
+ it 'does overwrite the original geometry with bang method' do
26
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons!)
27
+
28
+ geom = read('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))')
29
+
30
+ result = geom.orient_polygons!(true)
31
+
32
+ assert_equal('POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))', write(geom))
33
+ assert_equal('POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))', write(result))
34
+ assert_same(geom, result)
35
+ end
36
+
37
+ it 'handles empty polygons' do
38
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
39
+
40
+ simple_tester(
41
+ :orient_polygons,
42
+ 'POLYGON EMPTY',
43
+ 'POLYGON EMPTY'
44
+ )
45
+ end
46
+
47
+ it 'hole orientation is opposite to shell' do
48
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
49
+
50
+ simple_tester(
51
+ :orient_polygons,
52
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))',
53
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))'
54
+ )
55
+
56
+ simple_tester(
57
+ :orient_polygons,
58
+ 'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))',
59
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))',
60
+ true
61
+ )
62
+ end
63
+
64
+ it 'ensures all polygons in collection are processed' do
65
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
66
+
67
+ simple_tester(
68
+ :orient_polygons,
69
+ 'MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1)), ((100 100, 200 100, 200 200, 100 100)))',
70
+ 'MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), ((100 100, 200 100, 200 200, 100 100)))'
71
+ )
72
+
73
+ simple_tester(
74
+ :orient_polygons,
75
+ 'MULTIPOLYGON (((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), ((100 100, 200 200, 200 100, 100 100)))',
76
+ 'MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), ((100 100, 200 100, 200 200, 100 100)))',
77
+ true
78
+ )
79
+ end
80
+
81
+ it 'polygons in collection are oriented, closed linestring unchanged' do
82
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
83
+
84
+ simple_tester(
85
+ :orient_polygons,
86
+ 'GEOMETRYCOLLECTION (POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), LINESTRING (100 100, 200 100, 200 200, 100 100))',
87
+ 'GEOMETRYCOLLECTION (POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), LINESTRING (100 100, 200 100, 200 200, 100 100))',
88
+ true
89
+ )
90
+ end
91
+
92
+ it 'nested collection handled correctly' do
93
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:orient_polygons)
94
+
95
+ simple_tester(
96
+ :orient_polygons,
97
+ 'GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)))))',
98
+ 'GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)))))'
99
+ )
100
+ end
101
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryPointOnSurfaceTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_point_on_surface_and_representative_point
14
+ %w{
15
+ point_on_surface
16
+ representative_point
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 0)',
27
+ 'LINESTRING(0 0, 5 0, 10 0)'
28
+ )
29
+
30
+ simple_tester(
31
+ method,
32
+ 'POINT (5 5)',
33
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'
34
+ )
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe '#polygon_hull_simplify' do
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def tester(expected, geom, *args, **options)
14
+ skip unless ENV['FORCE_TESTS'] || !geom.respond_to?(:polygon_hull_simplify)
15
+
16
+ simple_tester(:polygon_hull_simplify, expected, geom, *args, **options)
17
+ end
18
+
19
+ it 'handles a POLYGON' do
20
+ tester(
21
+ 'POLYGON ((10 90, 50 90, 90 90, 90 10, 10 10, 10 90))',
22
+ 'POLYGON ((10 90, 40 60, 20 40, 40 20, 70 50, 40 30, 30 40, 60 70, 50 90, 90 90, 90 10, 10 10, 10 90))',
23
+ 0.5,
24
+ outer: true
25
+ )
26
+
27
+ tester(
28
+ 'POLYGON ((10 90, 40 60, 30 40, 60 70, 50 90, 90 90, 90 10, 10 10, 10 90))',
29
+ 'POLYGON ((10 90, 40 60, 20 40, 40 20, 70 50, 40 30, 30 40, 60 70, 50 90, 90 90, 90 10, 10 10, 10 90))',
30
+ 0.7,
31
+ outer: true
32
+ )
33
+
34
+ tester(
35
+ 'POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))',
36
+ 'POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))',
37
+ 0.7,
38
+ outer: true
39
+ )
40
+ end
41
+
42
+ it 'handles an empty POLYGON' do
43
+ tester('POLYGON EMPTY', 'POLYGON EMPTY', 0.5, outer: true)
44
+ end
45
+
46
+ it 'handles a mode' do
47
+ tester(
48
+ 'POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))',
49
+ 'POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))',
50
+ 0.7,
51
+ mode: :area_ratio,
52
+ outer: true
53
+ )
54
+ end
55
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryPolygonizeTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_polygonize
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize)
15
+
16
+ geom_a = read(
17
+ 'GEOMETRYCOLLECTION(
18
+ LINESTRING(0 0, 10 10),
19
+ LINESTRING(185 221, 100 100),
20
+ LINESTRING(185 221, 88 275, 180 316),
21
+ LINESTRING(185 221, 292 281, 180 316),
22
+ LINESTRING(189 98, 83 187, 185 221),
23
+ LINESTRING(189 98, 325 168, 185 221)
24
+ )'
25
+ )
26
+
27
+ polygonized = geom_a.polygonize
28
+
29
+ assert_equal(2, polygonized.length)
30
+ assert_equal(
31
+ 'POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))',
32
+ write(polygonized[0].snap_to_grid(0.1))
33
+ )
34
+ assert_equal(
35
+ 'POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))',
36
+ write(polygonized[1].snap_to_grid(0.1))
37
+ )
38
+ end
39
+
40
+ def test_polygonize_with_geometry_arguments
41
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize)
42
+
43
+ geom_a = read('LINESTRING (100 100, 100 300, 300 300, 300 100, 100 100)')
44
+ geom_b = read('LINESTRING (150 150, 150 250, 250 250, 250 150, 150 150)')
45
+
46
+ polygonized = geom_a.polygonize(geom_b)
47
+
48
+ assert_equal(2, polygonized.length)
49
+ assert_equal(
50
+ 'POLYGON ((100 100, 100 300, 300 300, 300 100, 100 100), (150 150, 250 150, 250 250, 150 250, 150 150))',
51
+ write(polygonized[0].snap_to_grid(0.1))
52
+ )
53
+ assert_equal(
54
+ 'POLYGON ((150 150, 150 250, 250 250, 250 150, 150 150))',
55
+ write(polygonized[1].snap_to_grid(0.1))
56
+ )
57
+ end
58
+
59
+ def test_polygonize_valid
60
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_valid)
61
+
62
+ geom_a = read(
63
+ 'GEOMETRYCOLLECTION(
64
+ LINESTRING (100 100, 100 300, 300 300, 300 100, 100 100),
65
+ LINESTRING (150 150, 150 250, 250 250, 250 150, 150 150)
66
+ )'
67
+ )
68
+
69
+ polygonized = geom_a.polygonize_valid
70
+
71
+ assert_equal(
72
+ 'POLYGON ((100 100, 100 300, 300 300, 300 100, 100 100), (150 150, 250 150, 250 250, 150 250, 150 150))',
73
+ write(polygonized.snap_to_grid(0.1))
74
+ )
75
+ end
76
+
77
+ def test_polygonize_cut_edges
78
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_cut_edges)
79
+
80
+ geom_a = read(
81
+ 'GEOMETRYCOLLECTION(
82
+ LINESTRING(0 0, 10 10),
83
+ LINESTRING(185 221, 100 100),
84
+ LINESTRING(185 221, 88 275, 180 316),
85
+ LINESTRING(185 221, 292 281, 180 316),
86
+ LINESTRING(189 98, 83 187, 185 221),
87
+ LINESTRING(189 98, 325 168, 185 221)
88
+ )'
89
+ )
90
+
91
+ cut_edges = geom_a.polygonize_cut_edges
92
+
93
+ assert_equal(0, cut_edges.length)
94
+ end
95
+
96
+ def test_polygonize_full
97
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_full)
98
+
99
+ writer.rounding_precision = if Geos::GEOS_NICE_VERSION >= '031000'
100
+ 0
101
+ else
102
+ 3
103
+ end
104
+
105
+ geom_a = read(
106
+ 'GEOMETRYCOLLECTION(
107
+ LINESTRING(0 0, 10 10),
108
+ LINESTRING(185 221, 100 100),
109
+ LINESTRING(185 221, 88 275, 180 316),
110
+ LINESTRING(185 221, 292 281, 180 316),
111
+ LINESTRING(189 98, 83 187, 185 221),
112
+ LINESTRING(189 98, 325 168, 185 221)
113
+ )'
114
+ )
115
+
116
+ polygonized = geom_a.polygonize_full
117
+
118
+ assert_kind_of(Array, polygonized[:rings])
119
+ assert_kind_of(Array, polygonized[:cuts])
120
+ assert_kind_of(Array, polygonized[:dangles])
121
+ assert_kind_of(Array, polygonized[:invalid_rings])
122
+
123
+ assert_equal(2, polygonized[:rings].length)
124
+ assert_equal(0, polygonized[:cuts].length)
125
+ assert_equal(2, polygonized[:dangles].length)
126
+ assert_equal(0, polygonized[:invalid_rings].length)
127
+
128
+ assert_equal(
129
+ 'POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))',
130
+ write(polygonized[:rings][0])
131
+ )
132
+
133
+ assert_equal(
134
+ 'POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))',
135
+ write(polygonized[:rings][1])
136
+ )
137
+
138
+ assert_equal(
139
+ 'LINESTRING (185 221, 100 100)',
140
+ write(polygonized[:dangles][0])
141
+ )
142
+
143
+ assert_equal(
144
+ 'LINESTRING (0 0, 10 10)',
145
+ write(polygonized[:dangles][1])
146
+ )
147
+
148
+ geom_b = geom_a.union(read('POINT(0 0)'))
149
+ polygonized = geom_b.polygonize_full
150
+
151
+ assert_equal(2, polygonized[:dangles].length)
152
+ assert_equal(0, polygonized[:invalid_rings].length)
153
+
154
+ assert_equal(
155
+ 'LINESTRING (132 146, 100 100)',
156
+ write(polygonized[:dangles][0])
157
+ )
158
+
159
+ assert_equal(
160
+ 'LINESTRING (0 0, 10 10)',
161
+ write(polygonized[:dangles][1])
162
+ )
163
+ end
164
+
165
+ def test_polygonize_with_bad_arguments
166
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_full)
167
+
168
+ assert_raises(ArgumentError) do
169
+ geom = read('POINT(0 0)')
170
+ geom.polygonize(geom, 'gibberish')
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryPrecisionTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_precision
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:precision)
15
+
16
+ geom = read('POLYGON EMPTY')
17
+ scale = geom.precision
18
+
19
+ assert_in_delta(0.0, scale)
20
+
21
+ geom_with_precision = geom.with_precision(2.0)
22
+
23
+ assert_equal('POLYGON EMPTY', write(geom_with_precision))
24
+ scale = geom_with_precision.precision
25
+
26
+ assert_in_delta(2.0, scale)
27
+ end
28
+
29
+ def test_with_precision
30
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:with_precision)
31
+
32
+ geom = read('LINESTRING(1 0, 2 0)')
33
+
34
+ geom_with_precision = geom.with_precision(5.0)
35
+
36
+ assert_equal('LINESTRING EMPTY', write(geom_with_precision))
37
+
38
+ geom_with_precision = geom.with_precision(5.0, keep_collapsed: true)
39
+
40
+ assert_equal('LINESTRING (0 0, 0 0)', write(geom_with_precision))
41
+ end
42
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryProjectTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_project_and_project_normalized
14
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:project)
15
+
16
+ geom_a = read('POINT(1 2)')
17
+ geom_b = read('POINT(3 4)')
18
+
19
+ # The method only accept lineal geometries
20
+ assert_raises(Geos::GEOSException) do
21
+ geom_a.project(geom_b)
22
+ end
23
+
24
+ geom_a = read('LINESTRING(0 0, 10 0)')
25
+ geom_b = read('POINT(0 0)')
26
+
27
+ assert_equal(0, geom_a.project(geom_b))
28
+ assert_equal(0, geom_a.project(geom_b, true))
29
+ assert_equal(0, geom_a.project_normalized(geom_b))
30
+
31
+ geom_b = read('POINT(10 0)')
32
+
33
+ assert_equal(10, geom_a.project(geom_b))
34
+ assert_equal(1, geom_a.project(geom_b, true))
35
+ assert_equal(1, geom_a.project_normalized(geom_b))
36
+
37
+ geom_b = read('POINT(5 0)')
38
+
39
+ assert_equal(5, geom_a.project(geom_b))
40
+ assert_in_delta(0.5, geom_a.project(geom_b, true))
41
+ assert_in_delta(0.5, geom_a.project_normalized(geom_b))
42
+
43
+ geom_a = read('MULTILINESTRING((0 0, 10 0),(20 10, 20 20))')
44
+ geom_b = read('POINT(20 0)')
45
+
46
+ assert_equal(10, geom_a.project(geom_b))
47
+ assert_in_delta(0.5, geom_a.project(geom_b, true))
48
+ assert_in_delta(0.5, geom_a.project_normalized(geom_b))
49
+
50
+ geom_b = read('POINT(20 5)')
51
+
52
+ assert_equal(10, geom_a.project(geom_b))
53
+ assert_in_delta(0.5, geom_a.project(geom_b, true))
54
+ assert_in_delta(0.5, geom_a.project_normalized(geom_b))
55
+ end
56
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class GeometryRelateTests < Minitest::Test
6
+ include TestHelper
7
+
8
+ def setup
9
+ super
10
+ writer.trim = true
11
+ end
12
+
13
+ def test_relate
14
+ tester = lambda { |expected, geom_a, geom_b|
15
+ assert_equal(expected, geom_a.relate(geom_b))
16
+ }
17
+
18
+ geom_a = read('POINT(0 0)')
19
+ geom_b = read('POINT(0 0)')
20
+ tester['0FFFFFFF2', geom_a, geom_b]
21
+
22
+ geom_a = read('POINT(0 0)')
23
+ geom_b = read('POINT(1 0)')
24
+ tester['FF0FFF0F2', geom_a, geom_b]
25
+
26
+ geom_a = read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')
27
+ geom_b = read('POINT(1 0)')
28
+ tester['FF20F1FF2', geom_a, geom_b]
29
+ end
30
+
31
+ def test_relate_pattern
32
+ tester = lambda { |pattern, geom_a, geom_b, expected|
33
+ assert_equal(expected, geom_a.relate_pattern(geom_b, pattern))
34
+ }
35
+
36
+ geom_a = read('POINT(0 0)')
37
+ geom_b = read('POINT(0 0)')
38
+ tester['0FFFFFFF2', geom_a, geom_b, true]
39
+ tester['0*******T', geom_a, geom_b, true]
40
+ tester['0*******1', geom_a, geom_b, false]
41
+
42
+ geom_a = read('POINT(0 0)')
43
+ geom_b = read('POINT(1 0)')
44
+ tester['FF0FFF0F2', geom_a, geom_b, true]
45
+ tester['F*******2', geom_a, geom_b, true]
46
+ tester['T*******2', geom_a, geom_b, false]
47
+
48
+ geom_a = read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')
49
+ geom_b = read('POINT(1 0)')
50
+ tester['FF20F1FF2', geom_a, geom_b, true]
51
+ tester['F****T**T', geom_a, geom_b, true]
52
+ tester['T*******2', geom_a, geom_b, false]
53
+ end
54
+
55
+ def test_relate_boundary_node_rule
56
+ skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:relate_boundary_node_rule)
57
+
58
+ geom_a = read('LINESTRING(0 0, 2 4, 5 5, 0 0)')
59
+ geom_b = read('POINT(0 0)')
60
+
61
+ ret = geom_a.relate_boundary_node_rule(geom_b, :ogc)
62
+
63
+ assert_equal('0F1FFFFF2', ret)
64
+
65
+ ret = geom_a.relate_boundary_node_rule(geom_b, :endpoint)
66
+
67
+ assert_equal('FF10FFFF2', ret)
68
+
69
+ assert_raises(TypeError) do
70
+ geom_a.relate_boundary_node_rule(geom_b, :gibberish)
71
+ end
72
+ end
73
+ end