add metar lib and adding some modifications
This commit is contained in:
parent
129c551fa0
commit
a31b704203
File diff suppressed because it is too large
Load Diff
214
app/Support/MetarWrapper.php
Normal file
214
app/Support/MetarWrapper.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
use MetarDecoder\MetarDecoder;
|
||||
|
||||
/**
|
||||
* Wrapper around the METAR decoder. Compensate for
|
||||
* errors and have tests around this functionality
|
||||
* @package App\Support
|
||||
*/
|
||||
class MetarWrapper
|
||||
{
|
||||
private $metar,
|
||||
$metar_str;
|
||||
|
||||
/**
|
||||
* Metar constructor.
|
||||
* @param $metar_str
|
||||
*/
|
||||
public function __construct($metar_str)
|
||||
{
|
||||
$decoder = new MetarDecoder();
|
||||
$this->metar = $decoder->parse($metar_str);
|
||||
$this->metar_str = $metar_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this is VFR or IFR conditions
|
||||
* @return string
|
||||
*/
|
||||
public function getCategory(): string
|
||||
{
|
||||
$category = 'VFR';
|
||||
|
||||
$visibility = $this->getVisibility(false);
|
||||
$ceiling = $this->getCeiling(false);
|
||||
|
||||
if ($visibility < 3 || $ceiling < 1000) {
|
||||
$category = 'IFR';
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ceiling
|
||||
* @param bool $convert
|
||||
* @return int
|
||||
*/
|
||||
public function getCeiling($convert = true): int
|
||||
{
|
||||
$ceiling = 1000;
|
||||
$clouds = $this->metar->getClouds();
|
||||
if ($clouds && \count($clouds) > 0) {
|
||||
$ceiling = $clouds[0]->getBaseHeight()->getValue();
|
||||
}
|
||||
|
||||
if(!$convert) {
|
||||
return $ceiling;
|
||||
}
|
||||
|
||||
return $ceiling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the cloud layers
|
||||
*/
|
||||
public function getClouds(): array
|
||||
{
|
||||
if (!$this->metar->getClouds()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$layers = [];
|
||||
$unit = setting('units.altitude');
|
||||
|
||||
foreach($this->metar->getClouds() as $cloud) {
|
||||
if($unit === 'ft') {
|
||||
$base_height = $cloud->getBaseHeight()->getValue();
|
||||
} else {
|
||||
$base_height = $cloud->getBaseHeight()->getConvertedValue('m');
|
||||
}
|
||||
|
||||
$layers[] = [
|
||||
'amount' => $cloud->getAmount(),
|
||||
'base_height' => $base_height,
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
return $layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Last update time
|
||||
* @return string
|
||||
*/
|
||||
public function getLastUpdate(): string
|
||||
{
|
||||
return $this->metar->getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pressure, pass in the unit type
|
||||
* @param string $unit Pass mb for millibars, hg for hg
|
||||
* @return float|null
|
||||
*/
|
||||
public function getPressure($unit = 'mb')
|
||||
{
|
||||
if (!$this->metar->getPressure()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$pressure = $this->metar->getPressure()->getValue();
|
||||
if (strtolower($unit) === 'mb') {
|
||||
return $pressure;
|
||||
}
|
||||
|
||||
return round($pressure * 33.86, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw metar string
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRawMetar()
|
||||
{
|
||||
return $this->metar_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temperature, if it exists in the METAR
|
||||
* Convert to the units that are set in the VA
|
||||
* @return float|null
|
||||
*/
|
||||
public function getTemperature()
|
||||
{
|
||||
if (!$this->metar->getAirTemperature()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(setting('units.temperature') === 'c') {
|
||||
return $this->metar->getAirTemperature()->getValue();
|
||||
}
|
||||
|
||||
// Convert to F
|
||||
round(($this->metar->getAirTemperature()->getValue() * 9 / 5) + 32, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility
|
||||
* @param bool $convert
|
||||
* @return int
|
||||
*/
|
||||
public function getVisibility($convert=true): int
|
||||
{
|
||||
// initially in miles
|
||||
$visibility = 10; // assume it's ok and VFR
|
||||
$vis = $this->metar->getVisibility();
|
||||
if ($vis) {
|
||||
$vis = $vis->getVisibility();
|
||||
if ($vis) {
|
||||
$visibility = (int) $vis->getValue();
|
||||
|
||||
if ($convert && setting('units.distance') === 'km') {
|
||||
return $vis->getConvertedValue('m') / 1000;
|
||||
}
|
||||
|
||||
return $visibility;
|
||||
}
|
||||
}
|
||||
|
||||
if($convert && setting('units.distance') === 'km') {
|
||||
return round($visibility * 1.60934, 2);
|
||||
}
|
||||
|
||||
return $visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return wind information
|
||||
*/
|
||||
public function getWinds()
|
||||
{
|
||||
$sw = $this->metar->getSurfaceWind();
|
||||
if (!$sw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ret = [
|
||||
'speed' => null,
|
||||
'direction' => null,
|
||||
'gusts' => null,
|
||||
];
|
||||
|
||||
$mean_speed = $sw->getMeanSpeed();
|
||||
if($mean_speed) {
|
||||
$ret['speed'] = $mean_speed->getConvertedValue('kt');
|
||||
}
|
||||
|
||||
$dir = $sw->getMeanDirection();
|
||||
if($dir) {
|
||||
$ret['direction'] = $dir->getValue();
|
||||
}
|
||||
|
||||
$gusts = $sw->getSpeedVariations();
|
||||
if($gusts) {
|
||||
$ret['gusts'] = $gusts->getConvertedValue('kt');
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ namespace App\Widgets;
|
||||
|
||||
use App\Interfaces\Widget;
|
||||
use App\Support\Http;
|
||||
use App\Support\Metar;
|
||||
use App\Support\MetarWrapper;
|
||||
use App\Support\Units\Distance;
|
||||
use App\Support\Units\Temperature;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@ -50,7 +50,7 @@ class Weather extends Widget
|
||||
$raw_metar = $metar_class->get_metar($this->config['icao']);
|
||||
|
||||
if ($raw_metar && $raw_metar !== '') {
|
||||
$metar = new Metar($raw_metar);
|
||||
$metar = new MetarWrapper($raw_metar);
|
||||
$wind = $metar->getWinds();
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,32 @@
|
||||
<?php
|
||||
|
||||
use \App\Support\Metar;
|
||||
use App\Repositories\SettingRepository;
|
||||
use App\Support\Metar;
|
||||
|
||||
/**
|
||||
* Test the parsing/support class of the metar
|
||||
*/
|
||||
class MetarTest extends TestCase
|
||||
{
|
||||
private $settingsRepo;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
$this->settingsRepo = app(SettingRepository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding/subtracting a percentage
|
||||
*/
|
||||
public function testMetar1()
|
||||
{
|
||||
$metar =
|
||||
'KJFK 042151Z 28026G39KT 10SM '
|
||||
.'FEW055 SCT095 BKN110 BKN230 12/M04 '
|
||||
.'A2958 RMK AO2 PK WND 27045/2128 PRESRR '
|
||||
.'SLP018 T01221044';
|
||||
'KJFK 042151Z 28026G39KT 10SM FEW055 SCT095 BKN110 BKN230 12/M04 A2958 RMK AO2 PK WND 27045/2128 PRESRR SLP018 T01221044';
|
||||
|
||||
$parsed = new Metar($metar);
|
||||
#$m = new Metar($metar);
|
||||
#$parsed = $m->result;
|
||||
$parsed = Metar::parse($metar);
|
||||
|
||||
/*
|
||||
Conditions VFR visibility 10NM
|
||||
@ -29,6 +37,39 @@ class MetarTest extends TestCase
|
||||
BKN @ 23000 ft
|
||||
Wind 26 kts @ 280° gusts to 39
|
||||
*/
|
||||
$this->assertEquals('KJFK', $parsed['station']);
|
||||
$this->assertEquals('Wed, 04 Apr 2018 21:51:00 +0000', $parsed['observed_date']);
|
||||
$this->assertEquals(4, $parsed['observed_day']);
|
||||
$this->assertEquals('21:51 UTC', $parsed['observed_time']);
|
||||
#$this->assertEquals('3:42 hr. ago', $parsed['observed_age']);
|
||||
$this->assertEquals(13.38, $parsed['wind_speed']);
|
||||
$this->assertEquals(20.06, $parsed['wind_gust_speed']);
|
||||
$this->assertEquals(280, $parsed['wind_direction']);
|
||||
$this->assertEquals('W', $parsed['wind_direction_label']);
|
||||
$this->assertEquals(false, $parsed['wind_direction_varies']);
|
||||
$this->assertEquals(16093, $parsed['visibility']);
|
||||
$this->assertEquals('16093 meters', $parsed['visibility_report']);
|
||||
$this->assertEquals('Dry', $parsed['present_weather_report']);
|
||||
|
||||
$this->assertCount(4, $parsed['clouds']);
|
||||
$this->assertEquals(
|
||||
'A few at 1676 meters; scattered at 2896 meters; broken sky at 3353 meters; broken sky at 7010 meters',
|
||||
$parsed['clouds_report']);
|
||||
$this->assertEquals(1676, $parsed['cloud_height']);
|
||||
$this->assertEquals(false, $parsed['cavok']);
|
||||
|
||||
$this->assertEquals(12, $parsed['temperature']);
|
||||
$this->assertEquals(54, $parsed['temperature_f']);
|
||||
|
||||
$this->assertEquals(-4, $parsed['dew_point']);
|
||||
$this->assertEquals(25, $parsed['dew_point_f']);
|
||||
|
||||
$this->assertEquals(33, $parsed['humidity']);
|
||||
$this->assertEquals(29.58, $parsed['barometer']);
|
||||
$this->assertEquals(0.87, $parsed['barometer_in']);
|
||||
|
||||
$this->assertEquals('AO2 PK WND 27045/2128 PRESRR SLP018 T01221044', $parsed['remarks']);
|
||||
|
||||
}
|
||||
|
||||
public function testMetar2()
|
||||
|
Loading…
Reference in New Issue
Block a user