Geographic Information Systems Asked on February 12, 2021
I’m working to improve the location and accuracy of a map / data-point driven application.
I have a collection of locations of interest. Each location of interest has a collection of data points that include lat/long and are weighted from 1 to 100. 100 means the exact location should be used and 1 means this location should be considered the least in the output of whatever formula to find the center of the location of interest.
How can I find the center of the location of interest while including the weights to help improve accuracy?
I found a code sample to calculate this but it doesn’t consider weights in the data points.
/**
* Calculate the center/average of multiple GeoLocation coordinates
* Expects an array of objects with .latitude and .longitude properties
*
* @url http://stackoverflow.com/a/14231286/538646
*/
function averageGeolocation(coords) {
if (coords.length === 1) {
return coords[0];
}
let x = 0.0;
let y = 0.0;
let z = 0.0;
for (let coord of coords) {
let latitude = coord.latitude * Math.PI / 180;
let longitude = coord.longitude * Math.PI / 180;
x += Math.cos(latitude) * Math.cos(longitude);
y += Math.cos(latitude) * Math.sin(longitude);
z += Math.sin(latitude);
}
let total = coords.length;
x = x / total;
y = y / total;
z = z / total;
let centralLongitude = Math.atan2(y, x);
let centralSquareRoot = Math.sqrt(x * x + y * y);
let centralLatitude = Math.atan2(z, centralSquareRoot);
return {
latitude: centralLatitude * 180 / Math.PI,
longitude: centralLongitude * 180 / Math.PI
};
}
// expect ~ 37.790831, -122.407169
const sf = [{
latitude: 37.797749,
longitude: -122.412147
}, {
latitude: 37.789068,
longitude: -122.390604
}, {
latitude: 37.785269,
longitude: -122.421975
}];
console.log(averageGeolocation(sf));
// expect ~ 8.670552, -173.207864
const globe = [{ // Japan
latitude: 37.928969,
longitude: 138.979637
}, { // Nevada
latitude: 39.029788,
longitude: -119.594585
}, { // New Zealand
latitude: -39.298237,
longitude: 175.717917
}];
console.log(averageGeolocation(globe));
You need to decide if the weights are linear, exponential, logarithmic, etc.
A simple way to do this, assuming weights are linear, would be to pass a list of points to a function that would use the following logic:
You could also return a number of point equal to ln(weight), weight^2, etc.
Here is a python implementation which shouldn't be hard to port to js. It accepts a list of lists of points with the format [[lat, lon, weight], [lat, lon, weight], etc]
def weighted_point(lat_lon):
weighted_lat_lon = []
for coord in lat_lon:
weight = coord[-1]
if weight == 100:
#weighted_lat_lon = [[coord[0], coord[1]]]
#stop looping through points is a weight is 100
return([[coord[0], coord[1]]])
else:
i = 0
for i in range(weight):
weighted_lat_lon.append([coord[0], coord[1]])
return weighted_lat_lon
You can test this by passing lists of points such as lat_lon = [[90, 70, 3], [-40, 0, 1], [0, -100, 10]] or lat_lon = [[90, 70, 3], [-40, 0, 100], [0, -100, 10]]
Answered by jgm_GIS on February 12, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP