获取距离某个坐标点最近的几个坐标(计算距离)

function getNearlySite(){
//        $geohash = new \Geohash();

        //中心点位
        $id = params('id');
        $arr = Db::table('enterprises')
            ->field('id,lat84,lon84')
            ->where('id','=',$id)
            ->select();

        //坐标
        $data = Db::table('sites')
            ->field('id,lat,lon,site_name')
            ->select();

        //算出实际距离
        foreach($data as $key=>$val)
        {
            $distance = self::getDistance($arr[0]['lat84'],$arr[0]['lon84'],$val['lat'],$val['lon']);
            $data[$key]['distance'] = $distance;

            //排序列
            $sortdistance[$key] = $distance;
        }

        //距离排序
        array_multisort($sortdistance,SORT_ASC,$data);

        //最近3个点
        $lists = array();
        $weeks = getWeek();
        foreach($data as $ke=>$va)
        {
            if($ke<3){
                foreach ($weeks as $k=>$v){
                    $aqi = Db::table('air_quality')
                        ->field('avg(PM10) as AQI,SUBSTRING(add_time,1,10) as add_time,site_code')
                        ->where('site_code','=',$va['id'])
                        ->where('add_time','like',$v.'%')
                        ->group('SUBSTRING(add_time,1,10)')
                        ->order('add_time','desc')
                        ->limit(7)
                        ->select();
                    if($aqi){
                        $lists['name'.$ke]['AQI'][] = $aqi[0]['AQI'];
                        $lists['name'.$ke]['time'][] = $v;
                    }else{
                        $lists['name'.$ke]['AQI'][] = 0;
                        $lists['name'.$ke]['time'][] = $v;
                    }
                }
                $lists['name'.$ke]['name'][] = $va['site_name'];
            }
        }

        return getDates($lists);
    }

    //计算距离
    function getDistance($latitude1, $longitude1, $latitude2, $longitude2)
    {
        $earth_radius = 6371000;   //approximate radius of earth in meters

        $dLat = deg2rad($latitude2 - $latitude1);
        $dLon = deg2rad($longitude2 - $longitude1);
        /*
          Using the
          Haversine formula

          http://en.wikipedia.org/wiki/Haversine_formula
          http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe
          验证:百度地图  http://developer.baidu.com/map/jsdemo.htm#a6_1
          calculate the distance
        */
        $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);
        $c = 2 * asin(sqrt($a));
        $d = $earth_radius * $c;

        return round($d);   //四舍五入
    }

这个就是直接能用的,本来找的是一个geohash算法的,但是貌似这里没用到 !就自己修修改改发上来了 

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算弧上的距离一个最近可以分为以下几个步骤: 1. 将弧线分解为多个线段; 2. 对于每个线段,计算到线段的最近; 3. 将到每个线段的最近距离进行比较,找到距离最小的作为到弧的最近; 4. 计算距离最小的在弧上的位置,即弧的起始角度加上弧的总角度乘以距离最小所在线段的位置比例。 以下是一个C++函数的示例代码,计算弧上的距离一个最近: ```cpp #include <iostream> #include <cmath> using namespace std; struct Point { double x, y; }; struct Arc { Point center; double radius; double start_angle; double end_angle; }; // 计算到线段的最近 Point getNearestPointOnLine(Point p, Point A, Point B) { double lenAB = pow(B.x - A.x, 2) + pow(B.y - A.y, 2); double r = ((p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y)) / lenAB; r = max(min(r, 1.0), 0.0); // 确保r在[0,1]之间 Point P; P.x = A.x + r * (B.x - A.x); P.y = A.y + r * (B.y - A.y); return P; } // 计算弧上的距离一个最近 Point getNearestPointOnArc(Point p, Arc arc) { int num_segments = 20; // 将弧线分解为20个线段 double angle_diff = (arc.end_angle - arc.start_angle) / num_segments; Point nearest_point; double min_dist = 1e9; double min_t = 0; for (int i = 0; i <= num_segments; i++) { double angle = arc.start_angle + i * angle_diff; Point A, B; A.x = arc.center.x + arc.radius * cos(angle); A.y = arc.center.y + arc.radius * sin(angle); B.x = arc.center.x + arc.radius * cos(angle + angle_diff); B.y = arc.center.y + arc.radius * sin(angle + angle_diff); Point P = getNearestPointOnLine(p, A, B); double dist = sqrt(pow(P.x - p.x, 2) + pow(P.y - p.y, 2)); if (dist < min_dist) { min_dist = dist; nearest_point = P; min_t = i * angle_diff / (arc.end_angle - arc.start_angle); } } double angle = arc.start_angle + (arc.end_angle - arc.start_angle) * min_t; Point point_on_arc = { arc.center.x + arc.radius * cos(angle), arc.center.y + arc.radius * sin(angle) }; return point_on_arc; } int main() { Arc arc = { {0, 0}, 1, 0, M_PI }; Point p = { 2, 0 }; Point nearest_point = getNearestPointOnArc(p, arc); cout << "The nearest point on arc is (" << nearest_point.x << ", " << nearest_point.y << ")" << endl; return 0; } ``` 这个函数中,`getNearestPointOnLine`函数计算到线段的最近,`getNearestPointOnArc`函数将弧线分解为多个线段,并计算到每个线段的最近,最后返回距离最小的作为到弧的最近。在`main`函数中,我们定义了一个半径为1的圆弧,并将p设置为(2, 0),然后调用`getNearestPointOnArc`函数计算弧上的距离p的最近,并输出该坐标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值