php - 如果条件适用,Haversine 公式 PHP 将添加到第二个表中
问题描述
我正在尝试实施Haversine Formula
以检查表格的纬度/经度。我的 android 应用程序将所有传入位置存储在数据库中的特定表中,inregistrari
. 我的目标是获得公式来测试基于经度和纬度的新传入位置,如果新值与alerte
(第二个表)中存在的值之间的距离超过 50m,insert
则到两个表中的位置(alerte
,inregistrari
) , 否则,仅在inregistrari
. 新值必须通过存储在 中的所有位置进行验证alerte
。所以,最后我会得到一个包含所有位置()的表格,而第二个只有在 50m( )inregistrari
内没有任何其他位置的位置。alerte
我试图实施( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) )
但无法让它按我想要的方式工作。我寻求指导,因为PHP
我实际上对此还不是很熟悉。作为第一步,我设法直接在两个表PHP
中自动创建了 to insert
,现在我只需要实现Haversine
. 提前致谢!
php尝试实现haversine:
case 'alerta':
if(isTheseParametersAvailable(array('latitudine', 'longitudine', 'id_alerta_tip', 'ID_user'))){
$problema = $_POST['id_alerta_tip'];
$latitudine = $_POST['latitudine'];
$longitudine = $_POST['longitudine'];
$id = $_POST['ID_user'];
$stmt = $conn->prepare("SELECT latitudine, longitudine FROM inregistrari WHERE latitudine = ? AND longitudine = ?");
$stmt->bind_param("ss", $latitudine, $longitudine);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows < 1){
$stmt = $conn->prepare("INSERT INTO inregistrari (ID_user, id_alerta_tip, latitudine, longitudine) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $id, $problema, $latitudine, $longitudine);
$stmt->execute();
$stmt->store_result();
$stmt = $conn->prepare("SELECT * FROM alerte WHERE id_alerta_tip = ?");
$stmt->bind_param("s",$problema);
$stmt->execute();
$stmt->store_result();
while($row = mysqli_fetch_array($stmt))
{
$latitudine1=$row[latitudine];
$longitudine1=$row[longitudine];
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;
}
if(getDistance($latitudine,$longitudine,$latitudine1,$longitudine1)<0.05)
{
$stmt = $conn->prepare("INSERT INTO alerte(id_utilizator, latitudine, longitudine, tip_problema) VALUES ('$id','$latitudine', '$longitudine', '$problema')");
$stmt->execute();
}
}
$stmt = $conn->prepare("SELECT id_alerta FROM alerte WHERE latitudine = ? AND longitudine = ?");
$stmt->bind_param("ss", $latitudine, $longitudine);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows > 0){
$stmt->bind_result($id_alerta);
$stmt->fetch();
$stmt= $conn->prepare("UPDATE inregistrari SET ID_Alerta_Primarie = ? WHERE latitudine = ? AND longitudine = ?");
$stmt->bind_param("iss",$id_alerta ,$latitudine, $longitudine);
$stmt->execute();
$stmt->close();
}else{
$response['error'] = false;
$response['message'] = 'Alerta nu a putut fi inregistrata';
}
$response['error'] = false;
$response['message'] = 'Alerta raportata';
}else{
$response['error'] = false;
$response['message'] = 'Alerta nu a putut fi inregistrata';
}
}else{
$response['error'] = false;
$response['message'] = 'Alerta nu a putut fi inregistrata';
}
break;
我试图实现 awhile
来一次获取每一行,但它不起作用。while
代码在语句之前停止运行。谢谢!
解决方案
这是实际的Haversine公式:
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
Angles need to be in radians to pass to Trigonometric functions
这是 MySQL 的等价物:
SELECT *,
( 3959 * acos( cos( radians(55.864237) ) * cos( radians( latitude ) )
* cos( radians( longitude ) - radians(-4.251806) ) + sin( radians(55.864237) )
* sin( radians( latitude ) ) ) ) AS distance
FROM postcodes HAVING distance < 20
ORDER BY distance LIMIT 1;
在这里,我检查 20 英里内的任何区域,但您可以根据需要将其设置为短或长。查询开头的 3959 数字是用于英里的数字,如果您使用公里,则应将此数字更改为 6371。我已将其限制为 1 行,因为我只想要最接近的匹配,但是您可能想要在其他情况下更改此设置!
这是 Haversine 的 Wiki http://en.wikipedia.org/wiki/Haversine_formula
祝你好运!
推荐阅读
- c# - 如何使用 C# 为 GIT 传递存储库名称
- ios - 如何转回 TableViewController (Swift) 的填充版本?
- javascript - 如何将 javascript 对象格式化为模式数据的 JSON 对象?
- c# - 自动标记数据,以便由当前用户打开
- javascript - 对象分配在执行分配之前操作对象。如何?
- wordpress - 媒体库未在 wordpress 2018 上显示图像
- ssis - 将 SSIS 包从我的本地系统执行到其他远程服务器,SSIS 包存储在文件系统中
- java - java.nio.channels.Selector.select() 立即返回 0
- wpf - 如何更新绑定到 UI 的集合?
- javascript - Django-如何通过 javascript 变量在模板中定义 django 变量?