选择最小距离的随机GPS点

3
我想编写一个php程序,从我的数据库中的400个点中选择16个随机gps点。
(点表:id-标题-纬度-经度)。
只有一个要求:选择16个随机点,每个点之间至少相距1公里(找到1KM范围内的点)。
这是一个选择药房的系统,每个药房之间的最小距离为1公里。我有400家药房在数据库中,每周必须选择16家药房。我不能选择两家非常接近的药房。
例如:
如果程序返回3个药房A、B和C。
药房之间的距离必须是:
A和B = 1公里
A和C = 1公里
B和C = 1公里

此问题已被 deceze、jeroen、Dagon、Perception 和 doug 关闭,原因为“并非一个真正的问题”。2小时前。对不起各位,我以为这是一个问题,但忘记它只是一条突发新闻。 - Fadel
2个回答

0

既然你只有400条记录,我们可以试着用较为困难的方法来处理,可能只需要几个小时时间...虽然我没有尝试过,但这或许能给你一些想法。

$min =1;
$n =16;

$pharmas = fillUp();

// main function 
function fillUp(){
   $points = array();
   while(count($points)< $n){
      $tmp = getRandomPoint();
      if(checkAll($tmp, $points){
         $points[] = $tmp;
      }
}
return $points;  // after a few hours ??
 }

// get a random point
// after all we might get lucky
function getRandomPoint(){
//...
// return array with ['latitude'] & ['longitude']
}

// check that all points meet the requirements
function checkAll($pt, $points){
    foreach($points as $point){
         if(distance($point, $pt) < $min {
              return false;
          }
    }
    return true;
}

// calculate the distance between 2 points
function distance ($point1, $point2, $uom='km') {
    //  Use Haversine formula to calculate the great circle distance
    //      between two points identified by longitude and latitude
    switch (strtolower($uom)) {
        case 'km' :
            $earthMeanRadius = 6371.009; // km
            break;
        case 'm' :
            $earthMeanRadius = 6371.009 * 1000; // km
            break;
        case 'miles' :
            $earthMeanRadius = 3958.761; // miles
            break;
        case 'yards' :
        case 'yds' :
            $earthMeanRadius = 3958.761 * 1760; // miles
            break;
        case 'feet' :
        case 'ft' :
            $earthMeanRadius = 3958.761 * 1760 * 3; // miles
            break;
        case 'nm' :
            $earthMeanRadius = 3440.069; // miles
            break;
    }
    $deltaLatitude = deg2rad($point2['latitude'] - $point1['latitude']);
    $deltaLongitude = deg2rad($point2['longitude'] - $point1['longitude']);
    $a = sin($deltaLatitude / 2) * sin($deltaLatitude / 2) +
            cos(deg2rad($point1['latitude'])) * cos(deg2rad($point2['latitude'])) *
            sin($deltaLongitude / 2) * sin($deltaLongitude / 2);
    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
    $distance = $earthMeanRadius * $c;
    return $distance;
}

0
一个简单的答案如下:
首先创建一个视图,包括与你感兴趣的点最接近的对象列表,然后使用PHP代码计算实际的球面距离。
@MY_LAT = 37.9824;
@MY_LONG = -87.5781547;

SELECT *, SQRT(
              ABS((latitude - @MY_LAT) * (latitude - @MY_LAT) + 
                  (longitude - @MY_LONG) * (longitude - @MY_LONG))) 
          AS DIST
FROM POINT_TABLE
ORDER BY DIST ASC

从这个视图中选择前n行,以获取与您的“兴趣点”最接近的16个点。在获得结果后,编写一个简短的PHP代码片段来检查这些点是否在您的参考点的1公里范围内。下面的代码应该能帮助您:

http://www.zipcodeworld.com/samples/distance.php.html

在这里,我在查询中使用笛卡尔距离公式,其唯一目的是减少您需要应用 PHP 中的球面距离公式的记录数量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接