Punto più vicino su una linea (proiezione sferica / di Mercatore)


9

Ho una linea (Ax, Ay - Bx, By) su una proiezione di un mercatore (google maps) e un punto casuale (Cx, Cy) più vicino a quella linea, vorrei conoscere il punto più vicino (blu trasparente sull'immagine) sopra quella linea da puntare (blu nell'immagine)

EDIT: chiarire che questo è in una proiezione di Mercatore (proiezione sferica) inserisci qui la descrizione dell'immagine


3
Questo post è una soluzione molto utile che potrebbe interessarti stackoverflow.com/questions/3120357/get-closest-point-to-a-line~~V~~singular~~2nd
Vinayan

1
Quel blu chiaro non sembra il più vicino, il più vicino dovrebbe creare un angolo di 90 gradi quando è collegato al blu scuro, è questo che vuoi dire?
Glenn Plas,

Ho fatto la foto a mano, quindi sì, è possibile
Colas,

@vinayan Il post a cui fai riferimento risolve un diverso problema nel trovare il punto più vicino a una linea , mentre ciò che è necessario qui sembra voler il punto più vicino a un segmento di linea .
whuber

1
Il segmento dovrebbe essere lungo circa 20-100 metri, il punto da centimetri a 30 metri tanto dal segmento
Colas,

Risposte:


2

controlla questo link , mi ha fatto usare la seguente funzione per calcolare le distanze dai segmenti di linea.

In PHP:

function point_to_line_segment_distance($startX,$startY, $endX,$endY, $pointX,$pointY) {

   // list($distanceSegment, $x, $y) = point_to_line_segment_distance($startX,$startY, $endX,$endY, $pointX,$pointY);

    // Adapted from Philip Nicoletti's function, found here: http://www.codeguru.com/forum/printthread.php?t=194400

    $r_numerator = ($pointX - $startX) * ($endX - $startX) + ($pointY - $startY) * ($endY - $startY);
    $r_denominator = ($endX - $startX) * ($endX - $startX) + ($endY - $startY) * ($endY - $startY);
    $r = $r_numerator / $r_denominator;

    $px = $startX + $r * ($endX - $startX);
    $py = $startY + $r * ($endY - $startY);

    $s = (($startY-$pointY) * ($endX - $startX) - ($startX - $pointX) * ($endY - $startY) ) / $r_denominator;

    $distanceLine = abs($s) * sqrt($r_denominator);

    $closest_point_on_segment_X = $px;
    $closest_point_on_segment_Y = $py;

    if ( ($r >= 0) && ($r <= 1) ) {
       $distanceSegment = $distanceLine;
    }
    else {
       $dist1 = ($pointX - $startX) * ($pointX - $startX) + ($pointY - $startY) * ($pointY - $startY);
       $dist2 = ($pointX - $endX) * ($pointX - $endX) + ($pointY - $endY) * ($pointY - $endY);
       if ($dist1 < $dist2) {
          $closest_point_on_segment_X = $startX;
          $closest_point_on_segment_Y = $startY;
          $distanceSegment = sqrt($dist1);
       }
       else {
          $closest_point_on_segment_X = $endX;
          $closest_point_on_segment_Y = $endY;
          $distanceSegment = sqrt($dist2);
       }
    }

    return array($distanceSegment, $closest_point_on_segment_X, $closest_point_on_segment_Y);
}

È quindi possibile utilizzare le funzioni di proiezione per calcolare le distanze, sto usando la formula sopra per calcolare il tempo in quel punto data una velocità media e funziona davvero bene.

Se vuoi che una buona libreria PHP calcoli le distanze tra le coordinate in PHP, controlla la classe GeoCalc


Ehi Glenn Plas, la tua classe sembra avere un piccolo offset a sinistra oa destra, ho fatto uno screenshot su Google Earth che vedrai quell'offset, la foto: link , il codice che ho usatopoint_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas,

Non è la mia classe, l'ho appena trovata dopo aver cercato molto ;-) Ma uso una precisione di 8 cifre nei miei problemi, sembra che tu ne usi 6. Questo potrebbe essere il motivo, non ho mai notato alcun offset qui. Grazie per averlo sottolineato, lo ricontrollerò non appena dovrò saperlo.
Glenn Plas,

Forse stai rihgt, non riesco a ottenere più decilma su gEarth, tra l'altro nella mia ultima foto il segmento era lungo 1000 metri, l'offset era ~ 110meters
Colas,

Riguarda la scala su cui lo uso, non di più. Lo uso per vedere a che ora un autobus (trasporto pubblico) passa una fermata il più vicino. Ho intenzione di ricontrollarlo e metterlo in una mappa per "vedere" se si proietta bene su una sfera.
Glenn Plas,

Oh ... pensavo che quella funzione fosse fatta per le proiezioni sferiche, quindi ora capisco l'offset
Colas,

1

puoi usare la funzione computeDistanceBetween () da api map google .

distance = google.maps.geometry.spherical.computeDistanceBetween(firstCoord, secondCoord);

La distanza tra due punti è la lunghezza del percorso più breve tra di loro. Questo percorso più breve è chiamato geodetico. Su una sfera tutti i geodetici sono segmenti di un grande cerchio. Per calcolare questa distanza, chiama computeDistanceBetween (), passandogli due oggetti LatLng.

È possibile invece utilizzare computeLength () per calcolare la lunghezza di un determinato percorso se si dispone di più posizioni

spero che ti aiuti ...


per prima cosa ho bisogno di conoscere il punto (azzurro) per calcolare la distanza tra
Colas,

La mia soluzione qui sotto lo fa, il punto sul segmento è sconosciuto. In realtà ho un problema / soluzione piuttosto simile a quello menzionato. Puoi tranquillamente utilizzarli su piccola scala.
Glenn Plas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.