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