【发布时间】:2019-08-03 00:29:57
【问题描述】:
我想在我的 $user_devices 数组中找到两个最远的对象(彼此相距)。
$user_devices 的每个对象都有属性:id、name、imei 和坐标。例如:
$user_devices = array(
'id' => '1',
'name' => 'First object',
'imei' => '123456789',
'coordinates' => '51.313032,11.798092'
);
我要做的是遍历整个数组,将纬度和经度转换为 x 和 y,最后计算位置之间的距离。
问题在于,该算法应该能够在至少 5000 条记录(位置)的情况下快速运行,但将其集成到网站需要大约 20 秒的加载时间。
如何优化这个算法?
public static function get_farthest_devices($user_devices)
{
$r = 6378; // Earth radius in km
$max_distance = 0;
$count = count($user_devices);
for ($i = 0; $i < $count - 1; $i++) {
$coordinates = $user_devices[$i]->coordinates;
$coordinates_explode = explode(',', $coordinates);
$lat = $coordinates_explode[0];
$lng = $coordinates_explode[1];
$x1 = $r * cos(deg2rad($lat)) * cos(deg2rad($lng));
$y1 = $r * cos(deg2rad($lat)) * sin(deg2rad($lng));
for ($j = $i + 1; $j < $count; $j++) {
$coordinates = $user_devices[$j]->coordinates;
$coordinates_explode = explode(',', $coordinates);
$lat = $coordinates_explode[0];
$lng = $coordinates_explode[1];
$x2 = $r * cos(deg2rad($lat)) * cos(deg2rad($lng));
$y2 = $r * cos(deg2rad($lat)) * sin(deg2rad($lng));
$distance_between_points = sqrt( pow($x2-$x1, 2) + pow($y2-$y1, 2) );
if($distance_between_points > $max_distance)
{
$max_distance = $distance_between_points;
$obj_i = $user_devices[$i];
$obj_j = $user_devices[$j];
}
}
}
echo 'MAX distance is between: ' . $obj_i->name . ' (' . $obj_i->imei . ') and ' . $obj_j->name . ' (' . $obj_j->imei . ') ' . $max_distance . ' km<br/>';
}
【问题讨论】:
-
对象可以在地球上的任何地方还是在有限的区域(例如,在某个国家或城市)?
-
对象可以在任何地方。
-
为什么不使用数据库呢?在表中插入每条记录并执行查询
-
整个 user_devices 数组是从数据库中获取的。每个设备位置可以每 x 秒更改一次。在每次页面加载时,用户都应该看到哪两个设备相距最远。
-
从前三个点创建一个三角形,然后为每个给定的下一个点扩展它(如果点在结果图形之外)或保持原样,具体取决于该点是否在结果内数字。对于图中的每个点,存储坐标,这样您就不必一次又一次地爆炸/deg2rad/sin/cos。
标签: php coordinates distance geocoding haversine