用mysqli从haversine公式绑定距离参数

Posted

技术标签:

【中文标题】用mysqli从haversine公式绑定距离参数【英文标题】:binding distance parameter from haversine formula with mysqli 【发布时间】:2014-01-02 20:03:13 【问题描述】:

我正在开发一个网站,该网站将显示离特定位置最近的商店位置。我正在使用半正弦公式来确定距离,除了 XML 看不到我创建的距离字段外,一切正常。

switch($unit) 
  case "km":
    $distance = 6371; // KM
    break;
  case "mi":
    $distance = 3959; // KM
    break;


$query = "SELECT store_id, name, address, description, longitude, latitude, 
    (? * acos(cos(radians(?)) * cos( radians(latitude)) * cos(radians(longitude)
     - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) 
    AS distanceFromLocation FROM stores";



$stmt = $mysqli->prepare($query);
$stmt->bind_param('iddd', $distance, $user_latitude, $user_longitude, $user_latitude);

$valid_statement = true;
try 
  $stmt->execute();
  $stmt->store_result();
 catch(Exception $e) 
  $valid_statement = false;
  error_log($e->getMessage());


if($valid_statement) 

  $stmt->bind_result($store_id, $name, $address, $description, $longitude, $latitude, $distanceFromLocation);

  while($stmt->fetch()) 
    echo $distanceFromLocation;
    $node = $dom->createElement("marker");
    $newnode = $parnode->appendChild($node);
    $newnode->setAttribute("storeid", $store_id);
    $newnode->setAttribute("name", $name);
    $newnode->setAttribute("address", $address);
    $newnode->setAttribute("lat", $latitude);
    $newnode->setAttribute("lng", $longitude);
    $newnode->setAttribute("distance", $distanceFromLocation);
  

distanceFromLocation 变量在进入 while 循环时始终为空。我已经测试了 SQL,它将返回正确的距离值。任何想法为什么我无法访问距离场?是不是因为是计算字段?

【问题讨论】:

您为什么使用字符串ssss 而不是数字(6371 公里或 3959 英里)作为您的第一个参数? 这些值是作为字符串接收的,所以我将它们保留为字符串,因为它不会影响 SQL 查询的结果。我尝试将它们切换为:ssss、isss 和 iddd,它根本没有改变查询的结果,所以我在发布时将其作为字符串保留。自从我发布它以来,通过这个工作的过程,我把它改成了 iddd。 您正试图乘以一个字符串。 PS你不需要参数化它,因为它是一个常量。 我已将行修改为“iddd”而不是“ssss”。这并没有改变任何结果。我对其进行了参数化,因为用户可以定义他们想要 KM 还是 Mi。 您仍然必须使用数字,即$unit = 6371;$stmt->bind_param($unit,.... 【参考方案1】:

您需要将 switch 的结果合并为第一个参数。为了清楚起见,我还将 $distance 更改为 $constant。

switch($unit) //From User
  case "km":
    $constant = 6371; // KM
    break;
  case "mi":
    $constant = 3959; // KM
    break;


$query = "SELECT store_id, name, address, description, longitude, latitude, 
    (? * acos(cos(radians(?)) * cos( radians(latitude)) * cos(radians(longitude)
     - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) 
    AS distanceFromLocation FROM stores";



$stmt = $mysqli->prepare($query);
$stmt->bind_param($constant, $distance, $user_latitude, $user_longitude, $user_latitude);
etc.

【讨论】:

【参考方案2】:

如果您必须将MySQL 用于地理空间工作,而不是自己重新实现公式,请查看the geospatial support。根据the performance blog, mysql supports st_distance for determining distance between two points,应该没问题。除此之外,您可以查看 st_distance_sphere 或 st_distance_spheroid,两者都是are supported as of 5.1。

【讨论】:

以上是关于用mysqli从haversine公式绑定距离参数的主要内容,如果未能解决你的问题,请参考以下文章

红宝石中的Haversine公式

如何使用 Haversine 公式计算行驶距离(不是位移)?

根据haversine距离公式选择不同的列值?

MySQL 大圆距离(Haversine 公式)

Haversine 公式 - 数学略有偏差,不确定原因

计算两个经纬度点之间的距离? (Haversine 公式)