RouteTrait.php 6.3 KB
<?php
/**
 * +-----------------------------------------------------------------------------------------------------------------------
 * trait :第三方相关接口 trait
 * +-----------------------------------------------------------------------------------------------------------------------
 *
 * PHP version 7
 *
 * @category  App\Models\Traits
 * @package   App\Models\Traits
 * @author    Richer <yangzi1028@163.com>
 * @date      2023年3月6日14:05:34
 * @copyright 2020-2021 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Models\Traits;

use App\Models\Bus;
use App\Models\BusLocation;
use App\Models\RouteSite;
use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Trait RouteTrait
 * @package App\Models\Traits
 */
trait RouteTrait
{
    /**
     * 根据当前的定位获取当前的站点信息
     *
     * @param $sites
     * @param $location
     * @return array
     */
    public function getSiteByLocation($bus_id, $sites, $location): array
    {
        if (!$location) {
            return [];
        }


        $point = [$location->longitude, $location->latitude];

        // 获取当前的上一条记录
        $record = BusLocation::where('bus_id', $bus_id)->whereDate('created_at', today()->toDateString())->first();
        if (!$record) {
            // 如果还没有记录,说明是在始发站第一次进行记录

            // 然后获取始发站和终点站的距离
            $first = $sites->first();
            $last = $sites->last();
            $distance1 =   get_distance($point, [$first->site->longitude, $first->site->latitude]);
            $distance2 =   get_distance($point, [$last->site->longitude, $last->site->latitude]);

            if ($distance1 < $distance2) {
                // 记录当前的问题
            }
        }


        // 算法,只要比较
        $distances = $sites->map(function ($site) use ($point) {
            $distance = get_distance($point, [$site->site->longitude, $site->site->latitude]);
            return [
                'distance' => $distance,
                'site' => [
                    'name'      => (string)$site->site->name,
                    'longitude' => $site->site->longitude,
                    'latitude'  => $site->site->latitude,
                    'sort' => $site->sort,
                    'distance'  => $site->distance,
                ],
//                'sort' => $site->sort,
//                'site' => $site->site->toArray(),
            ];
//            dump($site);
//            dump($point);
//            dump( [$site->longitude, $site->latitude]);
//            $distances[] = get_distance($point, [$site->site->longitude, $site->site->latitude]);
        });//->toArray();

        // 获取距离最小的数据
        $min_distance = $distances->min('distance');

        // 然后判断该站点上一站和下一站的距离
        $site = $distances->where('distance', $min_distance)->first();

        // 获取上一个
        $pre_site = $distances->where('site.sort', Arr::get($site, 'site.sort') - 1)->first();

        // 获取下一个
        $next_site = $distances->where('site.sort', Arr::get($site, 'site.sort') + 1)->first();

        // TODO 获取始发站和终点站
        $rs = ['first'];
        // 如果距离上个站点的距离比站点到上个站点的距离还少,说明在这个两点之间
        if (Arr::get($pre_site, 'distance') < Arr::get($site, 'site.distance')) {
            $rs = [
                'previous' => $pre_site,
                'next' => $site,
            ];
        } else {
            $rs = [
                'previous' => $site,
                'next' => $next_site,
            ];
        }
//        BusLocation::where('id', 1)->update(['site_info' => json_encode($rs)]);
        return $rs;

//        dd($distances);
    }

    /*protected function getDistance($longitude1, $latitude1, $longitude2, $latitude2)
    {
        if ($longitude1 && $latitude1 && $longitude2 && $latitude2) {
            // 方法 1
            $pie = ' 3.1415926';
            // $distance = "ACOS(SIN(( $latitude * $pie) / 180 ) *SIN((latitude * $pie) / 180 ) +COS(( $latitude * $pie) / 180 ) * COS((latitude * $pie) / 180 ) *COS(( $longitude * $pie) / 180 - (longitude * $pie) / 180 ) ) * 6380 * 1000 AS distance";
            // 方法 2
            $radius = 6371000 * $pie / 180 ;// 111195 地球半径
            $distance = "(st_distance(point(longitude,latitude), point($longitude,$latitude)) * $radius) AS distance";
            $query  = $query->select('*')->addSelect(DB::raw($distance));

            // add by Richer 于 2022年6月1日11:28:29 客户新需求 距离改成白天1000米晚上2500米,时间那边改成5000米以内单子不让显示,以外的显示
            if ($sort === 'distance') {
                // 晚上10点到早上7点2000米
                // 当前的小时
                $d = 3000;
                $hour = Carbon::now()->hour;
                if ($hour >= 22 ||  $hour < 7) {
                    $d = 3000;
                }

                $query->having('distance', '<=', $d)// 小于 1000 m
                ->orderBy('distance', 'ASC');
            } else {
                $query->having('distance', '<=', 5000)// 小于 50000 m
                ->latest();
            }
        }
    }*/

    /**
     * 设置站点间的距离
     * @param $route_id
     */
    public function setRouteSiteDistance($route_id)
    {
        // 按照顺序获取该路线的全部站点
        $sites = RouteSite::with(['site'])->orderBy('sort')->where('route_id', $route_id)->get();
        $sites->each(function ($site) use ($sites) {
            $point1 = [$site->site->longitude, $site->site->latitude];
            $sort = $site->sort + 1;

            $site2 = $sites->where('sort', $sort)->first();

            if ($site2) {
                $point2 = [$site2->site->longitude, $site2->site->latitude];
                $distance = get_distance($point1, $point2);
                $site2->distance = $distance;
                $site2->save();
            }
        });
    }
}