TransWikia.com

Math formula to calculate GPS location for weighted GPS data points

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));

One Answer

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:

  1. If any of the weights are 100, only return that point
  2. Otherwise, return a duplicate number of points equal to the weight

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP