如何将PHP半径函数与多个变量一起使用?

时间:2016-10-29 02:42:40

标签: php mysql latitude-longitude

我一直在阅读radius和mysql,我对如何使用多个搜索变量精确实现代码感到困惑,所以有人可能会为我分解它。

我的数据库包含以下表格:

  

idx | 输入 | 价格 | item_desc | s_lat | s_long | 创建日期

这是我目前的代码。

$search_origin_radius = "200";
$search_dest_radius = "100";
$search_origin_lat = "37.2629742";
$search_origin_long = "-98.286158";
$search_dest_lat = "37.2629742";
$search_dest_long = "-98.286158";
$type = "consumers";
$price = "100";

$sql = "SELECT * FROM products WHERE `price` = '$price'";

if($type && !empty($type))
{
    $sql .= " AND `type` = '$type'";    
}

到目前为止我发现的所有内容都说使用:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( latitude ) ) 
    * cos( radians( longitude ) - radians(-122) ) + sin( radians(37) ) * sin(radians(lat)) ) ) AS distance 
FROM myTable
HAVING distance < 50
ORDER BY distance 

但我对如何为$search_origin_radius$search_dest_radius实施它感到非常困惑。基本上我要做的就是在两个城市的价格范围和半径范围内找到所有待售的物品。

示例我想找到俄克拉荷马城周围100美元的价格,200英里内的OK和100英里内的堪萨斯城。

编辑**正如建议的那样,将其添加为存储函数。

function Calc_Distance($latitudeFrom, $longitudeFrom, $latitudeTo,         $longitudeTo, $earthRadius = 3959)
{
  // convert from degrees to radians
  $latFrom = deg2rad($latitudeFrom);
  $lonFrom = deg2rad($longitudeFrom);
  $latTo = deg2rad($latitudeTo);
  $lonTo = deg2rad($longitudeTo);

  $latDelta = $latTo - $latFrom;
  $lonDelta = $lonTo - $lonFrom;

  $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
  return $angle * $earthRadius;
}

使用新查询但仍未显示任何内容:

$sql = "
SELECT *
FROM products
WHERE Calc_Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200
  AND Calc_Distance(s_lat, s_long, $search_dest_lat,   $search_dest_long)   < 100
  AND price = $price
";

3 个答案:

答案 0 :(得分:5)

俄克拉荷马城和堪萨斯城距离彼此相距300英里。

距离堪萨斯城100英里以外的俄克拉荷马城AND 200英里以下的土地很少,所以我不会对你的查询没有结果感到惊讶。

也许你在这里想要OR逻辑..

SELECT id
  FROM products
 WHERE (*Oklahoma City distance calc miles* < 200
    OR *Kansas City distance calc miles* < 100)
   AND price = 100;

..或者你可以为每个城市UNION ALL SELECT

SELECT id, 'Oklahoma City' as city  
  FROM products
 WHERE *Oklahoma City distance calc miles* < 200
   AND price = 100

 UNION ALL

SELECT id, 'Kansas City'
  FROM products
 WHERE *Kansas City distance calc miles* < 100
   AND price = 100;

我个人倾向于第二,因为它很容易构建代码,并为您提供整齐地找到产品的城市。

虽然正如@PaulSpiegel所指出的那样,如果搜索区域相交,这个(未经修改的)可以多次返回一些产品。

答案 1 :(得分:0)

编写一个存储函数,它接受两对lat和lng,并返回一个距离。

$sql = "
SELECT ...
    FROM MyTbl
    WHERE Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200
      AND Distance(s_lat, s_long, $search_dest_lat,   $search_dest_long)   < 100
      AND price = $price
";

或者说出两次表达。

答案 2 :(得分:0)

  

如果您使用的是MySQL 5.7版,则可以使用它的空间便利性   功能,更具体地说是ST_Distance_Sphere。这条路   你将得到米的结果,从那里你很容易   以英里计算。

     

如果您的MySQL版本是5.6.1,那么您可以使用ST_Distance   像MySQL-Fiddle example

这样的函数
SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925*1.60934 AS `exact_distance`
FROM `entries` WHERE `price`=100 
HAVING `exact_distance`<=200;

你会注意到2个常数(68.9251.60934)。 第一个将ST_Distance的结果转换为英里 第二个(添加时)将其转换为千米 在上面的示例中,ST_Distance用于获取俄克拉荷马城的地理点距离。如果您想在SELECT查询中添加其他城市,那么您可以使用此类内容。

SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925 AS `exact_distance_from_Oklahoma_City`,
ST_Distance(POINT(`s_lat`,`s_long`), POINT(39.127562,-94.598810))*68.925 AS `exact_distance_from_Kansas_City`
FROM `entries` WHERE `price`=100 
HAVING `exact_distance_from_Oklahoma_City`<=200
AND `exact_distance_from_Kansas_City`<=100;