Calculate area of polygon

You need a source to find the area of ​​a polygon.

1 Like

Hi,

As far as I know, there is no direct and public function in Cesium to do this. However, this knowledge might be outdated, so anyone feel free to correct me!

What we do to calculate the area of polygons is to use the private Cesium class PolygonPipeline.
You an find the source here: https://github.com/CesiumGS/cesium/blob/main/Source/Core/PolygonPipeline.js

We actually use the triangulate function and then perform some calculations based on that.
But the class also contains a function computeArea2D. Maybe that’s sufficient for your case?
You would call it like this: Cesium.PolygonPipeline.computeArea2D(<your positions array>).

Disclaimer: As the class is private, it is probably not intended for direct use. So be aware of that. I don’t know of there are any caveats to look out for because of this.

If this doesn’t fit your needs, you might have to do this without the use of Cesium (at least for the pure calculation). Then any resource found on the internet should help. For example this StackOverflow question:

Hi @11167,

to extend @UniquePanda’s reply, i want to share some code you can use to get the area of a polygon. As already stated, you have to use some private calsses:

		let polygon = entity.polygon;
		let hierarchy = polygon.hierarchy._value;
		let indices = Cesium.PolygonPipeline.triangulate(hierarchy.positions, hierarchy.holes);
		let area = 0;
		for (let i = 0; i < indices.length; i += 3) {
			let vector1 = hierarchy.positions[indices[i]];
			let vector2 = hierarchy.positions[indices[i+1]];
			let vector3 = hierarchy.positions[indices[i+2]];			
			let vectorC = Cesium.Cartesian3.subtract(vector2, vector1, new Cesium.Cartesian3());
			let vectorD = Cesium.Cartesian3.subtract(vector3, vector1, new Cesium.Cartesian3());			
			let areaVector = Cesium.Cartesian3.cross(vectorC, vectorD, new Cesium.Cartesian3());			
			area += Cesium.Cartesian3.magnitude(areaVector)/2.0;
		}

Best, Lennart

2 Likes

You can certainly do this using some manual arithmetic, or you can use a turf library. You already have a linear-ring of positions from your hierarchy, you just need to convert them to decimal degrees, then into a Turf polygon (which is just GeoJSON). The great thing about Turf is that you can find just about any geospatial operation you might want to compute in the complete docs, then grab only the relatively tiny modules for those functions individually via NPM.

1 Like

Thanks for this suggestion!

Do Turf handle the 3rd dimension, or is the height information lost during conversion?
(If I have a “oblique” polygon, the area differ from the area of a flat one)

Sorry, I haven’t had a chance to test it. It’s supposed to work against any GeoJSON so I would say that if it does ignore elevation, that would be a bug and I’d report it.

Hello @11167 .
I had a similar question some time ago and my solution is I use a “cutout” for a triangular polygon (if the polygon is not flat - the area may differ from the 2d projection, whereas the triangle is always flat in any projection)

then I calculate the area for each triangle using Heron’s formula
S=sqrt{p*(p-a)(p-b)(p-c)}
at the end I sum up all the areas.
I used this for a drawing tool and it worked well on a globe with heights. True, my figures did not contain more than a few dozen triangles in the end.
I hope this helps you.