phpvms/app/Console/Commands/NavdataCommand.php
2017-12-20 19:12:11 -06:00

213 lines
7.3 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use League\Geotools\Coordinate\Coordinate;
use App\Models\Navdata;
use App\Models\Enums\NavaidType;
class NavdataCommand extends Command
{
protected $signature = 'phpvms:navdata';
protected $description = '';
/**
* Streaming file read
* @param $filename
* @return \Generator
*/
protected function readFile($filename)
{
$fp = fopen($filename, 'rb');
while (($line = fgets($fp)) !== false) {
$line = rtrim($line, "\r\n");
if($line[0] === ';') {
continue;
}
yield $line;
}
fclose($fp);
}
/**
* Read and parse in the navaid file
* @throws \League\Geotools\Exception\InvalidArgumentException
*/
public function read_wp_nav_aid()
{
/*
* ....,....1....,....2....,....3....,....4....,....5....,....6..
* CORPUS CHRISTI CRP VORD 27.903764 -97.444881115.50H
* CORPUS CHRISTI ICRP ILSD 27.759597 -97.495508110.30T
* ROCKPORT RKP NDB 28.090569 -97.045544391.00N
* NNNNNNNNNNNNNNNNNNNNNNNNIIII TTTT dd.dddddd ddd.ddddddfff.ffC NNNN
* COL 1-24 Facility Name IIII
* COL 25-28 ID TTTT
* COL 30-33 Type ILS Insturment Landing System (Localizer)
* ILSD ILS/DME
* NDB Nondirectional Beacon
* NDBM NDB/Locator Middle Marker (LMM)
* NDBO NDB/Locator Outer Marker (LOM)
* MARI Unknown - seems to be same as MHW class NDB
* VOR VHF Omnidirectional Radio
* VORD VOR/DME (no separate code for VORTAC)
* dd.dddddd COL 34-43 Latitude (-Lat for South)
* ddd.dddddd COL 44-54 Longitude ( -Lon for West)
* fff.ff COL 55-60 Frequency (MHz for ILS/VOR KHz for NDB) See Note Below C
* Col 61 Class H High Altitude/Long Range
* N NDB
* T Terminal/Short RangeNote:
* If NDB frequency is above 999.99 KHz then the
* frequecy field still starts in col 55 and C is col 62,
* for example:....,....1....,....2....,....3....,....4....,....5....,....6..
* EREBUNI Y NDBM 40.104053 44.4505831180.00N
* Where the frequency above is 1180.00 KHz (1.180 MHz)
*/
$file_path = storage_path('/navdata/WPNAVAID.txt');
if (!file_exists($file_path)) {
$this->error('WPNAVAID.txt not found in storage/navdata');
return false;
}
$this->info('Importing navaids (WPNAVAID.txt) ...');
$generator = $this->readFile($file_path);
$imported = 0;
foreach($generator as $line) {
$navaid = [
'id' => trim(substr($line, 24, 4)), // ident column
'name' => trim(substr($line, 0, 24)),
'type' => trim(substr($line, 29, 4)),
'lat' => trim(substr($line, 33, 9)),
'lon' => trim(substr($line, 43, 11)),
'freq' => trim(substr($line, 54, 6)),
'class' => trim($line[60]),
];
# Map to the Navaid enum
switch($navaid['type'])
{
case 'ILS':
$navaid['type'] = NavaidType::LOC;
break;
case 'ILSDME':
$navaid['type'] = NavaidType::LOC_DME;
break;
case 'NDB':
case 'NDBM':
case 'NDBO':
case 'MARI':
$navaid['type'] = NavaidType::NDB;
break;
case 'VOR':
$navaid['type'] = NavaidType::VOR;
break;
case 'VORD':
$navaid['type'] = NavaidType::VOR_DME;
break;
default:
$navaid['type'] = NavaidType::UNKNOWN;
break;
}
#$coord = new Coordinate([$navaid['lat'], $navaid['lon']]);
#$navaid['lat'] = $coord->getLatitude();
#$navaid['lon'] = $coord->getLongitude();
if($navaid['id'] === 'LCH' || $navaid['id'] === 'RSG') {
print_r($navaid);
}
Navdata::updateOrCreate([
'id' => $navaid['id'], 'name' => $navaid['name']
], $navaid);
$imported++;
if($imported % 100 === 0) {
$this->info('Imported ' . $imported . ' entries...');
}
}
$this->info('Imported a total of ' . $imported . ' nav aids');
}
/**
*
*/
public function read_wp_nav_fix()
{
/*
* ....,....1....,....2....,...3....,....4....,....
* 5.8750W 8750W-87.000000 -50.000000
* GAREP GAREP 37.619689 128.073419
* CIHAD CIHAD 37.619719 -86.013228
* FOLAB FOLAB 37.619931 -87.359411
* KEKAD KEKAD 37.620000 67.518333
* NIKDE NIKDE 37.620567-122.563328
* ZUMAS ZUMAS 37.620575-113.167747
* NNNNN NNNNN dd.dddddd dd.dddddd
* Col 1-5 & 25-30 Fix Name
* dd.dddddd Col 32-40 Latitude degrees (-Lat for South, sign Col 31)
* ddd.dddddd Col 41-51 Longitude degrees (-Lon for West, decimal always Col 45)
* Note: The duplicate name fields may be the result how the FAA
* provides data, where there are many more fixes defined than provide
* in the airac data. For example, most terminal data is not included.
* This data includes airway crossing, radar service boundaries, etc.
*/
$file_path = storage_path('/navdata/WPNAVFIX.txt');
if(!file_exists($file_path)) {
$this->error('WPNAVFIX.txt not found in storage/navdata');
return false;
}
$this->info('Importing navaids (WPNAVFIX.txt) ...');
$generator = $this->readFile($file_path);
$imported = 0;
foreach ($generator as $line) {
$navfix = [
'id' => trim(substr($line, 0, 4)), // ident column
'name' => trim(substr($line, 24, 6)),
'type' => NavaidType::FIX,
'lat' => trim(substr($line, 30, 10)),
'lon' => trim(substr($line, 40, 11)),
];
switch ($navfix['type']) {
default:
$navfix['type'] = NavaidType::UNKNOWN;
break;
}
Navdata::updateOrCreate(['id' => $navfix['id']], $navfix);
$imported++;
if ($imported % 100 === 0) {
$this->info('Imported ' . $imported . ' entries...');
}
}
$this->info('Imported a total of ' . $imported . ' nav fixes');
}
public function handle()
{
$this->info('Emptying the current navdata...');
Navdata::query()->truncate();
$this->info('Looking for nav files...');
$this->read_wp_nav_aid();
$this->read_wp_nav_fix();
}
}