Android Question How to Calculate Polygon area ?

itgirl

Active Member
Licensed User
Longtime User
hello i used Google Maps Android v2 along with GoogleMapsExtra but i can't seem to find out how to calculate the area covered with the PolygonPoints , any ideas ?

and i have already tried Navigation lib with (FlatArea) and (SphericalArea) both return wrong values :(

292kv2c.jpg
 
Last edited:

itgirl

Active Member
Licensed User
Longtime User
You must have done something wrong... show what you did and I'll help you.

it's pretty simple what i've done

B4X:
Dim bbn As List
bbn.Initialize

bbn.Add("2598155.79,624532.89")
bbn.Add("2598135.75,624530.32")
bbn.Add("2598139.57,624500.56")
bbn.Add("2598157.20,624502.82")
bbn.Add("2598164.71,624530.46")


'bbn.Add("23.488764162834954,58.21954608191258")
'bbn.Add("23.488583381931885,58.21951925358826")
'bbn.Add("23.48862015974252,58.21922818386339")
'bbn.Add("23.488779220075564,58.219249230624335")
'bbn.Add("23.488844904033314,58.219523030232494")


Dim bb As Navigation
Log(bb.SphericalArea(bbn))


i've tried both latlong coordinates and northing easting coordinates with no luck :(
i've googled for a land coordinates along with the area i came up with these coordinates and it's 702 m2
 
Upvote 0

itgirl

Active Member
Licensed User
Longtime User
Only calculate or fill?
Amaziiiing work thanks works perfect it gave back 702.164 which is exactly the right area , i've saw your math similar on javascript but i didn't think it was the correct one , thank you so much you have made my day ;)
 
Upvote 0

derez

Expert
Licensed User
Longtime User
The list of UTM coordinates using FlatArea gives
7.021633000065371E-4
which is correct as the result is in SQR KM.
Lat Lon with Spherical gives a wrong result , I'll check why.
EDIT:
I translated the UTM coordinates and it shows slight differences. I checked with the translated Lat-Lon and it gives a closer result (959 sqr m). I guess the spherical area algo is too sensitive to rounding errors when working with such small area.

Just to explain - the SphericalArea method calculates area which is placed on a sphere (usually the globe), while FlatArea calculates a convex poligon on a plane. The curvature of Earth is actually nothing when the coordinates vary so close like the case above. The SpericalArea algorithm is a function of the sum of the internal angles of the poligon (which on a sphere is not (n-2)*180 degrees)
 
Last edited:
Upvote 0

itgirl

Active Member
Licensed User
Longtime User
The list of UTM coordinates using FlatArea gives
7.021633000065371E-4
which is correct as the result is in SQR KM.
Lat Lon with Spherical gives a wrong result , I'll check why.
EDIT:
I translated the UTM coordinates and it shows slight differences. I checked with the translated Lat-Lon and it gives a closer result (959 sqr m). I guess the spherical area algo is too sensitive to rounding errors when working with such small area.

yes you are right the FlatArea was the closest solution even though it was giving back 7.021633000065371E-4 and it should actually return 0.000702
but still the lat,long gives a wrong one well there's still a big difference between 959 sqr m and 702 sqr m. as you were saying if i'm working with a bigger area the results would be right ? how did you come up with the formula to calculate it if i may ask ? I'm pretty interested in this math, and thank you so much for the Navigation Lib it was a big help ;)
 
Upvote 0

derez

Expert
Licensed User
Longtime User
Look here http://mathworld.wolfram.com/SphericalPolygon.html which say :
Spherical Polygon
A closed geometric figure on the surface of a sphere which is formed by the arcs of great circles. The spherical polygon is a generalization of the spherical triangle. If
Inline1.gif
is the sum of the radian angles of a spherical polygon on asphere of radius
Inline2.gif
, then the area is

NumberedEquation1.gif

