3

Google Maps API V3 と jQuery を使用して Phonegap アプリケーションを作成しています。

くぼみが検出されると、アプリケーションは経度と緯度の値を別々に MySQL データベースに保存します。私がする必要があるのは、比較的近く、おそらく同じポットホールである可能性のある値を選択することです。

jQuery/PHP/SQL で比較的近い値を取得し、それらの平均点を見つけて、その値を使用して他の処理を続行する方法はありますか?

基本的に必要なのは、特定のくぼみが 5 回検出されると、Google マップ上にグラフ化されることです。ただし、このしきい値に達した場合のみです。問題は、同じくぼみが、それを報告するデバイスの精度に応じて、わずかに異なる経度と緯度の値で報告される可能性があることです。

4

2 に答える 2

2

必要なのは、指定された 2 つの場所の経度と緯度の座標間の距離を計算するための Haversine の式です。これに基づいて、km 単位の範囲を使用して、特定の座標に近い/近いすべての値をチェックするメソッドを作成できます。

距離を計算するための Haversine 式

$('some_element').click(function(){
    var location1 = [lat, lon] // Specify Longitude and latitude
    var location2 = [lat, lon] // Specify Longitude and latitude

    var lat1 = location1[0], lon1 = location1[1];
    var lat2 = location2[0], lon2 = location2[1];
    var earth = 6371 // Earth's Radius in Kms

    var dLat = (lat2-lat1) * Math.PI / 180;
    var dLon = (lon2-lon1) * Math.PI / 180;
    var nlat1 = (lat1) * Math.PI / 180;
    var nlat2 = (lat2) * Math.PI / 180;
    // Calculation
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(nlat1) * Math.cos(nlat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = earth * c;
    var distance = Math.round(d*Math.pow(10,2)) / Math.pow(10,2); //Round off to 2 decimal places
    alert(distance);
});
于 2012-12-21T21:46:10.160 に答える
1

新しい穴の近くの穴を特定する必要があるため、次のコードでこれをメートル単位で行うことができます。エラーチェック付きのPODを使用したMySQLクエリでHaversineFormulaを使用します。

$latと$lngは新しい甌穴の座標であり、$radiusはメートル単位の検索半径です。6378160は、赤道でのメートル単位の地球の半径です。

このレベルでの精度を確保するには、データベース内の座標に小数点以下4桁以上が必要です。Wikiを参照してください。

編集

    try {
    // Prepare search statement
    $stmt1 = $dbh->prepare("SELECT id, lat, lng, cnt, ( 6378160 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) ) ) AS  distance FROM potholes  HAVING distance <  ? ORDER BY distance LIMIT 0,10");
    // Assign parameters
    $stmt1->bindParam(1,$lat);
    $stmt1->bindParam(2,$lng);
    $stmt1->bindParam(3,$lat);
    $stmt1->bindParam(4,$radius);
    //Execute query
    $stmt1->setFetchMode(PDO::FETCH_ASSOC);
    $stmt1->execute();
    if ($stmt1->rowCount()>0) {//Existing pothole 
        // fetch row
        $row = $stmt1->fetch();
        $id = $row['id'];
        $lat1 = $row['lat'];
        $lng1 = $row['lng'];
        $cnt = $row['cnt'];
        $meanLat = (($lat1*$cnt)+$lat)/($cnt+1);
        $meanLng = (($lng1*$cnt)+$lng)/($cnt+1);
        ++$cnt;
        // Prepare UPDATE statement existing pothole
        $stmt2 = $dbh->prepare("UPDATE  `potholes` SET  `lat` = ?,`cnt` =  ? WHERE  `potholes`.`id` = ? LIMIT 1");
        // Assign parameters
        $stmt2->bindParam(1,$meanLat);
        $stmt2->bindParam(2,$cnt);
        $stmt2->bindParam(3,$id);
        $stmt2->execute();
    //  }
    }else{//New pothole
        // Prepare INSERT statement new pothole
        $stmt3 = $dbh->prepare("INSERT INTO `potholes` (`id`, `lat`, `lng`, `cnt`) VALUES (NULL, ?, ?, '1')");
        // Assign parameters
        $stmt3->bindParam(1,$lat);
        $stmt3->bindParam(2,$lng);
        $stmt3->execute();

    }
echo json_encode($data);//Echo to calling page if required
}



catch(PDOException $e) {
    echo "Error Message.". $e->getMessage() ;// Remove or modify after testing 
    file_put_contents('PDOErrors.txt',date('[Y-m-d H:i:s]').", data2c.php, ". $e->getMessage()."\r\n", FILE_APPEND);  
 }
//Close the connection
$dbh = null; 
于 2012-12-22T08:41:01.127 に答える