我正在开发一个应用程序,我需要搜索某个地理区域是否有某些项目。这些物品在数据库中,在具有其他信息的表格中以纬度和经度进行分割。我需要做的是基本上在一些坐标中搜索数据库中所有项目的圆形区域。现在我只是在查询获取所有数据,然后对每个项目进行一些计算,看它是否在该区域内(基本上是毕达哥拉斯定理,因为我不需要太多的精度)。有没有做过类似事情的人可以就如何优化它提出一些建议吗?也许还有某种缓存系统返回先前搜索在一般区域收集的resoult,该区域的精度并不重要,并且将圆圈移动几公里也不会成为问题。 我使用MySql作为数据库,PHP应该产生我的结果。 提前谢谢你:)
修改 我没有发布代码,因为我没有要求特定的代码修改,而是更直接的方法来解决问题,某种算法我以后可以自己编写代码 无论如何这是数据库结构 表Interv
ID Int
Addr Text
Info Text
Area Int
Type Text
Lat Double
Lng Double
Time Datetime
Table Area
ID Int
Name Text
这是PHP页面
require("Utils.php");
require("Config.php");
if(!array_key_exists("Lat",$_GET) || !array_key_exists("Lng",$_GET)){
$re = array("error"=>"1");
echo json_encode($re);
exit();
}
$lat = $_GET["Lat"];
$lng = $_GET["Lng"];
$mysqli = get_mysqli();
$query = "SELECT `Interv`.`Addr`,`Interv`.`Info`,`Interv`.`Lat`,`Interv`.`Lng`,`Interv`.`Type`, `Area`.`Name` FROM `Interv` JOIN `Area` ON `Interv`.`Area`=`Area`.`ID` WHERE `Time` > '".date("Y-m-d H:i:s",(time() - Max_Time))."';";
$result = $mysqli->query($query);
if($result->num_rows >0){
$responce = array("Error" => 0 , "Data" => array());
$i = 0;
while($row = $result->fetch_array(MYSQLI_ASSOC)){
if(sqrt(pow($lat-$row["Lat"],2)+pow($lng-$row["Lng"],2)) < Max_Distance){
$responce["Data"][$i] = array("Addr" => $row["Addr"], "Info" => $row["Info"], "Type" => $row["Type"], "Area" => $row["Name"]);
$i++;
}
}
echo json_encode($responce);
$result->close();
}
$mysqli->close();
我想过使用谷歌的API来计算距离,但我认为这会完全扼杀服务器带宽,因此我不确定如何处理这个问题.-。
再次感谢
答案 0 :(得分:0)
这是一种未优化的,也是数学上不正确的做地理球距的方法。
答案 1 :(得分:0)
对于最多10K分,这可能会做得足够好:
添加一个&#34;边界框&#34;到WHERE
子句并INDEX(latitude), INDEX(longitude)
。
你需要除以COS(lat)
来补偿经度线比纬度线更接近。
毕达哥拉斯距离可能足以让小&#39;小&#39;距离不靠近极点也不越过日期线的距离。同样,需要COS
。
我添加了一个标签;见其他标记的讨论。