The algorithm in the lib (I don't remember where found, but except for the addition of excentricity
B4X:
Rs = 6378.137 / Math.pow((1+es*Math.sin(phis)*Math.sin(phis)),0.5);  // km
the code is implementation of the above formula, where the angle between two lines is by the Bearing function which finds the great arc's azimuth between two points.
I attach the method's code:
/**
* The methods calculates the area on the Earth's spherical enclosed inside a polygon
* which is defined in the list parameter.
* Every list item should be a string of the form "Lat,Long".
* The returned area is in square Km.
*/
public double SphericalArea(List<String> GEOlist)
{
double meanlat = 0;
int n = GEOlist.size() ;
String []str = new String[2] ;
double [][] points = new double[n][2] ; // new array because the content must change
for (int i = 0;i<n;i++)
{
str = GEOlist.get(i).split(",") ;
points[0] = Double.valueOf(str[0])* deg2rad ; // allocation by the index
points[1] = Double.valueOf(str[1])* deg2rad ;
meanlat += points[0];
}
meanlat = meanlat/n ;
return Spherical(points , n, 0, 1, meanlat);
}

private double Spherical(double [][] points , int n, int UindxX, int UindxY, double meanlat)
{
double sum1,sum2,Rs,phis ;

double es = 0.0067394967423 ; // eccentricity
double twoPi = 2 * Math.PI ;
phis = Math.atan(Math.tan(meanlat)/(1+es));
Rs = 6378.137 / Math.pow((1+es*Math.sin(phis)*Math.sin(phis)),0.5); // km
// find angles for point 0
double f1 = Bearing(points[0][0],points[0][1],points[1][0],points[1][1]);
double f2 = Bearing(points[0][0],points[0][1],points[n-1][0],points[n-1][1]);
sum1 = (f1 + twoPi - f2)%twoPi;
sum2 = (f2 + twoPi - f1)%twoPi;
// find angles for point n-1
f1 = Bearing(points[n-1][0],points[n-1][1],points[0][0],points[0][1]);
f2 = Bearing(points[n-1][0],points[n-1][1],points[n-2][0],points[n-2][1]) ;
sum1 += (f1 + twoPi - f2)%twoPi;
sum2 += (f2 + twoPi - f1)%twoPi;
// find angles for the intermediate points
for (int i = 1;i<n-1;i++)
{
f1 = Bearing(points[0],points[1],points[i+1][0],points[i+1][1]);
f2 = Bearing(points[0],points[1],points[i-1][0],points[i-1][1]);
sum1 += (f1 + twoPi - f2)%twoPi;
sum2 += (f2 + twoPi - f1)%twoPi;
}
sum1 = Math.min(sum1,sum2) ; // the minimun is the internal angles sum
return Math.abs((Math.abs(sum1)-(n-2)*Math.PI)) * Rs*Rs ;// in sqr km
}
7.021633000065371E-4 and it should actually return 0.000702
This is the same except for rounding (E-4) !

as you were saying if i'm working with a bigger area the results would be right ?

In the example of the lib use I have the Sea of Galilae as the poligon and get for flat area 160.02777 SQR KM and for spherical area 160.05543. There will always be some difference, especially when taking into consideration that translating geo to utm is not clean of truncation errors as well.
 
Last edited:
Upvote 0

derez

Expert
Licensed User
Longtime User
Tested the results using a square of 1 Km and got results 0f 1 (flat) and 1.002709 (spherical).
The spherical method should correctly give larger area in all case. I guess that from this area and up you get quite reasonable results.
B4X:
Sub test
Dim glist, ulist As List
glist.Initialize
ulist.Initialize
Dim d() As Double
Dim ux(4),uy(4) As Double

ux(0) = 625000
ux(1) = ux(0)
ux(2) = 626000
ux(3) = ux(2)

uy(0) = 2595000
uy(1) = 2596000
uy(2) = uy(1)
uy(3) = uy(0)

ulist.Add(ux(0) & "," & uy(0))
ulist.Add(ux(1) & "," & uy(1))
ulist.Add(ux(2) & "," & uy(2))
ulist.Add(ux(3) & "," & uy(3))

d = nav.UTMToLatLon(6378137,1/298.257223563,40,ux(0),True,uy(0))
glist.Add(d(0) & "," & d(1))
d = nav.UTMToLatLon(6378137,1/298.257223563,40,ux(1),True,uy(1))
glist.Add(d(0) & "," & d(1))
d = nav.UTMToLatLon(6378137,1/298.257223563,40,ux(2),True,uy(2))
glist.Add(d(0) & "," & d(1))
d = nav.UTMToLatLon(6378137,1/298.257223563,40,ux(3),True,uy(3))
glist.Add(d(0) & "," & d(1))
Log(nav.FlatArea(ulist))
Log(nav.SphericalArea(glist))
End Sub

With square of 100 m it is still OK but when checking a square 0f 50 m the result of the spherical runs away...
 
Last edited:
Upvote 0

itgirl

Active Member
Licensed User
Longtime User
Look here http://mathworld.wolfram.com/SphericalPolygon.html which say :


The algorithm in the lib (I don't remember where found, but except for the addition of excentricity
B4X:
Rs = 6378.137 / Math.pow((1+es*Math.sin(phis)*Math.sin(phis)),0.5);  // km
the code is implementation of the above formula, where the angle between two lines is by the Bearing function which finds the great arc's azimuth between two points.
I attach the method's code:

This is the same except for rounding (E-4) !


In the example of the lib use I have the Sea of Galilae as the poligon and get for flat area 160.02777 SQR KM and for spherical area 160.05543. There will always be some difference, especially when taking into consideration that translating geo to utm is not clean of truncation errors as well.



translating geo to utm is not clean of truncation errors as well
yes you are correct on this one i have searched alot and came up with that.

i think your method is slightly different from the one i was looking into even though each method return incorrect data but still close enough,
thank you for taking time to explain everything and thanks for the code it will come in handy
 
Upvote 0
Top