From 5cf0bbaa65af0a4c8d25165d94cbc36ca4d276e6 Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Mon, 1 Jan 2018 16:01:01 -0600 Subject: [PATCH] Clean up the GeoJSON generation code --- Makefile | 3 +- app/Database/seeds/sample.yml | 32 ++++ app/Http/Controllers/Api/PirepController.php | 71 ++++----- app/Models/GeoJson.php | 66 +++++++++ app/Models/Pirep.php | 7 + app/Repositories/AcarsRepository.php | 18 ++- app/Services/GeoService.php | 145 ++++++++----------- app/Services/PIREPService.php | 51 +++---- 8 files changed, 233 insertions(+), 160 deletions(-) create mode 100644 app/Models/GeoJson.php diff --git a/Makefile b/Makefile index 8083fafe..32d6f0f0 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,8 @@ test: .PHONY: replay-acars replay-acars: - @php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual + #@php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual + @php artisan phpvms:replay ASH6028 --manual .PHONY: sass-watch sass-watch: diff --git a/app/Database/seeds/sample.yml b/app/Database/seeds/sample.yml index 64316c40..b3c55d4f 100644 --- a/app/Database/seeds/sample.yml +++ b/app/Database/seeds/sample.yml @@ -276,6 +276,14 @@ user_bids: flight_id: flightid_3 acars: + - pirep_id: pirepid_1 + type: 1 + nav_type: 2 + name: TNV + lat: 30.28852 + lon: -96.058239 + created_at: now + updated_at: now - pirep_id: pirepid_1 type: 1 nav_type: 2 @@ -284,6 +292,14 @@ acars: lon: -95.345719 created_at: now updated_at: now + - pirep_id: pirepid_1 + type: 1 + nav_type: 2 + name: LCH + lat: 30.14151 + lon: -93.105569 + created_at: now + updated_at: now - pirep_id: pirepid_1 type: 1 nav_type: 2 @@ -292,6 +308,22 @@ acars: lon: -88.804267 created_at: now updated_at: now + - pirep_id: pirepid_1 + type: 1 + nav_type: 2 + name: ATL + lat: 33.62907 + lon: -84.435064 + created_at: now + updated_at: now + - pirep_id: pirepid_1 + type: 1 + nav_type: 2 + name: SIE + lat: 39.0955 + lon: -74.800344 + created_at: now + updated_at: now pireps: - id: pirepid_1 diff --git a/app/Http/Controllers/Api/PirepController.php b/app/Http/Controllers/Api/PirepController.php index 17926b35..dcfc9b22 100644 --- a/app/Http/Controllers/Api/PirepController.php +++ b/app/Http/Controllers/Api/PirepController.php @@ -28,6 +28,22 @@ class PirepController extends AppBaseController $pirepRepo, $pirepSvc; + protected $check_attrs = [ + 'airline_id', + 'aircraft_id', + 'dpt_airport_id', + 'arr_airport_id', + 'flight_id', + 'flight_number', + 'route_leg', + 'route_code', + 'flight_time', + 'planned_flight_time', + 'level', + 'route', + 'notes', + ]; + public function __construct( AcarsRepository $acarsRepo, GeoService $geoSvc, @@ -55,40 +71,23 @@ class PirepController extends AppBaseController */ public function prefile(Request $request) { - Log::info('PIREP Prefile, user '. Auth::user()->pilot_id, - $request->toArray()); - - $check_attrs = [ - 'airline_id', - 'aircraft_id', - 'dpt_airport_id', - 'arr_airport_id', - 'flight_id', - 'flight_number', - 'route_leg', - 'route_code', - 'flight_time', - 'planned_flight_time', - 'level', - 'route', - 'notes', - ]; + Log::info('PIREP Prefile, user '. Auth::user()->pilot_id, $request->toArray()); $attrs = [ - 'user_id' => Auth::user()->id, + 'user_id' => Auth::user()->id, + 'state' => PirepState::IN_PROGRESS, + 'status' => PirepStatus::PREFILE, ]; - foreach ($check_attrs as $attr) { + foreach ($this->check_attrs as $attr) { if ($request->filled($attr)) { $attrs[$attr] = $request->get($attr); } } - $attrs['state'] = PirepState::IN_PROGRESS; - $attrs['status'] = PirepStatus::PREFILE; - try { $pirep = $this->pirepRepo->create($attrs); + $this->pirepSvc->saveRoute($pirep); } catch(\Exception $e) { Log::error($e); } @@ -108,27 +107,14 @@ class PirepController extends AppBaseController */ public function file($id, Request $request) { - Log::info('PIREP Prefile, user ' . Auth::user()->pilot_id, - $request->toArray()); + Log::info('PIREP Prefile, user ' . Auth::user()->pilot_id, $request->toArray()); - $attrs = []; - $check_attrs = [ - 'airline_id', - 'aircraft_id', - 'dpt_airport_id', - 'arr_airport_id', - 'flight_id', - 'flight_number', - 'route_leg', - 'route_code', - 'flight_time', - 'planned_flight_time', - 'level', - 'route', - 'notes', + $attrs = [ + 'state' => PirepState::PENDING, + 'status' => PirepStatus::ARRIVED, ]; - foreach($check_attrs as $attr) { + foreach($this->check_attrs as $attr) { if($request->filled($attr)) { $attrs[$attr] = $request->get($attr); } @@ -138,9 +124,6 @@ class PirepController extends AppBaseController $pirep_fields = $request->get('fields'); } - $attrs['state'] = PirepState::PENDING; - $attrs['status'] = PirepStatus::ARRIVED; - try { $pirep = $this->pirepRepo->update($attrs, $id); $pirep = $this->pirepSvc->create($pirep, $pirep_fields); diff --git a/app/Models/GeoJson.php b/app/Models/GeoJson.php new file mode 100644 index 00000000..02c455e1 --- /dev/null +++ b/app/Models/GeoJson.php @@ -0,0 +1,66 @@ +line_coords[] = [$lon, $lat]; + $this->point_coords[] = new Feature(new Point([$lon, $lat]), $attrs); + ++$this->counter; + } + + /** + * Get the FeatureCollection for the line + * @return FeatureCollection + */ + public function getLine(): FeatureCollection + { + if(empty($this->line_coords) || \count($this->line_coords) < 2) { + return new FeatureCollection([]); + } + + return new FeatureCollection([ + new Feature(new LineString($this->line_coords)) + ]); + } + + /** + * Get the feature collection of all the points + * @return FeatureCollection + */ + public function getPoints(): FeatureCollection + { + return new FeatureCollection($this->point_coords); + } +} diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index 5c437ada..5d12fb2c 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -94,6 +94,13 @@ class Pirep extends BaseModel ->orderBy('created_at', 'asc'); } + public function acars_route() + { + return $this->hasMany('App\Models\Acars', 'pirep_id') + ->where('type', AcarsType::ROUTE) + ->orderBy('created_at', 'asc'); + } + public function aircraft() { return $this->belongsTo('App\Models\Aircraft', 'aircraft_id'); diff --git a/app/Repositories/AcarsRepository.php b/app/Repositories/AcarsRepository.php index 3ed234ee..ab052a5d 100644 --- a/app/Repositories/AcarsRepository.php +++ b/app/Repositories/AcarsRepository.php @@ -5,10 +5,6 @@ namespace App\Repositories; use App\Models\Acars; use App\Models\Pirep; use App\Models\Enums\PirepState; -use App\Models\Enums\PirepStatus; - -use App\Repositories\Traits\CacheableRepository; -use Prettus\Repository\Contracts\CacheableInterface; class AcarsRepository extends BaseRepository //implements CacheableInterface { @@ -19,9 +15,19 @@ class AcarsRepository extends BaseRepository //implements CacheableInterface return Acars::class; } - public function forPirep($pirep_id) + /** + * @param $pirep_id + * @param $type + * @return mixed + */ + public function forPirep($pirep_id, $type) { - return $this->findWhere(['pirep_id' => $pirep_id]); + $where = [ + 'pirep_id' => $pirep_id, + 'type' => $type, + ]; + + return $this->orderBy('created_at', 'asc')->findWhere($where); } /** diff --git a/app/Services/GeoService.php b/app/Services/GeoService.php index 10510772..7d277bed 100644 --- a/app/Services/GeoService.php +++ b/app/Services/GeoService.php @@ -2,11 +2,9 @@ namespace App\Services; -use App\Models\Acars; -use App\Models\Airport; -use Illuminate\Database\Eloquent\ModelNotFoundException; -use Illuminate\Support\Collection; use Log; +use App\Models\Enums\AcarsType; +use App\Repositories\AcarsRepository; use \GeoJson\Geometry\Point; use \GeoJson\Geometry\LineString; @@ -16,6 +14,7 @@ use \GeoJson\Feature\FeatureCollection; use \League\Geotools\Geotools; use \League\Geotools\Coordinate\Coordinate; +use App\Models\GeoJson; use App\Models\Flight; use App\Models\Pirep; use App\Repositories\NavdataRepository; @@ -30,10 +29,13 @@ use App\Repositories\NavdataRepository; */ class GeoService extends BaseService { - private $navRepo; + private $acarsRepo, $navRepo; - public function __construct(NavdataRepository $navRepo) - { + public function __construct( + AcarsRepository $acarsRepo, + NavdataRepository $navRepo + ) { + $this->acarsRepo = $acarsRepo; $this->navRepo = $navRepo; } @@ -247,19 +249,14 @@ class GeoService extends BaseService */ public function flightGeoJson(Flight $flight): array { - $route_coords = []; - $route_points = []; + $route = new GeoJson(); ## Departure Airport - $route_coords[] = [$flight->dpt_airport->lon, $flight->dpt_airport->lat]; - - $route_points[] = new Feature( - new Point([$flight->dpt_airport->lon, $flight->dpt_airport->lat]), [ - 'name' => $flight->dpt_airport->icao, - 'popup' => $flight->dpt_airport->full_name, - 'icon' => 'airport', - ] - ); + $route->addPoint($flight->dpt_airport->lat, $flight->dpt_airport->lon, [ + 'name' => $flight->dpt_airport->icao, + 'popup' => $flight->dpt_airport->full_name, + 'icon' => 'airport', + ]); if($flight->route) { $all_route_points = $this->getCoordsFromRoute( @@ -270,8 +267,7 @@ class GeoService extends BaseService // lat, lon needs to be reversed for GeoJSON foreach($all_route_points as $point) { - $route_coords[] = [$point->lon, $point->lat]; - $route_points[] = new Feature(new Point([$point->lon, $point->lat]), [ + $route->addPoint($point->lat, $point->lon, [ 'name' => $point->name, 'popup' => $point->name . ' (' . $point->name . ')', 'icon' => '' @@ -279,23 +275,15 @@ class GeoService extends BaseService } } - ## Arrival Airport - $route_coords[] = [$flight->arr_airport->lon, $flight->arr_airport->lat,]; - - $route_points[] = new Feature( - new Point([$flight->arr_airport->lon, $flight->arr_airport->lat]), [ - 'name' => $flight->arr_airport->icao, - 'popup' => $flight->arr_airport->full_name, - 'icon' => 'airport', - ] - ); - - $route_points = new FeatureCollection($route_points); - $planned_route_line = new FeatureCollection([new Feature(new LineString($route_coords), [])]); + $route->addPoint($flight->arr_airport->lat, $flight->arr_airport->lon, [ + 'name' => $flight->arr_airport->icao, + 'popup' => $flight->arr_airport->full_name, + 'icon' => 'airport', + ]); return [ - 'route_points' => $route_points, - 'planned_route_line' => $planned_route_line, + 'route_points' => $route->getPoints(), + 'planned_route_line' => $route->getLine(), ]; } @@ -306,60 +294,49 @@ class GeoService extends BaseService */ public function pirepGeoJson(Pirep $pirep) { - $planned_rte_points = []; - $planned_rte_coords = []; + $planned = new GeoJson(); + $actual = new GeoJson(); - $planned_rte_coords[] = [$pirep->dpt_airport->lon, $pirep->dpt_airport->lat]; - $feature = new Feature( - new Point([$pirep->dpt_airport->lon, $pirep->dpt_airport->lat]), [ - 'name' => $pirep->dpt_airport->icao, - 'popup' => $pirep->dpt_airport->full_name, - 'icon' => 'airport', - ]); - - $planned_rte_points[] = $feature; - - if (!empty($pirep->route)) { - $all_route_points = $this->getCoordsFromRoute( - $pirep->dpt_airport->icao, - $pirep->arr_airport->icao, - [$pirep->dpt_airport->lat, $pirep->dpt_airport->lon], - $pirep->route); - - // lat, lon needs to be reversed for GeoJSON - foreach ($all_route_points as $point) { - $planned_rte_coords[] = [$point->lon, $point->lat]; - $planned_rte_points[] = new Feature(new Point([$point->lon, $point->lat]), [ - 'name' => $point->name, - 'popup' => $point->name . ' (' . $point->name . ')', - 'icon' => '' - ]); - } - } - - $planned_rte_coords[] = [$pirep->arr_airport->lon, $pirep->arr_airport->lat]; - - $planned_rte_points[] = new Feature( - new Point([$pirep->arr_airport->lon, $pirep->arr_airport->lat]), [ - 'name' => $pirep->arr_airport->icao, - 'popup' => $pirep->arr_airport->full_name, - 'icon' => 'airport', - ] - ); - - $planned_rte_points = new FeatureCollection($planned_rte_points); - - $planned_route = new FeatureCollection([ - new Feature(new LineString($planned_rte_coords), []) + /** + * PLANNED ROUTE + */ + $planned->addPoint($pirep->dpt_airport->lat, $pirep->dpt_airport->lon, [ + 'name' => $pirep->dpt_airport->icao, + 'popup' => $pirep->dpt_airport->full_name, ]); - $actual_route = $this->getFeatureFromAcars($pirep); + $planned_route = $this->acarsRepo->forPirep($pirep->id, AcarsType::ROUTE); + foreach($planned_route as $point) { + $planned->addPoint($point->lat, $point->lon, [ + 'name' => $point->name, + 'popup' => $point->name . ' (' . $point->name . ')', + ]); + } + + $planned->addPoint($pirep->arr_airport->lat, $pirep->arr_airport->lon, [ + 'name' => $pirep->arr_airport->icao, + 'popup' => $pirep->arr_airport->full_name, + 'icon' => 'airport', + ]); + + /** + * ACTUAL ROUTE + */ + $actual_route = $this->acarsRepo->forPirep($pirep->id, AcarsType::FLIGHT_PATH); + foreach ($actual_route as $point) { + $actual->addPoint($point->lat, $point->lon, [ + 'pirep_id' => $pirep->id, + 'name' => $point->altitude, + 'popup' => 'GS: ' . $point->gs . '
Alt: ' . $point->altitude, + ]); + } return [ - 'planned_rte_points' => $planned_rte_points, - 'planned_rte_line' => $planned_route, - 'actual_route_line' => $actual_route['line'], - 'actual_route_points' => $actual_route['points'], + 'planned_rte_points' => $planned->getPoints(), + 'planned_rte_line' => $planned->getLine(), + + 'actual_route_points' => $actual->getPoints(), + 'actual_route_line' => $actual->getLine(), ]; } } diff --git a/app/Services/PIREPService.php b/app/Services/PIREPService.php index ca1fe0a4..c57a2b3f 100644 --- a/app/Services/PIREPService.php +++ b/app/Services/PIREPService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Repositories\AcarsRepository; use Log; use App\Models\Acars; @@ -24,10 +25,11 @@ use App\Repositories\PirepRepository; class PIREPService extends BaseService { - protected $geoSvc, - $navRepo, - $pilotSvc, - $pirepRepo; + protected $acarsRepo, + $geoSvc, + $navRepo, + $pilotSvc, + $pirepRepo; /** * PIREPService constructor. @@ -37,11 +39,14 @@ class PIREPService extends BaseService * @param PirepRepository $pirepRepo */ public function __construct( - UserService $pilotSvc, + AcarsRepository $acarsRepo, GeoService $geoSvc, NavdataRepository $navRepo, - PirepRepository $pirepRepo - ) { + PirepRepository $pirepRepo, + UserService $pilotSvc + ) + { + $this->acarsRepo = $acarsRepo; $this->geoSvc = $geoSvc; $this->pilotSvc = $pilotSvc; $this->navRepo = $navRepo; @@ -57,12 +62,12 @@ class PIREPService extends BaseService { # Delete all the existing nav points Acars::where([ - 'pirep_id' => $pirep->id, - 'type' => AcarsType::ROUTE, - ])->delete(); + 'pirep_id' => $pirep->id, + 'type' => AcarsType::ROUTE, + ])->delete(); # Delete the route - if(empty($pirep->route)) { + if (empty($pirep->route)) { return $pirep; } @@ -76,7 +81,7 @@ class PIREPService extends BaseService /** * @var $point Navdata */ - foreach($route as $point) { + foreach ($route as $point) { $acars = new Acars(); $acars->pirep_id = $pirep->id; $acars->type = AcarsType::ROUTE; @@ -99,21 +104,21 @@ class PIREPService extends BaseService * * @return Pirep */ - public function create(Pirep $pirep, array $field_values=[]): Pirep + public function create(Pirep $pirep, array $field_values = []): Pirep { - if(empty($field_values)) { + if (empty($field_values)) { $field_values = []; } # Figure out what default state should be. Look at the default # behavior from the rank that the pilot is assigned to $default_state = PirepState::PENDING; - if($pirep->source === PirepSource::ACARS) { - if($pirep->pilot->rank->auto_approve_acars) { + if ($pirep->source === PirepSource::ACARS) { + if ($pirep->pilot->rank->auto_approve_acars) { $default_state = PirepState::ACCEPTED; } } else { - if($pirep->pilot->rank->auto_approve_manual) { + if ($pirep->pilot->rank->auto_approve_manual) { $default_state = PirepState::ACCEPTED; } } @@ -152,7 +157,7 @@ class PIREPService extends BaseService */ public function changeState(Pirep $pirep, int $new_state) { - Log::info('PIREP ' . $pirep->id . ' state change from '.$pirep->state.' to ' . $new_state); + Log::info('PIREP ' . $pirep->id . ' state change from ' . $pirep->state . ' to ' . $new_state); if ($pirep->state === $new_state) { return $pirep; @@ -169,17 +174,13 @@ class PIREPService extends BaseService } else { return $pirep; } - } - - /* + } /* * Move from a ACCEPTED to REJECTED status */ elseif ($pirep->state === PirepState::ACCEPTED) { $pirep = $this->reject($pirep); return $pirep; - } - - /** + } /** * Move from REJECTED to ACCEPTED */ elseif ($pirep->state === PirepState::REJECTED) { @@ -216,7 +217,7 @@ class PIREPService extends BaseService $this->setPilotState($pilot, $pirep); - Log::info('PIREP '.$pirep->id.' state change to ACCEPTED'); + Log::info('PIREP ' . $pirep->id . ' state change to ACCEPTED'); event(new PirepAccepted($pirep));