RouteTrait.php
6.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?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();
}
});
}
}