cleanup of geojson and route map code

This commit is contained in:
Nabeel Shahzad
2018-01-01 19:02:22 -06:00
parent d4f69bee2a
commit 78af2fd637
4 changed files with 111 additions and 106 deletions
+6 -1
View File
@@ -8,7 +8,12 @@ use \GeoJson\Feature\Feature;
use \GeoJson\Feature\FeatureCollection; use \GeoJson\Feature\FeatureCollection;
/** /**
* Class GeoJson * Return different points/features in GeoJSON format
* https://tools.ietf.org/html/rfc7946
*
* Once a PIREP is accepted, save this returned structure as a
* JSON-encoded string into the raw_data field of the PIREP row
*
* @package App\Models * @package App\Models
*/ */
class GeoJson class GeoJson
+84 -98
View File
@@ -3,29 +3,24 @@
namespace App\Services; namespace App\Services;
use Log; use Log;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Models\Enums\AcarsType; use App\Models\Enums\AcarsType;
use App\Repositories\AcarsRepository; use App\Repositories\AcarsRepository;
use \GeoJson\Geometry\Point;
use \GeoJson\Geometry\LineString;
use \GeoJson\Feature\Feature;
use \GeoJson\Feature\FeatureCollection;
use \League\Geotools\Geotools; use \League\Geotools\Geotools;
use \League\Geotools\Coordinate\Coordinate; use \League\Geotools\Coordinate\Coordinate;
use App\Models\Acars;
use App\Models\GeoJson; use App\Models\GeoJson;
use App\Models\Flight; use App\Models\Flight;
use App\Models\Pirep; use App\Models\Pirep;
use App\Repositories\NavdataRepository; use App\Repositories\NavdataRepository;
use Nwidart\Modules\Collection;
/** /**
* Return different points/features in GeoJSON format * Class GeoService
* https://tools.ietf.org/html/rfc7946 * @package App\Services
*
* Once a PIREP is accepted, save this returned structure as a
* JSON-encoded string into the raw_data field of the PIREP row
*
*/ */
class GeoService extends BaseService class GeoService extends BaseService
{ {
@@ -64,81 +59,84 @@ class GeoService extends BaseService
} }
/** /**
* Pass in a route string, with the departure/arrival airports, and the
* starting coordinates. Return the route points that have been found
* from the `navdata` table
* @param $dep_icao string ICAO to ignore * @param $dep_icao string ICAO to ignore
* @param $arr_icao string ICAO to ignore * @param $arr_icao string ICAO to ignore
* @param $start_coords array Starting point, [x, y] * @param $start_coords array Starting point, [x, y]
* @param $route string Textual route * @param $route string Textual route
* @return array * @return array
*/ */
public function getCoordsFromRoute($dep_icao, $arr_icao, $start_coords, $route) public function getCoordsFromRoute($dep_icao, $arr_icao, $start_coords, $route): array
{ {
$coords = []; $coords = [];
$split_route = explode(' ', $route); $filter_points = [$dep_icao, $arr_icao, 'SID', 'STAR'];
$skip = [ $split_route = collect(explode(' ', $route))->transform(function($point) {
$dep_icao, if(empty($point)) { return false; }
$arr_icao, return strtoupper(trim($point));
'SID', })->filter(function($point) use ($filter_points) {
'STAR' return !(empty($point) || \in_array($point, $filter_points, true));
]; });
foreach ($split_route as $route_point) { /**
* @var $split_route Collection
$route_point = trim($route_point); * @var $route_point Acars
*/
if (\in_array($route_point, $skip, true)) { foreach ($split_route as $route_point)
continue; {
} Log::debug('Looking for ' . $route_point);
try { try {
Log::debug('Looking for ' . $route_point);
$points = $this->navRepo->findWhere(['id' => $route_point]); $points = $this->navRepo->findWhere(['id' => $route_point]);
$size = \count($points); } catch(ModelNotFoundException $e){
continue;
if($size === 0) {
continue;
} else if($size === 1) {
$point = $points[0];
Log::info('name: ' . $point->id . ' - ' . $point->lat . 'x' . $point->lon);
$coords[] = $point;
continue;
}
# Find the point with the shortest distance
Log::info('found ' . $size . ' for '. $route_point);
# 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) {
$start_point = $coords[\count($coords) - 1];
$start_point = [$start_point->lat, $start_point->lon];
} else {
$start_point = $start_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) { } catch (\Exception $e) {
Log::error($e); Log::error($e);
continue; continue;
} }
$size = \count($points);
if ($size === 0) {
continue;
} elseif ($size === 1) {
$point = $points[0];
Log::debug('name: ' . $point->id . ' - ' . $point->lat . 'x' . $point->lon);
$coords[] = $point;
continue;
}
# Find the point with the shortest distance
Log::info('found ' . $size . ' for '. $route_point);
# 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) {
$start_point = $coords[\count($coords) - 1];
$start_point = [$start_point->lat, $start_point->lon];
} else {
$start_point = $start_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;
} }
return $coords; return $coords;
@@ -177,35 +175,24 @@ class GeoService extends BaseService
*/ */
public function getFeatureFromAcars(Pirep $pirep) public function getFeatureFromAcars(Pirep $pirep)
{ {
$route_line = []; $route = new GeoJson();
$route_points = [];
/** /**
* @var $point \App\Models\Acars * @var $point \App\Models\Acars
*/ */
$counter = 1; $counter = 1;
foreach ($pirep->acars as $point) { foreach ($pirep->acars as $point) {
$route_line[] = [$point->lon, $point->lat]; $route->addPoint($point->lat, $point->lon, [
$route_points[] = new Feature( 'pirep_id' => $pirep->id,
new Point([$point->lon, $point->lat]), [ 'name' => $point->altitude,
'pirep_id' => $pirep->id, 'popup' => $counter . '<br />GS: ' . $point->gs . '<br />Alt: ' . $point->altitude,
'name' => $point->altitude, ]);
'popup' => $counter . '<br />GS: ' . $point->gs . '<br />Alt: ' . $point->altitude,
]);
++$counter;
}
if(\count($route_line) >= 2) {
$route_line = new Feature(new LineString($route_line));
$route_line = new FeatureCollection([$route_line]);
} else {
$route_line = new FeatureCollection([]);
} }
return [ return [
'line' => $route_line, 'line' => $route->getLine(),
'points' => new FeatureCollection($route_points) 'points' => $route->getPoints()
]; ];
} }
@@ -214,7 +201,7 @@ class GeoService extends BaseService
*/ */
public function getFeatureForLiveFlights($pireps) public function getFeatureForLiveFlights($pireps)
{ {
$flight_points = []; $flight = new GeoJson();
/** /**
* @var Pirep $pirep * @var Pirep $pirep
@@ -229,17 +216,16 @@ class GeoService extends BaseService
continue; continue;
} }
$flight_points[] = new Feature( $flight->addPoint($point->lat, $point->lon, [
new Point([$point->lon, $point->lat]), [ 'pirep_id' => $pirep->id,
'pirep_id' => $pirep->id, 'gs' => $point->gs,
'gs' => $point->gs, 'alt' => $point->altitude,
'alt' => $point->altitude, 'heading' => $point->heading ?: 0,
'heading' => $point->heading ?: 0, 'popup' => $pirep->ident . '<br />GS: ' . $point->gs . '<br />Alt: ' . $point->altitude,
'popup' => $pirep->ident . '<br />GS: ' . $point->gs . '<br />Alt: ' . $point->altitude, ]);
]);
} }
return new FeatureCollection($flight_points); return $flight->getPoints();
} }
/** /**
+21 -2
View File
@@ -2,14 +2,16 @@
use App\Facades\Utils; use App\Facades\Utils;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class GeoTest extends TestCase class GeoTest extends TestCase
{ {
public function setUp() { use WithoutMiddleware;
}
public function testClosestPoint() public function testClosestPoint()
{ {
$geoSvc = app('\App\Services\GeoService'); $geoSvc = app('\App\Services\GeoService');
/** /**
* [2017-12-21 00:54:10] dev.INFO: Looking for ATL * [2017-12-21 00:54:10] dev.INFO: Looking for ATL
* [2017-12-21 00:54:10] dev.INFO: ATL - 36.58106 x 26.375603 * [2017-12-21 00:54:10] dev.INFO: ATL - 36.58106 x 26.375603
@@ -33,4 +35,21 @@ class GeoTest extends TestCase
$this->assertEquals([52.15527, 22.200833], $coords); $this->assertEquals([52.15527, 22.200833], $coords);
} }
/**
* Make sure the departure airports/sid/star are all filtered out
*/
public function testGetCoords()
{
$geoSvc = app('\App\Services\GeoService');
$route = [];
$navpoints = factory(App\Models\Navdata::class, 5)->create();
foreach ($navpoints as $point) {
$route[] = $point->id;
}
$route_str = 'KAUS SID '.implode(' ', $route).' STAR KJFK';
$coords = $geoSvc->getCoordsFromRoute('KAUS', 'KJFK', [0, 0], $route_str);
$this->assertEquals(5, \count($coords));
}
} }
-5
View File
@@ -159,9 +159,4 @@ class PIREPTest extends TestCase
# Make sure latest PIREP was updated # Make sure latest PIREP was updated
$this->assertNotEquals($last_pirep->id, $latest_pirep->id); $this->assertNotEquals($last_pirep->id, $latest_pirep->id);
} }
public function testPirepFinances()
{
}
} }