我一直在阅读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
";
答案 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.925
和1.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;