From 70b1476e939f2a4df62e210e65a24a19d8287a2f Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Sun, 24 Dec 2017 17:38:38 -0600 Subject: [PATCH] Add markers for the navpoints on the flight and pirep maps --- Makefile | 1 + .../Controllers/Frontend/FlightController.php | 4 +- .../Controllers/Frontend/PirepController.php | 4 +- app/Models/Enums/NavaidType.php | 12 ++ app/Services/GeoService.php | 139 ++++++++++++------ public/assets/system/js/system.js | 50 ++++++- .../layouts/default/flights/map.blade.php | 3 +- .../layouts/default/pireps/map.blade.php | 3 +- 8 files changed, 160 insertions(+), 56 deletions(-) diff --git a/Makefile b/Makefile index d5922491..6a45bfc7 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,7 @@ reset: clean reload-db: @php artisan database:create --reset @php artisan migrate:refresh --seed + @php artisan phpvms:navdata .PHONY: tests tests: test diff --git a/app/Http/Controllers/Frontend/FlightController.php b/app/Http/Controllers/Frontend/FlightController.php index eb172412..71f5d14f 100644 --- a/app/Http/Controllers/Frontend/FlightController.php +++ b/app/Http/Controllers/Frontend/FlightController.php @@ -127,11 +127,11 @@ class FlightController extends AppBaseController return redirect(route('frontend.dashboard.index')); } - $coords = $this->geoSvc->flightGeoJson($flight); + $map_features = $this->geoSvc->flightGeoJson($flight); return $this->view('flights.show', [ 'flight' => $flight, - 'coords' => $coords, + 'map_features' => $map_features, ]); } } diff --git a/app/Http/Controllers/Frontend/PirepController.php b/app/Http/Controllers/Frontend/PirepController.php index 957180fb..54f1762d 100644 --- a/app/Http/Controllers/Frontend/PirepController.php +++ b/app/Http/Controllers/Frontend/PirepController.php @@ -120,11 +120,11 @@ class PirepController extends Controller return redirect(route('frontend.pirep.index')); } - $coords = $this->geoSvc->pirepGeoJson($pirep); + $map_featuers = $this->geoSvc->pirepGeoJson($pirep); return $this->view('pireps.show', [ 'pirep' => $pirep, - 'coords' => $coords, + 'map_features' => $map_featuers, ]); } } diff --git a/app/Models/Enums/NavaidType.php b/app/Models/Enums/NavaidType.php index 3be72575..950b6668 100644 --- a/app/Models/Enums/NavaidType.php +++ b/app/Models/Enums/NavaidType.php @@ -42,4 +42,16 @@ class NavaidType extends EnumBase NavaidType::ANY_VOR => 'VOR', NavaidType::ANY_LOC => 'Localizer', ]; + + public static $icons = [ + NavaidType::VOR => 'VOR', + NavaidType::VOR_DME => 'VOR DME', + NavaidType::LOC => 'Localizer', + NavaidType::LOC_DME => 'Localizer DME', + NavaidType::NDB => 'Non-directional Beacon', + NavaidType::TACAN => 'TACAN', + NavaidType::UNKNOWN => 'Unknown', + NavaidType::ANY_VOR => 'VOR', + NavaidType::ANY_LOC => 'Localizer', + ]; } diff --git a/app/Services/GeoService.php b/app/Services/GeoService.php index 6267d589..0f58fe83 100644 --- a/app/Services/GeoService.php +++ b/app/Services/GeoService.php @@ -3,17 +3,18 @@ namespace App\Services; use Log; -//use \League\Geotools\Geotools; -use App\Models\Flight; -use App\Repositories\NavdataRepository; + +use \GeoJson\Geometry\Point; use \GeoJson\Geometry\LineString; use \GeoJson\Feature\Feature; use \GeoJson\Feature\FeatureCollection; -use League\Flysystem\Exception; use \League\Geotools\Geotools; use \League\Geotools\Coordinate\Coordinate; +use App\Models\Flight; +use App\Repositories\NavdataRepository; + /** * Return all of the coordinates, start to finish * Returned in the GeoJSON format @@ -33,7 +34,6 @@ class GeoService extends BaseService $this->navRepo = $navRepo; } - public function getClosestCoords($coordStart, $all_coords, $measure='flat') { $distance = []; @@ -92,39 +92,41 @@ class GeoService extends BaseService if($size === 0) { continue; } else if($size === 1) { - $point = $points[0]; - Log::info('name: ' . $point->id . ' - ' . $point->lat . 'x' . $point->lon); - - $coords[] = [ - $point->lat, - $point->lon, - ]; - + $coords[] = $point; continue; } # Find the point with the shortest distance Log::info('found ' . $size . ' for '. $route_point); - $potential_coords = []; - foreach($points as $point) { - #Log::debug('name: ' . $point->id . ' - '.$point->lat .'x'.$point->lon); - $potential_coords[] = [$point->lat, $point->lon]; - } - # Get the start point and then reverse the lat/lon reference # If the first point happens to have multiple possibilities, use # the starting point that was passed in - if(\count($coords) > 0) { + if (\count($coords) > 0) { $start_point = $coords[\count($coords) - 1]; - $start_point = [$start_point[0], $start_point[1]]; + $start_point = [$start_point->lat, $start_point->lon]; } else { $start_point = $start_coords; } - $coords[] = $this->getClosestCoords($start_point, $potential_coords); + # Put all of the lat/lon sets into an array to pick of what's clsest + # to the starting point + $potential_coords = []; + foreach($points as $point) { + $potential_coords[] = [$point->lat, $point->lon]; + } + + # returns an array with the closest lat/lon to start point + $closest_coords = $this->getClosestCoords($start_point, $potential_coords); + foreach($points as $point) { + if($point->lat === $closest_coords[0] && $point->lon === $closest_coords[1]) { + break; + } + } + + $coords[] = $point; } catch (\Exception $e) { Log::error($e); @@ -142,34 +144,56 @@ class GeoService extends BaseService */ public function flightGeoJson(Flight $flight): array { - $coords = []; - $coords[] = [$flight->dpt_airport->lon, $flight->dpt_airport->lat]; + $route_coords = []; + $route_points = []; + #$features = []; + + ## 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', + ] + ); - // TODO: Add markers for the start/end airports - // TODO: Read from the ACARS data table if($flight->route) { - $route_coords =$this->getCoordsFromRoute( + $all_route_points = $this->getCoordsFromRoute( $flight->dpt_airport->icao, $flight->arr_airport->icao, [$flight->dpt_airport->lat, $flight->dpt_airport->lon], $flight->route); // lat, lon needs to be reversed for GeoJSON - foreach($route_coords as $rc) { - $coords[] = [$rc[1], $rc[0]]; + foreach($all_route_points as $point) { + $route_coords[] = [$point->lon, $point->lat]; + $route_points[] = new Feature(new Point([$point->lon, $point->lat]), [ + 'name' => $point->name, + 'popup' => $point->name . ' (' . $point->name . ')', + 'icon' => '' + ]); } } - $coords[] = [$flight->arr_airport->lon, $flight->arr_airport->lat]; + ## Arrival Airport + $route_coords[] = [$flight->arr_airport->lon, $flight->arr_airport->lat,]; - $line = new LineString($coords); + $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', + ] + ); - $features = new FeatureCollection([ - new Feature($line, [], 1) - ]); + $route_points = new FeatureCollection($route_points); + $planned_route_line = new FeatureCollection([new Feature(new LineString($route_coords), [])]); return [ - 'features' => $features, + 'route_points' => $route_points, + 'planned_route_line' => $planned_route_line, ]; } @@ -180,35 +204,60 @@ class GeoService extends BaseService */ public function pirepGeoJson($pirep) { - $coords = []; - $coords[] = [$pirep->dpt_airport->lon, $pirep->dpt_airport->lat]; + $route_points = []; + $planned_rte_coords = []; + + $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, + 'popup' => $pirep->dpt_airport->full_name, + 'icon' => 'airport', + ] + ); // TODO: Add markers for the start/end airports // TODO: Check if there's data in the ACARS table if (!empty($pirep->route)) { - $route_coords = $this->getCoordsFromRoute( + $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 ($route_coords as $rc) { - $coords[] = [$rc[1], $rc[0]]; + 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, + 'popup' => $point->name . ' (' . $point->name . ')', + 'icon' => '' + ]); } } - $coords[] = [$pirep->arr_airport->lon, $pirep->arr_airport->lat]; + $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, + 'popup' => $pirep->arr_airport->full_name, + 'icon' => 'airport', + ] + ); - $line = new LineString($coords); + $route_points = new FeatureCollection($route_points); - $features = new FeatureCollection([ - new Feature($line, [], 1) + $planned_route_line = new LineString($planned_rte_coords); + + $planned_route = new FeatureCollection([ + new Feature($planned_route_line, [], 1) ]); return [ - 'features' => $features, + 'actual_route' => false, + 'route_points' => $route_points, + 'planned_route_line' => $planned_route, ]; } diff --git a/public/assets/system/js/system.js b/public/assets/system/js/system.js index 998bde24..e32864a7 100644 --- a/public/assets/system/js/system.js +++ b/public/assets/system/js/system.js @@ -60,6 +60,21 @@ const phpvms= (function() { return map; }; + + /** + * Show some popup text when a feature is clicked on + * @param feature + * @param layer + */ + const onFeaturePointClick = (feature, layer) => { + let popup_html = ""; + if (feature.properties && feature.properties.popup) { + popup_html += feature.properties.popup; + } + + layer.bindPopup(popup_html); + }; + return { /** @@ -69,7 +84,9 @@ const phpvms= (function() { render_route_map: (opts) => { opts = _.defaults(opts, { - features: null, // [ {name, lat, lon}, {name, lat, lon} ]; + route_points: null, + planned_route_line: null, // [ {name, lat, lon}, {name, lat, lon} ]; + actual_route_line: null, center: [], render_elem: 'map', overlay_elem: '', @@ -79,8 +96,6 @@ const phpvms= (function() { set_marker: false, }); - console.log(opts.features); - let map = draw_base_map(opts); if(opts.geodesic) { @@ -92,10 +107,10 @@ const phpvms= (function() { wrap: false, }).addTo(map); - geodesicLayer.geoJson(opts.features) + geodesicLayer.geoJson(opts.planned_route_line); map.fitBounds(geodesicLayer.getBounds()); } else { - let route = L.geoJSON(opts.features, { + let route = L.geoJSON(opts.planned_route_line, { "color": "#ff7800", "weight": 5, "opacity": 0.65 @@ -104,6 +119,31 @@ const phpvms= (function() { route.addTo(map); map.fitBounds(route.getBounds()); } + + // Draw the route points after + if (opts.route_points !== null) { + console.log(opts.route_points); + let route_points = L.geoJSON(opts.route_points, { + onEachFeature: onFeaturePointClick, + style: { + "color": "#1bff00", + "weight": 5, + "opacity": 0.65, + }, + pointToLayer: function (feature, latlng) { + return L.circleMarker(latlng, { + radius: 12, + fillColor: "#ff7800", + color: "#000", + weight: 1, + opacity: 1, + fillOpacity: 0.8 + }); + } + }); + + route_points.addTo(map); + } }, /** diff --git a/resources/views/layouts/default/flights/map.blade.php b/resources/views/layouts/default/flights/map.blade.php index 2e2b5772..b4fdbf46 100644 --- a/resources/views/layouts/default/flights/map.blade.php +++ b/resources/views/layouts/default/flights/map.blade.php @@ -12,7 +12,8 @@ @section('scripts') @endsection diff --git a/resources/views/layouts/default/pireps/map.blade.php b/resources/views/layouts/default/pireps/map.blade.php index 2e2b5772..b4fdbf46 100644 --- a/resources/views/layouts/default/pireps/map.blade.php +++ b/resources/views/layouts/default/pireps/map.blade.php @@ -12,7 +12,8 @@ @section('scripts') @endsection