Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Long/Lat-Punkte innerhalb eines Begrenzungsrahmens zusammenführen, abhängig von einem Radius in MySQL

Diese Operation kann zu kompliziert sein, um sie ohne die Hilfe von PHP oder einer anderen Programmiersprache auszuführen. So könnten Sie es in PHP machen:

<?
    $link = mysqli_connect("host", "user", "pass", "database");

    // Grab all the points from the db and push them into an array
    $sql = "SELECT * FROM data";
    $res = $link->query($sql);
    $arr = array();
    for($i = 0; $i < mysqli_num_rows($res); $i++){
        array_push($arr, mysqli_fetch_assoc($res));
    }

    // Cycle through the point array, eliminating those points that "touch" 
    $rad = 1000; //radius in KM
    for($i = 0; $i < count($arr); ++$i){
        $lat1 = $arr[$i]['lat'];
        $lon1 = $arr[$i]['long'];
        for($j = 0; $j<count($arr); ++$j){
            if($i != $j && isset($arr[$i]) && isset($arr[$j])){ // do not compare a point to itself
                $lat2 = $arr[$j]['lat'];
                $lon2 = $arr[$j]['long'];
                // get the distance between each pair of points using the haversine formula
                $dist = acos( sin($lat1*pi()/180)*sin($lat2*pi()/180) + cos($lat1*pi()/180)*cos($lat2*pi()/180)*cos($lon2*PI()/180-$lon1*pi()/180) ) * 6371;
                if($dist < $rad){
                    echo "Removing point id:".$arr[$i]['id']."<br>";
                    unset($arr[$i]);
                }
            }
        }
    }

    //display results
    echo "Remaining points:<br>";
    foreach($arr as $val){
        echo "id=".$val['id']."<br>";
    }
?>

Die Ausgabe dieses Codes für die von Ihnen bereitgestellten Daten lautet:

    Removing point id:1
    Removing point id:2
    Remaining points:
    id=3
    id=4

Beachten Sie, dass dies nur die überlappenden Punkte entfernt und keine Mittelung der Positionen durchführt. Das könntest du aber problemlos hinzufügen. Hoffe das hilft.