我想获得最近(最后添加)相关位置在特定区域内的自行车。这应该使用自行车模型上的查询范围scopeBounding($query, $latNorth, $lonEast, $latSouth, $lonWest)
完成。每辆自行车都有很多位置:
public function locations()
{
return $this->hasMany(Location::class);
}
到目前为止,我所拥有的一切似乎根本不起作用,因为我不知道如何只检查最新的相关位置。
public function scopeBounding($query, $latNorth, $lonEast, $latSouth, $lonWest)
{
return $query->whereHas('locations', function ($q) use ($latNorth, $lonEast, $latSouth, $lonWest)
{
$q->whereBetween('latitude', [$latNorth, $latSouth])
->whereBetween('longitude', [$lonWest, $lonEast]);
});
}
退回的自行车的最新位置不符合whereBetween
条件。
选择位置而不选择关联的自行车将按预期工作:
App\Location::whereBetween('latitude', [50, 50.2])->whereBetween('longitude', [11, 12])->get();
更新:
位置模型具有经度和纬度字段:
$table->decimal('latitude', 8, 6);
$table->decimal('longitude', 9, 6);
作用域的用法如下:
$bounding_bikes = Bike::bounding($latNorth, $lonEast, $latSouth, $lonWest)->get();
答案 0 :(得分:0)
我认为您应该尝试像获取特定自行车两点之间的距离之类的方法,然后可以对距离进行过滤。
我假设在这里您将拥有location表,而lat和lng应该是该表中的列。
这将以公里为单位计算距离
public function scopeBounding($query, $from_latitude, $from_longitude, $distance)
{
$raw = \DB::raw('ROUND ( ( 6371 * acos( cos( radians('.$from_latitude.') ) * cos( radians( locations.lat ) ) * cos( radians( locations.lng ) - radians('.$from_longitude.') ) + sin( radians('.$from_latitude.') ) * sin( radians( locations.lat ) ) ) ) ) AS distance');
return $query->select($raw)->orderBy( 'distance', 'asc' )->having('distance', '<=', $distance)
}
答案 1 :(得分:0)
我终于找到的解决方案对我来说确实很难看,但我没有发现更好的方法:
public function scopeBounding($query, $latNorth, $lonEast, $latSouth, $lonWest)
{
return $query->whereHas('locations', function ($q) use($latNorth, $lonEast, $latSouth, $lonWest) {
$q->whereRaw('`locations`.`id` = (select `locations`.`id` from `locations` where `bikes`.`id` = `locations`.`bike_id` order by `created_at` desc limit 1)')
->whereBetween('latitude', [$latSouth, $latNorth])
->whereBetween('longitude', [$lonWest, $lonEast]);
});
}
所以我很乐意提供任何简化方法的想法!