1+ import GeometryOps: perimeter, area, applyreduce, TraitTarget, WithTrait
2+ import GeoInterface as GI
3+
4+ function perimeter (m:: Geodesic , geom, :: Type{T} = Float64; init = zero (T), kwargs... ) where T
5+ # Create a Proj geodesic object using the ellipsoid parameters from the Geodesic manifold
6+ proj_geodesic = Ref (Proj. geod_geodesic (m. semimajor_axis, 1 / m. inv_flattening))
7+ proj_polygon = Ref (Proj. _null (Proj. geod_polygon))
8+
9+ function _perimeter_geodesic_inner (trait, geom)
10+ @assert GI. npoint (geom) >= 2 " Geodesic perimeter requires at least 2 points"
11+
12+ # Initialize the polygon
13+ proj_polygon[] = Proj. _null (Proj. geod_polygon)
14+ Proj. geod_polygon_init (proj_polygon, 1 )
15+
16+ # Add all points to the polygon
17+ for point in GI. getpoint (trait, geom)
18+ lat, lon = GI. y (point), GI. x (point) # Proj expects lat, lon order
19+ Proj. geod_polygon_addpoint (proj_geodesic, proj_polygon, lat, lon)
20+ end
21+
22+ # Compute the polygon properties
23+ # geod_polygon_compute returns (num_vertices, perimeter, area)
24+ area_result, perimeter_result = Proj. geod_polygon_compute (proj_geodesic[], proj_polygon[], false , true )
25+
26+ return T (perimeter_result)
27+ end
28+
29+ return applyreduce (
30+ WithTrait (_perimeter_geodesic_inner),
31+ + ,
32+ TraitTarget (GI. AbstractCurveTrait),
33+ geom; init, kwargs...
34+ )
35+ end
36+
37+ function GeometryOps. area (m:: Geodesic , geom, :: Type{T} = Float64; threaded = False (), init = zero (T), kwargs... ) where T
38+ # Create a Proj geodesic object using the ellipsoid parameters from the Geodesic manifold
39+ proj_geodesic = Ref (Proj. geod_geodesic (m. semimajor_axis, 1 / m. inv_flattening))
40+ proj_polygon = Ref (Proj. _null (Proj. geod_polygon))
41+
42+ function _area_geodesic_inner (trait, geom)
43+ @assert GI. npoint (geom) >= 2 " Geodesic perimeter requires at least 2 points"
44+
45+ # Initialize the polygon
46+ proj_polygon[] = Proj. _null (Proj. geod_polygon)
47+ Proj. geod_polygon_init (proj_polygon, 0 )
48+
49+ # Add all points to the polygon
50+ for point in GI. getpoint (trait, geom)
51+ lat, lon = GI. y (point), GI. x (point) # Proj expects lat, lon order
52+ Proj. geod_polygon_addpoint (proj_geodesic, proj_polygon, lat, lon)
53+ end
54+
55+ # Compute the polygon properties
56+ # geod_polygon_compute returns (num_vertices, perimeter, area)
57+ area_result, perimeter_result = Proj. geod_polygon_compute (proj_geodesic[], proj_polygon[], true , false )
58+
59+ return T (area_result)
60+ end
61+
62+ return applyreduce (
63+ WithTrait (_area_geodesic_inner),
64+ + ,
65+ TraitTarget (GI. AbstractCurveTrait),
66+ geom; init, kwargs...
67+ )
68+ end
0 commit comments