Based on this site: https://carto.com/blog/center-of-points/ i try to calculate the weighted average for a set of lon/lat points. The site shows the calculation in SQL-code, and i specifically look at the test data set as follows:
Data Table
country lat lon
------- -------- ---------
Tonga -21.1333 -175.2
Tuvalu -8.53333 179.2167
Where the result is:
avg_lon avg_lon_naive avg_lat
------- ------------- -------
-177.992 2.00833 -14.9333
Now i try to convert this to javascript like this:
// Calculate weighted average of points in lat/lon
// mypoint = [lat, lon ]
var mypoint1 = [-21.1333, -175.2];
var mypoint2 = [-8.53333, 179.2167];
//Weighted LON
var zeta = (Math.sin(Math.PI * mypoint1[1] / 180) + Math.sin(Math.PI *
mypoint2[1] / 180)) / 2;
console.log(zeta);
var xi = (Math.cos(Math.PI * mypoint1[1] / 180) + Math.sin(Math.PI *
mypoint2[1] / 180)) / 2;
console.log(xi);
var avglon = 180 * Math.atan2(zeta, xi) / Math.PI;
console.log("Average longitude: " + avglon);
//Weighted LAT
var avglat = (mypoint1[0] + mypoint2[0]) / 2;
console.log("Average latitude: " + avglat);
Which yields this result:
-0.03500355257793927
-0.49141106053653333
Average longitude: -175.92566317222995
Average latitude: -14.833314999999999
Press any key to continue...
Why do i get a different result in my JavaScript case? Have i done something wrong in the code? Missed something, some conversion or similar?
Or is there any difference in atan2 or PI in sql vs JavaScript?
Any pointers would be highly appreciated.
Edit: For the LAT calculation I have started to believe that the original post has error. Since the Lat calculation is relatively easy, we can see that:
2 x -14.9333 = 29,8666
Which is not the result of the original lat points given
-21.1333 +(-8.53333) = -29.6666299
Actually, I think that both methods are not correct. On a sphere I'd average the 3D vectors. In python that would look like:
import numpy as np
DEGREE = np.pi/180.
RAD = 1./DEGREE
def lon_lat_naive( inList ):
return np.mean( inList,axis=0)
def lon_lat_full_vector( inList ):
vec = [ [ np.cos( lat * DEGREE ) * np.cos( lon * DEGREE ), np.cos(lat* DEGREE ) * np.sin( lon * DEGREE ), np.sin( lat * DEGREE ) ] for lon, lat in inList ]
# ~ print vec
vec = np.sum( vec, axis=0)
vec /= np.linalg.norm( vec )
# ~ print vec
lat = np.arcsin( vec[2] ) * RAD
lon = np.arctan2( vec[1], vec[0] ) * RAD
return [ lon, lat ]
a = np.array( [10, 60 ])
b = np.array( [20, 80 ])
print( lon_lat_naive( np.array( [ a, b ] ) ) )
print( lon_lat_full_vector( np.array( [ a, b ] ) ) )
Tonga = np.array( [ -175.2, -21.1333 ])
Tuvalu = np.array( [ 179.2167, -8.53333 ])
tt = np.array( [Tonga, Tuvalu ] )
print( lon_lat_naive( tt ) )
print( lon_lat_full_vector( tt ) )
providing:
[15. 70.]
[12.573012941928377, 70.05362118882975]
[ 2.00835 -14.833315]
[-178.07333636886855, -14.850146658102775]
which is different from both, yours and the web page, but should give you---in the case of the two points---the midpoint of the arc connecting the two.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.