diff --git a/app/Console/Commands/AcarsReplay.php b/app/Console/Commands/AcarsReplay.php index 93861eac..0c46b493 100644 --- a/app/Console/Commands/AcarsReplay.php +++ b/app/Console/Commands/AcarsReplay.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Collection; use GuzzleHttp\Client; use App\Facades\Utils; +use Symfony\Component\Console\Input\InputOption; class AcarsReplay extends Command { @@ -52,6 +53,13 @@ class AcarsReplay extends Command ]); } + /*protected function getArguments() + { + return [ + ['--files', InputOption::VALUE_OPTIONAL] + ]; + }*/ + /** * Make a request to start a PIREP * @param \stdClass $flight @@ -107,13 +115,13 @@ class AcarsReplay extends Command $uri = '/api/pirep/' . $pirep_id . '/acars'; $upd = [ - 'log' => '', - 'lat' => $data->latitude, - 'lon' => $data->longitude, - 'heading' => $data->heading, - 'altitude' => $data->altitude, - 'gs' => $data->groundspeed, - 'transponder' => $data->transponder, + 'log' => '', + 'lat' => $data->latitude, + 'lon' => $data->longitude, + 'heading' => $data->heading, + 'altitude' => $data->altitude, + 'gs' => $data->groundspeed, + 'transponder' => $data->transponder, ]; $this->info("Update: $data->callsign, $upd[lat] x $upd[lon] \t\t" @@ -138,7 +146,7 @@ class AcarsReplay extends Command * Parse this file and run the updates * @param array $files */ - protected function runUpdates(array $files) + protected function updatesFromFile(array $files) { /** * @var $flights Collection @@ -227,7 +235,7 @@ class AcarsReplay extends Command } } - $this->runUpdates(explode(',', $files)); + $this->updatesFromFile(explode(',', $files)); $this->info('Done!'); } } diff --git a/app/Http/Controllers/Api/PirepController.php b/app/Http/Controllers/Api/PirepController.php index cbfbb8ca..587e6735 100644 --- a/app/Http/Controllers/Api/PirepController.php +++ b/app/Http/Controllers/Api/PirepController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Api; +use App\Services\GeoService; use Log; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -20,14 +21,19 @@ use App\Http\Controllers\AppBaseController; class PirepController extends AppBaseController { - protected $acarsRepo, $pirepRepo, $pirepSvc; + protected $acarsRepo, + $geoSvc, + $pirepRepo, + $pirepSvc; public function __construct( AcarsRepository $acarsRepo, + GeoService $geoSvc, PirepRepository $pirepRepo, PIREPService $pirepSvc ) { $this->acarsRepo = $acarsRepo; + $this->geoSvc = $geoSvc; $this->pirepRepo = $pirepRepo; $this->pirepSvc = $pirepSvc; } @@ -183,11 +189,18 @@ class PirepController extends AppBaseController } /** + * Return the GeoJSON for the ACARS line * @param $id * @param Request $request + * @return \Illuminate\Contracts\Routing\ResponseFactory */ public function geojson($id, Request $request) { $pirep = $this->pirepRepo->find($id); + $geodata = $this->geoSvc->getFeatureFromAcars($pirep); + + return response(\json_encode($geodata), 200, [ + 'Content-Type' => 'application/json', + ]); } } diff --git a/app/Services/GeoService.php b/app/Services/GeoService.php index b25c7af4..1b50fce3 100644 --- a/app/Services/GeoService.php +++ b/app/Services/GeoService.php @@ -18,11 +18,9 @@ use App\Models\Pirep; use App\Repositories\NavdataRepository; /** - * Return all of the coordinates, start to finish - * Returned in the GeoJSON format + * Return different points/features in GeoJSON format * https://tools.ietf.org/html/rfc7946 * - * TODO: Save this data: * Once a PIREP is accepted, save this returned structure as a * JSON-encoded string into the raw_data field of the PIREP row * @@ -36,7 +34,14 @@ class GeoService extends BaseService $this->navRepo = $navRepo; } - public function getClosestCoords($coordStart, $all_coords, $measure='flat') + /** + * Determine the closest set of coordinates from the starting position + * @param array $coordStart + * @param array $all_coords + * @return mixed + * @throws \League\Geotools\Exception\InvalidArgumentException + */ + public function getClosestCoords($coordStart, $all_coords) { $distance = []; $geotools = new Geotools(); @@ -45,12 +50,7 @@ class GeoService extends BaseService foreach($all_coords as $coords) { $coord = new Coordinate($coords); $dist = $geotools->distance()->setFrom($start)->setTo($coord); - - if($measure === 'flat') { - $distance[] = $dist->flat(); - } elseif ($measure === 'greatcircle') { - $distance[] = $dist->greatCircle(); - } + $distance[] = $dist->greatCircle(); } $distance = collect($distance); @@ -61,7 +61,7 @@ class GeoService extends BaseService /** * @param $dep_icao string ICAO to ignore * @param $arr_icao string ICAO to ignore - * @param $start_coords array [x, y] + * @param $start_coords array Starting point, [x, y] * @param $route string Textual route * @return array */ @@ -86,7 +86,7 @@ class GeoService extends BaseService } try { - Log::info('Looking for ' . $route_point); + Log::debug('Looking for ' . $route_point); $points = $this->navRepo->findWhere(['id' => $route_point]); $size = \count($points); @@ -168,9 +168,9 @@ class GeoService extends BaseService /** * Read an array/relationship of ACARS model points * @param Pirep $pirep - * @return array + * @return FeatureCollection */ - protected function getFeatureFromAcars(Pirep $pirep) + public function getFeatureFromAcars(Pirep $pirep) { $route_line = []; $route_points = []; @@ -183,26 +183,19 @@ class GeoService extends BaseService foreach ($pirep->acars as $point) { $route_line[] = [$point->lon, $point->lat]; - $route_points[] = new Feature( new Point([$point->lon, $point->lat]), [ - 'name' => $point->altitude, - 'popup' => 'GS: ' . $point->gs . '
Alt: ' . $point->altitude, - ]); + 'pirep_id' => $pirep->id, + 'name' => $point->altitude, + 'popup' => 'GS: ' . $point->gs . '
Alt: ' . $point->altitude, + ]); } # Arrival $route_line[] = [$pirep->arr_airport->lon, $pirep->arr_airport->lat]; + $route_line = new Feature(new LineString($route_line)); - # Convert to a feature - $route_line = new Feature(new LineString($route_line), [], 1); - - # TODO: Draw the plane icon from the last point - - return [ - 'line' => new FeatureCollection([$route_line]), - 'points' => new FeatureCollection($route_points) - ]; + return new FeatureCollection([$route_line, $route_points]); } /** @@ -223,11 +216,12 @@ class GeoService extends BaseService $point = $pirep->position; $flight_points[] = new Feature( new Point([$point->lon, $point->lat]), [ - 'gs' => $point->gs, - 'alt' => $point->altitude, - 'heading' => $point->heading ?: 0, - 'popup' => 'Flight: ' . $pirep->ident, - ]); + 'pirep_id' => $pirep->id, + 'gs' => $point->gs, + 'alt' => $point->altitude, + 'heading' => $point->heading ?: 0, + 'popup' => 'Flight: ' . $pirep->ident, + ]); } return new FeatureCollection($flight_points); @@ -242,7 +236,6 @@ class GeoService extends BaseService { $route_coords = []; $route_points = []; - #$features = []; ## Departure Airport $route_coords[] = [$flight->dpt_airport->lon, $flight->dpt_airport->lat]; @@ -288,8 +281,8 @@ class GeoService extends BaseService $planned_route_line = new FeatureCollection([new Feature(new LineString($route_coords), [])]); return [ - 'route_points' => $route_points, - 'planned_route_line' => $planned_route_line, + 'route_points' => $route_points, + 'planned_route_line' => $planned_route_line, ]; } @@ -306,9 +299,9 @@ class GeoService extends BaseService $planned_rte_coords[] = [$pirep->dpt_airport->lon, $pirep->dpt_airport->lat]; $route_points[] = new Feature( new Point([$pirep->dpt_airport->lon, $pirep->dpt_airport->lat]), [ - 'name' => $pirep->dpt_airport->icao, + 'name' => $pirep->dpt_airport->icao, 'popup' => $pirep->dpt_airport->full_name, - 'icon' => 'airport', + 'icon' => 'airport', ] ); @@ -323,9 +316,9 @@ class GeoService extends BaseService foreach ($all_route_points as $point) { $planned_rte_coords[] = [$point->lon, $point->lat]; $route_points[] = new Feature(new Point([$point->lon, $point->lat]), [ - 'name' => $point->name, + 'name' => $point->name, 'popup' => $point->name . ' (' . $point->name . ')', - 'icon' => '' + 'icon' => '' ]); } } @@ -333,9 +326,9 @@ class GeoService extends BaseService $planned_rte_coords[] = [$pirep->arr_airport->lon, $pirep->arr_airport->lat]; $route_points[] = new Feature( new Point([$pirep->arr_airport->lon, $pirep->arr_airport->lat]), [ - 'name' => $pirep->arr_airport->icao, + 'name' => $pirep->arr_airport->icao, 'popup' => $pirep->arr_airport->full_name, - 'icon' => 'airport', + 'icon' => 'airport', ] ); @@ -350,10 +343,10 @@ class GeoService extends BaseService $actual_route = $this->getFeatureFromAcars($pirep); return [ - 'route_points' => $route_points, - 'planned_route_line' => $planned_route, - 'actual_route_line' => $actual_route['line'], - 'actual_route_points' => $actual_route['points'], + 'route_points' => $route_points, + 'planned_route_line' => $planned_route, + 'actual_route_line' => $actual_route['line'], + 'actual_route_points' => $actual_route['points'], ]; } } diff --git a/public/assets/img/acars/marker.png b/public/assets/img/acars/marker.png new file mode 100644 index 00000000..b8d2fc93 Binary files /dev/null and b/public/assets/img/acars/marker.png differ diff --git a/public/assets/system/js/system.js b/public/assets/system/js/system.js index c4f6ec8e..f416ec82 100644 --- a/public/assets/system/js/system.js +++ b/public/assets/system/js/system.js @@ -5,6 +5,9 @@ const phpvms = (function() { + const PLAN_ROUTE_COLOR = '#36b123'; + const ACTUAL_ROUTE_COLOR = '#172aea'; + const draw_base_map = (opts) => { opts = _.defaults(opts, { @@ -123,7 +126,7 @@ const phpvms = (function() { let geodesicLayer = L.geodesic([], { weight: 7, opacity: 0.9, - color: '#36b123', + color: PLAN_ROUTE_COLOR, steps: 50, wrap: false, }).addTo(map); @@ -137,7 +140,7 @@ const phpvms = (function() { onEachFeature: onFeaturePointClick, pointToLayer: pointToLayer, style: { - "color": "#36b123", + "color": PLAN_ROUTE_COLOR, "weight": 5, "opacity": 0.65, }, @@ -154,7 +157,7 @@ const phpvms = (function() { let geodesicLayer = L.geodesic([], { weight: 7, opacity: 0.9, - color: '#172aea', + color: ACTUAL_ROUTE_COLOR, steps: 50, wrap: false, }).addTo(map); @@ -168,7 +171,7 @@ const phpvms = (function() { onEachFeature: onFeaturePointClick, pointToLayer: pointToLayer, style: { - "color": "#172aea", + "color": ACTUAL_ROUTE_COLOR, "weight": 5, "opacity": 0.65, },