Formula matematica per calcolare la posizione GPS per punti dati GPS ponderati

Aug 25 2020

Sto lavorando per migliorare la posizione e la precisione di un'applicazione basata su mappa/punto dati.

Ho una raccolta di luoghi di interesse. Ogni posizione di interesse ha una raccolta di punti dati che includono lat/long e sono ponderati da 1 a 100. 100 significa che deve essere utilizzata la posizione esatta e 1 significa che questa posizione deve essere considerata la minima nell'output di qualsiasi formula per trovare il centro del luogo di interesse.

Come posso trovare il centro della posizione di interesse includendo i pesi per migliorare la precisione?

Ho trovato un esempio di codice per calcolarlo ma non considera i pesi nei punti dati.

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

Risposte

jgm_GIS Aug 26 2020 at 01:48

Devi decidere se i pesi sono lineari, esponenziali, logaritmici, ecc.

Un modo semplice per farlo, assumendo che i pesi siano lineari, sarebbe quello di passare un elenco di punti a una funzione che utilizzi la seguente logica:

  1. Se uno qualsiasi dei pesi è 100, restituire solo quel punto
  2. Altrimenti, restituisci un numero duplicato di punti uguale al peso

Potresti anche restituire un numero di punti uguale a ln(peso), peso^2, ecc.

Ecco un'implementazione di Python che non dovrebbe essere difficile da portare su js. Accetta un elenco di elenchi di punti con il formato [[lat, lon, peso], [lat, lon, peso], ecc.]

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

Puoi verificarlo passando elenchi di punti come lat_lon = [[90, 70, 3], [-40, 0, 1], [0, -100, 10]] o lat_lon = [[90, 70, 3 ], [-40, 0, 100], [0, -100, 10]]