Pergunta

Eu estou com o objetivo de criar um recurso no meu mais recente projeto de preferência usando PHP. Quando cada usuário se inscrever eles vão inserir seu código postal. Então eu espero que irá ser converter isso para latitude / longitude usando o Open Street Map.

De qualquer forma, eu quero ser capaz de descobrir outros usuários localizados perto do usuário atual. Eu vi um monte de gente usando a fórmula Haversine, no entanto, isso significaria que o usuário consultado detalhes de todos os outros usuários para trabalhar a distância. Eu poderia armazenar em cache este mas seu breve vai se tornar ultrapassada à medida que novos usuários se inscrever.

Que tipo de efeito seria executando a seguinte consulta tem no meu sistema?

sql = "SELECT zipcode, ( 3959 * acos( cos( radians( {$coords['latitude']} ) ) 
    * cos( radians( latitude ) ) * cos( radians( longitude ) 
    - radians( {$coords['longitude']} ) ) 
    + sin( radians( {$coords['latitude']} ) ) * sin( radians( latitude ) ) ) ) 
    AS distance FROM zipcodes HAVING distance <= {$radius} ORDER BY distance";

Isso é puxado do blog de alguém.

Eu não tenho quaisquer valores para a taxa de inscrição ou a quantidade de usuários, uma vez que ainda está em desenvolvimento.

Eu gostaria de receber qualquer feedback ou outros métodos que eu poderia usar para encontrar usuários correspondentes dentro de um raio específico.

Foi útil?

Solução

Existem GIS e Extensões Espacias ao MySQL na versão 4.1, consulte aqui . A partir da descrição que você vai encontrar, que é usado para problemas como você tem aqui:

A GIS (Sistema de Informação Geográfica) lojas e olha para cima objectos que têm um ou mais atributos espaciais, tais como o tamanho ea posição, e é usado para processar esses objectos. Um exemplo simples seria um sistema que armazena endereços em uma cidade usando geográfica coordenadas. Se isso bastante estática dados foi, em seguida, combinado com outra informações, como a localização de um táxi, em seguida, esses dados poderiam ser usados para encontrar o táxi mais próximo a um certo localização.

Ele adiciona várias coisas para MySql como:

  • chaves espacial e o tipo de ponto:

    CREATE TABLE endereço ( CHAR endereço (80) não nulo, address_loc PONTO NOT NULL, PRIMARY KEY (endereço), ESPACIAL KEY (address_loc) );

  • rotinas de conversão

    valores de endereço INSERT INTO ( 'Foobar rua 12', GeomFromText ( 'POINT (2671 2500)') );

  • funções de cálculo GIS

    SELECIONAR c.cabdriver, ROUND ( GLength (LineStringFromWKB (LineString (asBinary (c.cab_loc), AsBinary (a.address_loc)))) ) distância AS Da cabina c, o endereço de um ORDER BY distância ASC LIMIT 1;

(Exemplos feita de ligação acima)

Outras dicas

O problema pode ser muito simplificada se você estiver disposto a afrouxar a definição de "dentro de um determinado raio" a não ser especificamente um círculo. Se você simplificar a um "quadrado", você pode encontrar todos os localização dentro do "raio" with 2 simples "entre" cláusulas (uma para um lat por muito tempo). por exemplo:

SELECT * FROM location WHERE
  lat BETWEEN (my_lat - radius) AND (my_lat + radius)
  AND long BETWEEN (my_long - radius) AND (my_long + radius);

Claro, isso poderia ser usado para selecionar um subconjunto de seus locais antes de usar um método mais preciso para calcular a distância real para eles.

É certo que este é Javascript não PHP, mas seria trivial para converter eu imagino.

Ele calcula a distância entre dois pontos, representando a curvatura da Terra. É usado-o em uma logística app um tempo atrás antes de substituí-lo com o código que faz isso usando uma rota adequada.

pode ser de utilidade para você ....

<script type="text/javascript">
function getDistance(lat1,lng1,lat2,lng2)
 {
  p1 = new VELatLong(lat1,lng1);
  p2 = new VELatLong(lat2,lng2);
  miles = true;
  p1.Latitude= latLonToRadians(p1.Latitude);
  p1.Longitude= latLonToRadians(p1.Longitude);
  p2.Latitude= latLonToRadians(p2.Latitude);
  p2.Longitude= latLonToRadians(p2.Longitude);
  var R = 6371; // earth's mean radius in km
  var dLat  = p2.Latitude- p1.Latitude;
  var dLong = p2.Longitude- p1.Longitude;
  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
  Math.cos(p1.Latitude) * Math.cos(p2.Latitude) * Math.sin(dLong/2) * 
Math.sin(dLong/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var disKm = R * c;
  var disMiles = disKm * 0.6214;
  alert (miles ? disMiles : disKm);
 }
 //  convert lat/long in degrees to radians
 function latLonToRadians( point )
 {
  return point * Math.PI / 180;
 }
</script>

Oh, e objetos VELatLong vêm da API do Virtual Earth ( http://msdn.microsoft.com/en-us/library/bb412519.aspx ), mas são basicamente um glorificado struct, então você deve ser capaz de encontrar um substituto adequado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top