11using Test
2- import GeoInterface as GI
3- import GeometryOps as GO
4- using GeometryOps: perimeter, Planar, Spherical, Geodesic
5- using Proj
2+ import GeometryOps as GO
63import LibGEOS as LG
7- using .. TestHelpers
84
9- pt = LG. Point ([0.0 , 0.0 ])
10- empty_pt = LG. readgeom (" POINT EMPTY" )
11- mpt = LG. MultiPoint ([[0.0 , 0.0 ], [1.0 , 0.0 ]])
12- empty_mpt = LG. readgeom (" MULTIPOINT EMPTY" )
13- l1 = LG. LineString ([[0.0 , 0.0 ], [0.5 , 0.5 ], [1.0 , 0.5 ]])
14- empty_l = LG. readgeom (" LINESTRING EMPTY" )
15- ml1 = LG. MultiLineString ([[[0.0 , 0.0 ], [0.5 , 0.5 ], [1.0 , 0.5 ]], [[0.0 , 0.0 ], [0.0 , 0.1 ]]])
16- empty_ml = LG. readgeom (" MULTILINESTRING EMPTY" )
17- r1 = LG. LinearRing ([[0.0 , 0.0 ], [1.0 , 0.0 ], [1.0 , 2.0 ], [0.0 , 0.0 ]])
18- empty_r = LG. readgeom (" LINEARRING EMPTY" )
19- p1 = LG. Polygon ([
20- [[10.0 , 0.0 ], [30.0 , 0.0 ], [30.0 , 20.0 ], [10.0 , 20.0 ], [10.0 , 0.0 ]],
21- ])
22- p2 = LG. Polygon ([
23- [[10.0 , 0.0 ], [10.0 , 20.0 ], [30.0 , 20.0 ], [30.0 , 0.0 ], [10.0 , 0.0 ]],
24- [[15.0 , 1.0 ], [15.0 , 11.0 ], [25.0 , 11.0 ], [25.0 , 1.0 ], [15.0 , 1.0 ]],
25- ])
26- p3 = LG. Polygon ([
27- [[10.0 , 0.0 ], [10.0 , 20.0 ], [30.0 , 20.0 ], [30.0 , 0.0 ], [10.0 , 0.0 ]],
28- [[15.0 , 1.0 ], [25.0 , 1.0 ], [25.0 , 11.0 ], [15.0 , 11.0 ], [15.0 , 1.0 ]],
29- ])
30- p4 = LG. Polygon ([
31- [
32- [0.0 , 5.0 ], [2.0 , 2.0 ], [5.0 , 2.0 ], [2.0 , - 2.0 ], [5.0 , - 5.0 ],
33- [0.0 , - 2.0 ], [- 5.0 , - 5.0 ], [- 2.0 , - 2.0 ], [- 5.0 , 2.0 ], [- 2.0 , 2.0 ],
34- [0.0 , 5.0 ],
35- ],
36- ])
37- empty_p = LG. readgeom (" POLYGON EMPTY" )
38- mp1 = LG. MultiPolygon ([p2, p4])
39- empty_mp = LG. readgeom (" MULTIPOLYGON EMPTY" )
40- c = LG. GeometryCollection ([p1, p2, r1])
41- c_with_epty_l = LG. GeometryCollection ([p1, p2, r1, empty_l])
42- empty_c = LG. readgeom (" GEOMETRYCOLLECTION EMPTY" )
43-
44- # Simple square for testing
5+ # Basic geometries for testing
6+ point = LG. Point ([0.0 , 0.0 ])
7+ line = LG. LineString ([[0.0 , 0.0 ], [1.0 , 0.0 ], [1.0 , 1.0 ]])
458square = LG. Polygon ([[[0.0 , 0.0 ], [1.0 , 0.0 ], [1.0 , 1.0 ], [0.0 , 1.0 ], [0.0 , 0.0 ]]])
469
47- @testset_implementations " That handle empty geoms" begin
48- @test GO. perimeter ($ empty_pt) == 0
49- @test GO. perimeter ($ empty_mpt) == 0
50- @test GO. perimeter ($ empty_l) == 0
51- @test GO. perimeter ($ empty_ml) == 0
52- @test GO. perimeter ($ empty_r) == 0
53- @test GO. perimeter ($ empty_p) == 0
54- @test GO. perimeter ($ empty_mp) == 0
55- @test GO. perimeter (c_with_epty_l) ≈ GO. perimeter (c)
56- @test GO. perimeter (empty_c) == 0
57- end
58-
59- @testset " With GeometryCollection" begin
60- # Geometry collection summed perimeter
61- @test GO. perimeter (c) ≈ GO. perimeter (p1) + GO. perimeter (p2) + GO. perimeter (r1)
62- @test GO. perimeter (c, Float32) isa Float32
63- end
64-
65- @testset_implementations " all" begin
10+ @testset " Basic perimeter tests" begin
6611 # Points have zero perimeter
67- @test GO. perimeter ($ pt) == 0
68- @test GO. perimeter ($ pt) isa Float64
69- @test GO. perimeter ($ pt, Float32) isa Float32
70- @test GO. perimeter ($ mpt) == 0
71-
72- # Lines have non-zero perimeter (length)
73- @test GO. perimeter ($ l1) > 0
74- @test GO. perimeter ($ l1) ≈ sqrt (0.5 ^ 2 + 0.5 ^ 2 ) + sqrt (0.5 ^ 2 + 0.0 ^ 2 ) # Distance between points
75- @test GO. perimeter ($ ml1) > GO. perimeter ($ l1)
12+ @test GO. perimeter (point) == 0
7613
77- # Rings have non-zero perimeter
78- @test GO. perimeter ($ r1) > 0
79- @test GO. perimeter ($ r1) ≈ 1.0 + 2.0 + sqrt (1.0 ^ 2 + 2.0 ^ 2 ) # 3 sides of triangle
14+ # Lines have perimeter equal to their length
15+ @test GO. perimeter (line) == 2.0 # 1.0 + 1.0
8016
81- # Simple square perimeter test
82- @test GO. perimeter ($ square) ≈ 4.0 # Square with side length 1
83- @test GO. perimeter ($ square, Float32) isa Float32
84-
85- # Polygons have non-zero perimeter
86- @test GO. perimeter ($ p1) > 0
87- @test GO. perimeter ($ p1) ≈ 2 * 20.0 + 2 * 20.0 # Rectangle perimeter: 2*(width + height)
88-
89- # Polygon with hole
90- outer_perimeter = 2 * 20.0 + 2 * 20.0 # Same as p1
91- hole_perimeter = 2 * 10.0 + 2 * 10.0 # Hole perimeter
92- @test GO. perimeter ($ p2) ≈ outer_perimeter + hole_perimeter
93-
94- # Multipolygon calculations work
95- @test GO. perimeter ($ mp1) ≈ GO. perimeter ($ p2) + GO. perimeter ($ p4)
96- @test GO. perimeter ($ mp1, Float32) isa Float32
17+ # Square has perimeter of 4 (each side is 1)
18+ @test GO. perimeter (square) == 4.0
9719end
9820
99- @testset " Geodesic perimeter tests" begin
100- # Test geodesic perimeter on simple geometries
101- geodesic = GO. Geodesic ()
102-
103- # Simple square in geographic coordinates (degrees)
104- geo_square = LG. Polygon ([[[0.0 , 0.0 ], [1.0 , 0.0 ], [1.0 , 1.0 ], [0.0 , 1.0 ], [0.0 , 0.0 ]]])
105-
106- # Geodesic perimeter should be different from planar
107- planar_perim = GO. perimeter (GO. Planar (), geo_square)
108- geodesic_perim = GO. perimeter (geodesic, geo_square)
109- @test geodesic_perim != planar_perim
110- @test geodesic_perim > 0
111-
112- # Test type conversion
113- @test GO. perimeter (geodesic, geo_square, Float32) isa Float32
114-
115- # Test with a larger polygon that would show more difference
116- large_square = LG. Polygon ([[[0.0 , 0.0 ], [10.0 , 0.0 ], [10.0 , 10.0 ], [0.0 , 10.0 ], [0.0 , 0.0 ]]])
117- large_planar_perim = GO. perimeter (GO. Planar (), large_square)
118- large_geodesic_perim = GO. perimeter (geodesic, large_square)
119- @test large_geodesic_perim != large_planar_perim
120- @test large_geodesic_perim > 0
121-
122- # The geodesic perimeter should be larger than planar for this case
123- # (due to Earth's curvature over longer distances)
124- @test large_geodesic_perim > large_planar_perim
125- end
126-
127- @testset " Spherical perimeter tests" begin
128- # Test spherical perimeter calculations
129- spherical = GO. Spherical (radius = 6371000.0 ) # Earth radius in meters
130-
131- # Simple square in geographic coordinates
132- geo_square = LG. Polygon ([[[0.0 , 0.0 ], [1.0 , 0.0 ], [1.0 , 1.0 ], [0.0 , 1.0 ], [0.0 , 0.0 ]]])
133-
134- # Spherical perimeter should be different from planar
135- planar_perim = GO. perimeter (GO. Planar (), geo_square)
136- spherical_perim = GO. perimeter (spherical, geo_square)
137- @test spherical_perim != planar_perim
138- @test spherical_perim > 0
139-
140- # Test type conversion
141- @test GO. perimeter (spherical, geo_square, Float32) isa Float32
142- end
21+ @testset " Spherical and geodesic" begin
22+ highlat_poly = LG. Polygon ([[[70. , 70. ], [70. , 80. ], [80. , 80. ], [80. , 70. ], [70. , 70. ]]])
23+ @test GO. perimeter (GO. Planar (), highlat_poly) == 40
24+ @test GO. perimeter (GO. Planar (), highlat_poly) < GO. perimeter (GO. Spherical (), highlat_poly)
25+ @test GO. perimeter (GO. Spherical (), highlat_poly) < GO. perimeter (GO. Geodesic (), highlat_poly)
26+
27+ @test GO. area (GO. Planar (), highlat_poly) == 100
28+ @test GO. area (GO. Planar (), highlat_poly) < GO. area (GO. Geodesic (), highlat_poly)
29+ end
0 commit comments