Bir hatta en yakın nokta (Küresel / Mercator projeksiyonu)


9

Bir mercator projeksiyonu (google maps) ve bu çizgiye en yakın rastgele bir nokta (Cx, Cy ) üzerinde bir çizgi (Axe, Ay - Bx, By) var , ben en yakın noktayı (görüntüdeki şeffaf mavi) bilmek istiyorum bu çizgiden noktaya (resimde mavi)

EDIT: Bunun bir Mercator projeksiyonunda olduğunu (küresel projeksiyon) açıklığa kavuşturmak için resim açıklamasını buraya girin


3
bu gönderi ilginizi çekebilecek çok yararlı bir çözüme sahiptir stackoverflow.com/questions/3120357/get-closest-point-to-a-line
vinayan

1
Bu açık mavi en yakın gibi görünmüyor, koyu maviye bağlandığında en yakın 90 derece açı oluşturmalı, demek istediğin bu mu?
Glenn Plas

Fotoğrafı elle yaptım, bu yüzden mümkün
Colas

@vinayan Gönderdiğiniz gönderi, bir satıra en yakın noktayı bulma konusunda farklı bir sorunu çözerken , burada ihtiyaç duyulan şey bir satır segmentine en yakın noktayı istiyor gibi görünüyor .
whuber

1
Segment yaklaşık 20-100 metre uzunluğunda olmalıdır, nokta santimetreden 30 metreye kadar olan nokta
Colas

Yanıtlar:


2

Bu bağlantıyı kontrol edin , çizgi segmentlerine olan mesafeleri hesaplamak için aşağıdaki işlevi kullanmamı sağladı.

PHP dilinde:

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

Daha sonra mesafeleri hesaplamak için projeksiyon işlevlerini kullanabilirsiniz, ortalama bir hız verilen bu noktada zamanı hesaplamak için yukarıdaki formülü kullanıyorum ve gerçekten iyi çalışıyor.

İyi bir PHP kütüphanesinin PHP koordinatları arasındaki mesafeleri hesaplamasını istiyorsanız, GeoCalc sınıfına göz atın


Hey Glenn Plas, sınıfın sol veya sağa biraz ofset var gibi görünüyor , Google Earth'te bir ekran görüntüsü yaptım, bu görseli göreceksin, pic: link , kullandığım kodpoint_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas

Sınıfım değil, sadece çok aradıktan sonra buldum ;-) Ama sorunlarımda 8 basamaklı hassasiyet kullanıyorum, 6 kullanıyorsunuz. Bu sebep olabilir, burada hiçbir fark görmedim. İşaret ettiğiniz için teşekkürler, bilmem gerekene kadar bunu iki kez kontrol edeceğim.
Glenn Plas

Belki sen rihgt, gEarth üzerinde daha fazla decilmas elde edemiyorum, son resmimde btw segment 1000 metre uzunluğunda, ofset ~ 110meters
Colas

Bu, kullandığım ölçekle ilgili, bundan daha fazlası değil. Bir otobüsün (toplu taşıma) en yakın duraktan ne zaman geçtiğini görmek için kullanıyorum. Yine de iki kez kontrol edeceğim ve bir küreye iyi yansıtıp yansıtmadığını görmek için bir haritaya koyacağım.
Glenn Plas

Oh ... Bu fonksiyonun küresel projeksiyonlar için yapıldığını düşündüm, bu yüzden şimdi ofseti anlıyorum
Colas

1

google map api'den computeDistanceBetween () işlevini kullanabilirsiniz .

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

İki nokta arasındaki mesafe, aralarındaki en kısa yolun uzunluğudur. Bu en kısa yola jeodezik denir. Bir kürede, tüm jeodezikler büyük bir dairenin parçalarıdır. Bu mesafeyi hesaplamak için, iki LatLng nesnesini ileterek computeDistanceBetween () öğesini çağırın.

Bunun yerine, birden fazla konumunuz varsa belirli bir yolun uzunluğunu hesaplamak için computeLength () kullanabilirsiniz.

umarım sana yardımcı olur ...


önce arasındaki mesafeyi hesaplamak için noktayı (açık mavi) bilmeliyim
Colas

Aşağıdaki çözümüm bunu yapıyor, segmentteki nokta bilinmiyor. Aslında bahsettiğim gibi oldukça benzer bir sorun / çözümüm var. Bunları küçük ölçeklerde güvenle kullanabilirsiniz.
Glenn Plas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.