Question

I have a question that I have spent too many hours trying to resolve. I am using de Haversine formula to calculate the distance between two points, but the code that I'm using is giving me values that are too high for a distance like KM.

This is the code:

$pesquisa_raio = "%" . $_GET['raio'] . "%";
$latitude = floatval("%" . $_GET['lat'] . "%");
$longitude = floatval("%" . $_GET['log'] . "%");
$cidade="%" . $_GET['cidade'] . "%";

$sql= "SELECT * FROM oferta";//"add depois" //Inner Join concelhos On oferta.concelhos_id = concelhos.idconcelhos ";
$query = mysql_query($sql);
$array = mysql_fetch_array($query);
$row = mysql_num_rows($query);
//$sql_cidades = "SELECT * FROM oferta WHERE localizacao like '$pesquisa_loc'";


if (isset($latitude) && isset($longitude)) {
    if ($row > 0) {
        do {
        $endereco=$array['concelho_id'];
        $request="http://maps.google.com/maps/api/geocode/json?address='.$endereco.'sensor=false";
        $json_data=file_get_contents($request);
        
        $earth_radius = 6372.795477598;
        $lat_1 = floatval($latitude);
        $lon_1 = floatval($longitude);
        $lat_2 = 41.145570;//floatval($latitude2);
        $lon_2 = -8.627014;//floatval($longitude2);
        $delta_lat = $lat_2 - $lat_1 ;
        $delta_lon = $lon_2 - $lon_1 ;
        $alpha    = $delta_lat/2;
        $beta     = $delta_lon/2;
        $a        = sin(deg2rad($alpha)) * sin(deg2rad($alpha)) + cos(deg2rad($lat_1)) * cos(deg2rad($lat_2)) * sin(deg2rad($beta)) * sin(deg2rad($beta)) ;
        $c        = asin(min(1, sqrt($a)));
        $distance = 2*$earth_radius * $c;
        $distance = round($distance, 4);
        echo $distance."\n";
          if($distance<=$pesquisa_raio){
            $response = $array['titulo'] . "|";
        }
    } while ($array = mysql_fetch_assoc($query));
        json_encode($response);

Is something wrong with the code, or is it that I can't understand the result?


Solved

So I have this code that doesn't work, but I fix the problem, this is the solution:

    $tipo_output = "json"; // pode ser utilizado o json também
               // a sua API KEY do Google Maps gerado com o link acima
                $google_api = "0R4r34bcHA6I0Ppts5oHcxhgoPmdOvt4Hz2cA2w";
               // o endereço que desejamos que o google procure
               // lembrando que o endereço tem que ser no padrão de uma requisição URL e caso possua acentuação, vamos executar um utf8_encode
               $cidade=$array['concelho'];
               echo $cidade;
               $endereco_desejado = urlencode(utf8_encode("$cidade, PT"));
               // Desired address
               $endereco_final = "http://maps.google.com/maps/api/geocode/json?address=". $endereco_desejado ."&sensor=true";
               // conteudo da página
                $string = file_get_contents($endereco_final); // get json content
$json_a = json_decode($string); //json decoder
            //busca da lat e log
            $longitude2 = $json_a->results[0]->geometry->location->lng;
            $latitude2 =$json_a->results[0]->geometry->location->lat;
            //calculo da distancia
            
            $earth_radius = 6371.0;
            $latitude1 = $latitude * pi() / 180.0;
            $longitude1 = $longitude * pi() / 180.0;
            $latitude2 = $latitude2 * pi() / 180.0;
            $longitude2 = $longitude2 * pi() / 180.0;
            
             $dLat = $latitude2 - $latitude1;
             $dLong = $longitude2 - $longitude1;
            
             $a = sin($dLat / 2) * sin($dLat / 2) + cos( $latitude1) * cos($latitude2) * sin($dLong / 2) * sin($dLong / 2);
             
             $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
            
             $resultado=intval($earth_radius * $c); // resultado em km.
Was it helpful?

Solution

Your inputs are broken.

$latitude = floatval("%" . $_GET['lat'] . "%");
$longitude = floatval("%" . $_GET['log'] . "%");

Think about what you're doing. floatval('%123.4%') will always be a zero, no matter what you take from $_GET.

Those look like leftovers from an SQL query, but there you need a different escaping method (e.g. PDO) to avoid SQL injection.


Also, you're loading remote data using a malformed query and apparently ignoring the result?

$endereco=$array['concelho_id'];
$request="http://maps.google.com/maps/api/geocode/json?address='.$endereco.'sensor=false";
$json_data=file_get_contents($request);

This will produce an URL similar to http://maps.google.com/maps/api/geocode/json?address='.some kind of address.'sensor=false , which is never going to give you useful answers because it's

  1. including single quotes and periods (you seem to have mixed up double and single quotes),
  2. not properly escaping the dynamic part at all,
  3. missing an & before sensor=false.

(Not to mention $array won't even be initialized the first time you run the do {} while loop.)

OTHER TIPS

I am not sure about your code, but I would create a function to calculate the distance.

function getDistance($latitude1, $longitude1, $latitude2, $longitude2) {
    $earth_radius = 6371;

    $dLat = deg2rad($latitude2 - $latitude1);
    $dLon = deg2rad($longitude2 - $longitude1);

    $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);
    $c = 2 * asin(sqrt($a));
    $d = $earth_radius * $c;

    return $d;
}

Taken from the codecodex.com page for Haversine formula

I tested the C# formula and it was spot on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top