Ponto mais próximo de uma linha (projeção esférica / Mercator)

9

Eu tenho uma linha (Ax, Ay - Bx, By) sobre uma projeção mercator (google maps) e um ponto aleatório (Cx, Cy) mais próximo dessa linha, gostaria de saber o ponto mais próximo (azul transparente na imagem) sobre essa linha para apontar (azul na imagem)

EDIT: para esclarecer que isso está em uma projeção Mercator (projeção esférica) insira a descrição da imagem aqui

Colas
fonte
3
Este post solução muito útil que pode interessar a você stackoverflow.com/questions/3120357/get-closest-point-to-a-line
Vinayan
11
Que o azul claro não parece o mais próximo, o mais próximo deve criar um ângulo de 90 graus quando conectado ao azul escuro, é isso que você quer dizer?
Glenn Plas
Fiz o pic à mão por isso sim, é posible
Colas
@vinayan A postagem que você faz referência resolve um problema diferente de encontrar o ponto mais próximo de uma linha , enquanto o que é necessário aqui parece querer o ponto mais próximo de um segmento de linha .
whuber
11
O segmento deve ser cerca de 20-100 metros de comprimento, o ponto de centímetros a 30 metros tanto do segmento
Colas

Respostas:

2

verifique este link , ele me fez usar a seguinte função para calcular distâncias para segmentos de linha.

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

Você pode usar as funções de projeção para calcular distâncias. Estou usando a fórmula acima para calcular o tempo nesse ponto, dada a velocidade média e funciona muito bem.

Se você deseja uma boa biblioteca PHP para calcular distâncias entre coordenadas no PHP, consulte a classe GeoCalc

Glenn Plas
fonte
Ei, Glenn Plas, sua classe parece ter um pequeno deslocamento para a esquerda ou para a direita. Eu fiz uma captura de tela no Google Earth. Você verá esse deslocamento, a foto: link , o código que eu usei.point_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))
Colas
Não é da minha classe, apenas encontrei depois de pesquisar muito ;-) Mas eu uso precisão de 8 dígitos nos meus problemas, você parece usar 6. Essa pode ser a razão, nunca notei nenhum deslocamento aqui. Obrigado por apontar, vou verificar novamente assim que precisar.
Glenn Plas
Talvez você está rihgt, eu não posso obter mais decilmas em gEarth, btw no meu último pic do segmento foi de 1000 metros de comprimento, o deslocamento foi ~ 110meters
Colas
É sobre a escala em que a uso, não mais do que isso. Eu o uso para ver a que horas um ônibus (transporte público) passa por uma parada o mais próximo. Vou verificar duas vezes e colocá-lo em um mapa para 'ver' se ele se projeta bem em uma esfera.
Glenn Plas
Oh ... Achei que essa função foi feita para projeções esféricas, então agora eu entendo o deslocamento
Colas
1

você pode usar a função computeDistanceBetween () da API do Google Map .

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

A distância entre dois pontos é o comprimento do caminho mais curto entre eles. Esse caminho mais curto é chamado de geodésico. Em uma esfera, todas as geodésicas são segmentos de um grande círculo. Para calcular essa distância, chame computeDistanceBetween (), passando dois objetos LatLng.

Em vez disso, você pode usar computeLength () para calcular o comprimento de um determinado caminho se você tiver vários locais

espero que ajude você ...

Aragão
fonte
primeiro eu preciso saber o ponto (azul claro) para calcular a distância entre
Colas
Minha solução abaixo faz isso, o ponto no segmento é desconhecido. Na verdade, tenho um problema / solução bastante semelhante ao mencionado. Você pode usá-los com segurança em pequenas escalas.
amigos estão dizendo sobre glenn