选择不同的经度和纬度值并找到它们的中值

Posted

技术标签:

【中文标题】选择不同的经度和纬度值并找到它们的中值【英文标题】:Selecting Distinct Longitude and Latitude values and finding their median 【发布时间】:2012-12-09 11:04:31 【问题描述】:

我正在使用 Google Maps API V3 和 jQuery 创建一个 Phonegap 应用程序。

当检测到坑洞时,应用程序将经度和纬度值分别存储在 mysql 数据库中。我需要做的是选择任何相对接近并且很可能是同一个坑洞的值。

在jQuery/php/SQL中有什么方法可以获取比较接近的值,找到它们的均值,然后使用该值继续处理一些其他的事情吗?

基本上,我需要的是,一旦特定坑洞被检测到 5 次,它就会在谷歌地图上绘制出来。但是,只有在满足此阈值时。困难在于,相同的坑洼可能会在稍有不同的经度和纬度值下报告,具体取决于报告它的设备的准确性。

【问题讨论】:

【参考方案1】:

您需要Haversine's Formula 来计算两个给定地点的经纬度坐标之间的距离。基于此,您可以编写一个方法来检查所有接近/接近给定坐标的值,使用以公里为单位的范围。

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);
);

【讨论】:

【参考方案2】:

当您需要识别新坑附近的坑洼时,以下代码可以以米为单位执行此操作。它使用带有错误检查的 POD 在 MySQL 查询中使用 Haversine Formula

$lat & $lng 是新坑洞的坐标,$radius 是搜索半径,以米为单位。 6378160 是地球在赤道处的半径,以米为单位。

为确保此级别的准确性,数据库中的坐标必须至少有 4 位小数See 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; 

【讨论】:

此代码将用于在数据库中输入新的坑洞详细信息,对吗?如果我理解正确,它会抓取新发现的坑洞的坑洞细节,将 lat 和 lng 与数据库中已有的坑洞进行比较,如果附近没有坑洞,则将坑洞细节插入数据库中。我的理解正确吗? @user1809790 再次阅读您的问题后,它不符合 5 次标准。如果需要,我会调查一下。 如果您有时间/经验,我会非常高兴。我自己对 javascript/php 并不是很熟悉,但正在尝试构建我的第一个移动应用程序:/ 我假设您将拥有后端 MySQL/PHP 来完成繁重的工作 我有一个 MySQL 数据库和一些 PHP 文件,它们将充当 Phonegap 应用程序将连接到的 Web 服务

以上是关于选择不同的经度和纬度值并找到它们的中值的主要内容,如果未能解决你的问题,请参考以下文章

球坐标转换的疑惑

如何在不同的数据帧中选择特定时间段内的点,然后根据纬度/经度选择这两个点之间的距离

经度/纬度值不正确

如果纬度/经度上有多个标记,我如何旋转地图标记

列出数组中最近的经度/纬度

给定两个区域的经度和纬度,如何找到它们之间的距离(以米为单位)。如何在 SQL 中查询..?