Nächster Punkt auf einer Linie (sphärische / Mercator-Projektion)


9

Ich habe eine Linie (Axe, Ay - Bx, By) über einer Mercator-Projektion (Google Maps) und einen zufälligen Punkt (Cx, Cy) , der dieser Linie am nächsten liegt. Ich würde den nächsten Punkt (transparentes Blau auf dem Bild) darüber kennen diese Linie zum Punkt (blau im Bild)

BEARBEITEN: um zu verdeutlichen, dass es sich um eine Mercator-Projektion handelt (sphärische Projektion) Geben Sie hier die Bildbeschreibung ein


3
Dieser Beitrag hat eine sehr nützliche Lösung, die Sie interessieren könnte stackoverflow.com/questions/3120357/get-closest-point-to-a-line
vinayan

1
Das Hellblau sieht nicht wie das nächste aus, das nächste sollte einen 90-Grad-Winkel erzeugen, wenn es mit dem Dunkelblau verbunden ist. Ist es das, was Sie meinen?
Glenn Plas

Ich habe das Bild von Hand gemacht, also ja, es ist möglich
Colas

@vinayan Der Beitrag, auf den Sie verweisen, löst ein anderes Problem beim Finden des nächstgelegenen Punkts zu einer Linie , während das, was hier benötigt wird, den nächstgelegenen Punkt zu einem Liniensegment zu wollen scheint .
whuber

1
Das Segment sollte ungefähr 20-100 Meter lang sein, der Punkt von Zentimetern bis 30 Metern so weit vom Segment entfernt
Colas

Antworten:


2

Schauen Sie sich diesen Link an . Ich habe die folgende Funktion verwendet, um Entfernungen zu Liniensegmenten zu berechnen.

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

Sie können dann Projektionsfunktionen verwenden, um Entfernungen zu berechnen. Ich verwende die obige Formel, um die Zeit zu diesem Zeitpunkt bei einer Durchschnittsgeschwindigkeit zu berechnen, und es funktioniert wirklich gut.

Wenn Sie möchten, dass eine gute PHP-Bibliothek Entfernungen zwischen Koordinaten in PHP berechnet, lesen Sie die GeoCalc-Klasse


Hey Glenn Plas, deine Klasse scheint einen kleinen Versatz nach links oder rechts zu haben. Ich habe einen Screenshot auf Google Earth gemacht. Du wirst diesen Versatz sehen, das Bild: Link , den Code, den ich verwendet habepoint_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas

Es ist nicht meine Klasse, ich habe es nur gefunden, nachdem ich viel gesucht habe ;-) Aber ich benutze 8 Stellen Genauigkeit bei meinen Problemen, Sie scheinen 6 zu verwenden. Das könnte der Grund sein, ich habe hier nie einen Versatz bemerkt. Vielen Dank für den Hinweis, ich werde dies überprüfen, sobald ich es wissen muss.
Glenn Plas

Vielleicht bist du rihgt, ich kann nicht mehr Dezilme auf gEarth erhalten, übrigens in meinem letzten Bild war das Segment 1000 Meter lang, der Versatz war ~ 110 Meter
Colas

Das ist ungefähr die Skala, auf der ich es benutze, nicht mehr als das. Ich benutze es, um zu sehen, wann ein Bus (öffentliche Verkehrsmittel) am nächsten an einer Haltestelle vorbeifährt. Ich werde es jedoch noch einmal überprüfen und in eine Karte einfügen, um zu sehen, ob es gut auf eine Kugel projiziert.
Glenn Plas

Oh ... Ich dachte, dass diese Funktion für sphärische Projektionen gemacht wurde, also verstehe ich jetzt den Versatz
Colas

1

Sie können die Funktion computeDistanceBetween () über die Google Map-API verwenden .

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

Der Abstand zwischen zwei Punkten ist die Länge des kürzesten Weges zwischen ihnen. Dieser kürzeste Weg wird als geodätisch bezeichnet. Auf einer Kugel sind alle Geodäten Segmente eines Großkreises. Um diese Entfernung zu berechnen, rufen Sie computeDistanceBetween () auf und übergeben Sie zwei LatLng-Objekte.

Sie können stattdessen computeLength () verwenden, um die Länge eines bestimmten Pfads zu berechnen, wenn Sie mehrere Standorte haben

ich hoffe es hilft dir ...


Zuerst muss ich den Punkt (hellblau) kennen, um die Entfernung zwischen
Colas

Meine Lösung unten macht das, der Punkt auf dem Segment ist unbekannt. Ich habe tatsächlich ein ziemlich ähnliches Problem / eine ähnliche Lösung wie erwähnt. Sie können diese sicher in kleinen Maßstäben verwenden.
Glenn Plas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.