Cálculo de distância entre locais usando coordenadas

hum…

acho que essa função funciona também:

[code]public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;

return dist; 
} [/code]

em milhas, ai só converter para kilometros

[quote=douglaskd]hum…

acho que essa função funciona também:

[code]public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;

return dist; 
} [/code]

em milhas, ai só converter para kilometros[/quote]

Bacana, cara, valeu! É que no meu cenário eu precisava fazer esse calculo em uma query na base de dados, então não ia rolar ter a funcionalidade no código Java. Muito bom!

Aproveitando o tópico, alguém poderia dar uma ajuda fazendo favor?

Preciso também buscar quais são os pontos mais próximos de um determinado ponto, minha tabela está desse jeito:

id | nome | latitude | longitude

Em um tutorial, consegui criar a coluna geom da seguinte forma:

SELECT AddGeometryColumn( 'public', 'estacao', 'geom', 32661, 'POINT', 2 );

Depois, fiz o seguinte código para gerar os valores espaciais de cada ponto:

UPDATE estacao SET geom = ST_transform(ST_PointFromText('POINT(' || longitude || ' ' || latitude || ')',4269),32661);

No tutorial dizia que para fazer uma busca dos pontos mais próximos deveria ser desta maneira:

SELECT nome FROM estacao WHERE geom && ST_expand(ST_transform(ST_PointFromText('POINT(-49.2653819 -25.4244287)', 4269),32661), 16093) AND ST_distance(ST_transform(ST_PointFromText('POINT(-49.2653819 -25.4244287)', 4269),32661),geom) < 100;

Bom, ele retorna pra mim 28 estações que seriam os pontos mais próximos da lat e long: -49.2653819 -25.4244287, porem diminuindo o valor de 100 (que seria em metros) para 1, ele ainda me retorna as 28 estações.

O que estaria errado?

Se executo essa Sql também me retorna as 28 estações:

SELECT nome FROM estacao WHERE ST_distance(ST_transform(ST_PointFromText('POINT(-49.2653819 -25.4244287)', 4269),32661), geom) < 1;

Com a sql postada aqui no tópico, não retorna nada pra mim:

select * from estacao where ST_DWithin(ST_GeometryFromText('POINT(-49.2653819 -25.4244287)'), geom, 1000); 

Aqui está um exemplo de como está algumas linhas da minha tabela:

id | latitude | longitude | nome | geom
182 | -25.4244287 | -49.2653819 | Estação tubo Aeroporto Afonso Pena | 0101000020957F00007332DC44E30169C188960590AA0165C1
183 | -25.4105796 | -49.2482570 | Estação tubo Agrárias | 0101000020957F00000029BE7406FE68C14FF4D0022E0265C1

Obrigado por enquanto :smiley:

A api maps 3.0 da google faz isso. Essa é a página da documentção:

https://developers.google.com/maps/documentation/distancematrix/

Obrigado pela resposta, fiz uns teste aqui e ficou bem legal utilizando a API do maps, porem lá fala que caso queira utilizar mais de um endereço de destino eu posso fazer isso, utilizando uma barra | para separar os pontos de destino.

Até ai blz, porém no meu caso, tenho 177 pontos cadastrados, caso queira comparar um ponto com qual ponto mais perto dele entre esses 177 pontos, eu teria que fazer um loop para isso certo? Fora isso, ainda teria que comparar qual é a menor distancia entre eles. Bom, não sei se esse seria o jeito de fazer com a API do maps, mas se for, acho esse processo bem repetitivo, por favor, me corrijam se estou errado.
A ideia de usar o Postgis era de ele mesmo retornar quais os pontos mais próximos dada uma medida, de forma mais simples.

Bom, se há uma outra maneira com a API do maps, ou então com o Postgis gostaria muito de saber.

Mais uma vez obrigado pela ajuda.

porra marlonfa vc acha q a API do postgis faz o calculo por mágica, claro q vai ter que saber as 177 posiçoes e saber a distancia de todas pra saber qual é a mais perto ou vc acha q ele simplesmente adivinha qual é o mais perto de primeira

[quote=eduJava]porra marlonfa vc acha q a API do postgis faz o calculo por mágica, claro q vai ter que saber as 177 posiçoes e saber a distancia de todas pra saber qual é a mais perto ou vc acha q ele simplesmente adivinha qual é o mais perto de primeira
[/quote]

Vlw pela mensagem construtiva.

Obviamente sei que não existe a magica.

Reanimando o post, acho que a resposta encontra-se em outro post aqui do GUJ:

http://www.guj.com.br/39440-calcular-distancia-entre-coordenadas-geograficas

select (6371acos(cos(pi()(90 - (LAT_DESTINO))/180)* cos((90 - (LAT_ORIGEM))* pi()/180)+ sin((90 - (-LAT_DESTINO))* pi()/180)* si((90 - (LAT_ORIGEM))pi()/180) cos((LON_ORIGEM - (LON_DESTINO))*pi()/180)));

Não sei se usa ou não funções do PostGes, parece que são funções de álgebra.

Abraço.