Add airport overview page and links to it #225
This commit is contained in:
@@ -113,6 +113,15 @@ class CreateSettingsTable extends Migration
|
|||||||
'description' => 'The units for fuel for display',
|
'description' => 'The units for fuel for display',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->addSetting('units.temperature', [
|
||||||
|
'name' => 'Temperature Units',
|
||||||
|
'group' => 'units',
|
||||||
|
'value' => 'f',
|
||||||
|
'type' => 'select',
|
||||||
|
'options' => 'f=Fahrenheit,c=Celsius',
|
||||||
|
'description' => 'The units for temperature',
|
||||||
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BIDS
|
* BIDS
|
||||||
*/
|
*/
|
||||||
|
|||||||
32
app/Support/Http.php
Normal file
32
app/Support/Http.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Support;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for HTTP stuff
|
||||||
|
* @package App\Support
|
||||||
|
*/
|
||||||
|
class Http
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Download a URI. If a file is given, it will save the downloaded
|
||||||
|
* content into that file
|
||||||
|
* @param $uri
|
||||||
|
* @param array $opts
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function get($uri, array $opts)
|
||||||
|
{
|
||||||
|
$client = new Client();
|
||||||
|
$response = $client->request('GET', $uri, $opts);
|
||||||
|
|
||||||
|
$body = $response->getBody()->getContents();
|
||||||
|
if ($response->getHeader('content-type') === 'application/json') {
|
||||||
|
$body = \GuzzleHttp\json_decode($body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
app/Widgets/CheckWx.php
Normal file
52
app/Widgets/CheckWx.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Widgets;
|
||||||
|
|
||||||
|
use App\Interfaces\Widget;
|
||||||
|
use App\Support\Http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a widget for the 3rd party CheckWX service
|
||||||
|
* @package App\Widgets
|
||||||
|
*/
|
||||||
|
class CheckWx extends Widget
|
||||||
|
{
|
||||||
|
protected $config = [
|
||||||
|
'icao' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to get the data from the CheckWX API
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
if (!config('checkwx.api_key')) {
|
||||||
|
$data = null;
|
||||||
|
} else {
|
||||||
|
$url = config('checkwx.url').'/metar/'.$this->config['icao'].'/decoded';
|
||||||
|
$data = Http::get($url, [
|
||||||
|
'headers' => [
|
||||||
|
'X-API-Key' => config('checkwx.api_key'),
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = json_decode($data);
|
||||||
|
#dd($data);
|
||||||
|
|
||||||
|
if($data->results === 1) {
|
||||||
|
$data = $data->data[0];
|
||||||
|
} else {
|
||||||
|
$data = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('widgets.check_wx', [
|
||||||
|
'config' => $this->config,
|
||||||
|
'data' => $data,
|
||||||
|
'unit_alt' => setting('units.altitude'),
|
||||||
|
'unit_dist' => setting('units.distance'),
|
||||||
|
'unit_temp' => setting('units.temperature'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -195,3 +195,29 @@ if (!function_exists('show_date')) {
|
|||||||
return $date->timezone($timezone)->toFormattedDateString();
|
return $date->timezone($timezone)->toFormattedDateString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('_fmt')) {
|
||||||
|
/**
|
||||||
|
* Replace strings
|
||||||
|
* @param $line "Hi, my name is :name"
|
||||||
|
* @param array $replace ['name' => 'Nabeel']
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function _fmt($line, array $replace)
|
||||||
|
{
|
||||||
|
if (empty($replace)) {
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($replace as $key => $value) {
|
||||||
|
$key = strtolower($key);
|
||||||
|
$line = str_replace(
|
||||||
|
[':'.$key],
|
||||||
|
[$value],
|
||||||
|
$line
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
10
config/checkwx.php
Normal file
10
config/checkwx.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* For METAR and TAF features, register for an API key at
|
||||||
|
* https://www.checkwx.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
'url' => 'https://api.checkwx.com',
|
||||||
|
'api_key' => false,
|
||||||
|
];
|
||||||
16
config/map.php
Normal file
16
config/map.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Configuration for mapping URLs and stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* This can really be any METAR service, as long as it returns GeoJSON
|
||||||
|
*/
|
||||||
|
'metar_wms' => [
|
||||||
|
'url' => 'https://ogcie.iblsoft.com/observations?',
|
||||||
|
'params' => [
|
||||||
|
'layers' => 'metar'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
@@ -34,12 +34,6 @@ return [
|
|||||||
*/
|
*/
|
||||||
'vacentral_api_url' => 'https://api.vacentral.net',
|
'vacentral_api_url' => 'https://api.vacentral.net',
|
||||||
|
|
||||||
/**
|
|
||||||
* For METAR features, register for an API key at
|
|
||||||
* https://www.checkwx.com
|
|
||||||
*/
|
|
||||||
'checkwx_api_key' => env('CHECKWX_API_KEY', false),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Misc Settings
|
* Misc Settings
|
||||||
*/
|
*/
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/assets/global/css/images/layers-2x.png
Normal file
BIN
public/assets/global/css/images/layers-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/assets/global/css/images/layers.png
Normal file
BIN
public/assets/global/css/images/layers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
public/assets/global/css/images/marker-icon-2x.png
Normal file
BIN
public/assets/global/css/images/marker-icon-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
public/assets/global/css/images/marker-icon.png
Normal file
BIN
public/assets/global/css/images/marker-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/assets/global/css/images/marker-shadow.png
Normal file
BIN
public/assets/global/css/images/marker-shadow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 618 B |
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=373465bdf8c91ab66596",
|
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=9fc76ac10f8d1c1906a0",
|
||||||
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=dae9f7e5d10b71e28486",
|
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=dae9f7e5d10b71e28486",
|
||||||
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=a11d81c6bf8d7a548c86",
|
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=a11d81c6bf8d7a548c86",
|
||||||
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=7cc40ba818ed0f94c3fb",
|
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=aa2a19e307306470a073",
|
||||||
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=c65781eda730445d666e",
|
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=c65781eda730445d666e",
|
||||||
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
||||||
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
const leaflet = require('leaflet');
|
const leaflet = require('leaflet');
|
||||||
|
|
||||||
import draw_base_map from './base_map'
|
import draw_base_map from './base_map'
|
||||||
|
import { addWMSLayer } from './helpers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a map with the airspace, etc around a given set of coords
|
* Render a map with the airspace, etc around a given set of coords
|
||||||
@@ -17,16 +18,27 @@ export default (opts) => {
|
|||||||
zoom: 12,
|
zoom: 12,
|
||||||
layers: [],
|
layers: [],
|
||||||
set_marker: true,
|
set_marker: true,
|
||||||
|
marker_popup: '',
|
||||||
|
|
||||||
|
// Passed from the config/maps.php file
|
||||||
|
metar_wms: {
|
||||||
|
url: '',
|
||||||
|
params: {}
|
||||||
|
},
|
||||||
}, opts);
|
}, opts);
|
||||||
|
|
||||||
let map = draw_base_map(opts)
|
let map = draw_base_map(opts);
|
||||||
const coords = [opts.lat, opts.lon]
|
const coords = [opts.lat, opts.lon];
|
||||||
console.log('Applying coords', coords)
|
console.log('Applying coords', coords);
|
||||||
|
|
||||||
map.setView(coords, opts.zoom)
|
map.setView(coords, opts.zoom);
|
||||||
if (opts.set_marker === true) {
|
if (opts.set_marker === true) {
|
||||||
leaflet.marker(coords).addTo(map)
|
leaflet.marker(coords).addTo(map).bindPopup(opts.marker_popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
if(opts.metar_wms.url !== '') {
|
||||||
|
addWMSLayer(map, opts.metar_wms);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,14 +50,14 @@ export default (opts) => {
|
|||||||
feature_groups.push(openaip_cached_basemap);
|
feature_groups.push(openaip_cached_basemap);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const openaip_basemap_phys_osm = leaflet.featureGroup(feature_groups)
|
const openaip_basemap_phys_osm = leaflet.featureGroup(feature_groups);
|
||||||
|
|
||||||
let map = leaflet.map('map', {
|
let map = leaflet.map('map', {
|
||||||
layers: [openaip_basemap_phys_osm],
|
layers: [openaip_basemap_phys_osm],
|
||||||
center: opts.center,
|
center: opts.center,
|
||||||
zoom: opts.zoom,
|
zoom: opts.zoom,
|
||||||
scrollWheelZoom: false,
|
scrollWheelZoom: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
const attrib = leaflet.control.attribution({position: 'bottomleft'})
|
const attrib = leaflet.control.attribution({position: 'bottomleft'})
|
||||||
attrib.addAttribution('<a href="https://www.thunderforest.com" target="_blank" style="">Thunderforest</a>')
|
attrib.addAttribution('<a href="https://www.thunderforest.com" target="_blank" style="">Thunderforest</a>')
|
||||||
|
|||||||
47
resources/js/maps/helpers.js
Normal file
47
resources/js/maps/helpers.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
const leaflet = require('leaflet');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a WMS layer to a map. opts must be:
|
||||||
|
* {
|
||||||
|
* url: '',
|
||||||
|
* params: {}
|
||||||
|
* }
|
||||||
|
* @param map
|
||||||
|
* @param opts
|
||||||
|
*/
|
||||||
|
export function addWMSLayer(map, opts) {
|
||||||
|
|
||||||
|
if(opts.url === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.params = Object.assign({
|
||||||
|
format: 'image/png',
|
||||||
|
transparent: true,
|
||||||
|
maxZoom: 14,
|
||||||
|
minZoom: 4,
|
||||||
|
}, opts.params);
|
||||||
|
|
||||||
|
const mlayer = leaflet.tileLayer.wms(
|
||||||
|
opts.url, opts.params
|
||||||
|
);
|
||||||
|
|
||||||
|
mlayer.addTo(map);
|
||||||
|
|
||||||
|
return mlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a popup
|
||||||
|
* @param feature
|
||||||
|
* @param layer
|
||||||
|
*/
|
||||||
|
export function showFeaturePopup(feature, layer) {
|
||||||
|
let popup_html = '';
|
||||||
|
if (feature.properties && feature.properties.popup) {
|
||||||
|
popup_html += feature.properties.popup
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.bindPopup(popup_html)
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ const leaflet = require('leaflet');
|
|||||||
|
|
||||||
import draw_base_map from './base_map'
|
import draw_base_map from './base_map'
|
||||||
import { ACTUAL_ROUTE_COLOR, PLAN_ROUTE_COLOR } from './config'
|
import { ACTUAL_ROUTE_COLOR, PLAN_ROUTE_COLOR } from './config'
|
||||||
|
import {addWMSLayer} from './helpers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show some popup text when a feature is clicked on
|
* Show some popup text when a feature is clicked on
|
||||||
@@ -48,11 +49,19 @@ export default (opts) => {
|
|||||||
actual_route_points: null,
|
actual_route_points: null,
|
||||||
actual_route_line: null,
|
actual_route_line: null,
|
||||||
render_elem: 'map',
|
render_elem: 'map',
|
||||||
|
metar_wms: {
|
||||||
|
url: '',
|
||||||
|
params: {}
|
||||||
|
},
|
||||||
}, opts);
|
}, opts);
|
||||||
|
|
||||||
console.log(opts)
|
console.log(opts);
|
||||||
|
|
||||||
let map = draw_base_map(opts)
|
let map = draw_base_map(opts);
|
||||||
|
|
||||||
|
if (opts.metar_wms.url !== '') {
|
||||||
|
addWMSLayer(map, opts.metar_wms);
|
||||||
|
}
|
||||||
|
|
||||||
let geodesicLayer = leaflet.geodesic([], {
|
let geodesicLayer = leaflet.geodesic([], {
|
||||||
weight: 7,
|
weight: 7,
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ return [
|
|||||||
'api_key' => '',
|
'api_key' => '',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// For METAR features, register for an API key at
|
||||||
|
// https://www.checkwx.com
|
||||||
|
'checkwx' => [
|
||||||
|
'url' => 'https://api.checkwx.com',
|
||||||
|
'api_key' => false,
|
||||||
|
],
|
||||||
|
|
||||||
#
|
#
|
||||||
# Other settings and configuration you might not need to modify
|
# Other settings and configuration you might not need to modify
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -3,19 +3,28 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-12">
|
||||||
<h2 class="description">{{ $airport->full_name }}</h2>
|
<h2 class="description">{{ $airport->full_name }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-5">
|
||||||
|
|
||||||
|
{{ Widget::checkWx([
|
||||||
|
'icao' => $airport->icao,
|
||||||
|
]) }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-7">
|
||||||
{{ Widget::airspaceMap([
|
{{ Widget::airspaceMap([
|
||||||
'width' => '100%',
|
'width' => '100%',
|
||||||
'height' => '250px',
|
'height' => '400px',
|
||||||
'lat' => $airport->lat,
|
'lat' => $airport->lat,
|
||||||
'lon' => $airport->lon,
|
'lon' => $airport->lon,
|
||||||
]) }}
|
]) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row" style="height: 30px;">
|
||||||
|
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h3 class="description">Inbound Flights</h3>
|
<h3 class="description">Inbound Flights</h3>
|
||||||
@@ -26,7 +35,6 @@
|
|||||||
@else
|
@else
|
||||||
@each('airports.table', $inbound_flights, 'flight')
|
@each('airports.table', $inbound_flights, 'flight')
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<h3 class="description">Outbound Flights</h3>
|
<h3 class="description">Outbound Flights</h3>
|
||||||
@each('airports.table', $outbound_flights, 'flight')
|
@each('airports.table', $outbound_flights, 'flight')
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
phpvms.map.render_route_map({
|
phpvms.map.render_route_map({
|
||||||
route_points: {!! json_encode($map_features['route_points']) !!},
|
route_points: {!! json_encode($map_features['route_points']) !!},
|
||||||
planned_route_line: {!! json_encode($map_features['planned_route_line']) !!},
|
planned_route_line: {!! json_encode($map_features['planned_route_line']) !!},
|
||||||
|
metar_wms: {!! json_encode(config('map.metar_wms')) !!},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h2 class="description">{{ $flight->ident }} - {{ $flight->dpt_airport->full_name }} to {{ $flight->arr_airport->full_name }}</h2>
|
<h2 class="description">{{ $flight->ident }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -13,29 +13,26 @@
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Departure</td>
|
<td>Departure</td>
|
||||||
<td>{{ $flight->dpt_airport->icao }} @ {{ $flight->dpt_time }}</td>
|
<td>
|
||||||
|
<a href="{{route('frontend.airports.show', ['id'=>$flight->dpt_airport_id])}}">
|
||||||
|
{{ $flight->dpt_airport->full_name }}</a>
|
||||||
|
@ {{ $flight->dpt_time }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Arrival</td>
|
<td>Arrival</td>
|
||||||
<td>{{ $flight->arr_airport->icao }} @ {{ $flight->arr_time }}</td>
|
<td>
|
||||||
|
<a href="{{route('frontend.airports.show', ['id'=>$flight->arr_airport_id])}}">
|
||||||
|
{{ $flight->arr_airport->full_name }}</a> @ {{ $flight->arr_time }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if($flight->alt_airport_id)
|
||||||
<tr>
|
|
||||||
<td>Route Code/Leg:</td>
|
|
||||||
<td>{{ $flight->route_code ?: '-' }}/{{ $flight->route_leg ?: '-' }}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Alternate Airport</td>
|
<td>Alternate Airport</td>
|
||||||
<td>
|
<td>
|
||||||
@if($flight->alt_airport_id)
|
{{ $flight->alt_airport->full_name }}
|
||||||
{{ $flight->alt_airport->full_name }}
|
|
||||||
@else
|
|
||||||
-
|
|
||||||
@endif
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@endif
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Route</td>
|
<td>Route</td>
|
||||||
@@ -49,5 +46,20 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@include("flights.map")
|
<div style="padding: 10px;"></div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<h5>{{$flight->dpt_airport_id}} METAR</h5>
|
||||||
|
{{ Widget::checkWx([
|
||||||
|
'icao' => $flight->dpt_airport_id,
|
||||||
|
]) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<h5>{{$flight->arr_airport_id}} METAR</h5>
|
||||||
|
{{ Widget::checkWx([
|
||||||
|
'icao' => $flight->arr_airport_id,
|
||||||
|
]) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@include('flights.map')
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -32,10 +32,12 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-5">
|
<div class="col-sm-5">
|
||||||
<span class="title">DEP </span>
|
<span class="title">DEP </span>
|
||||||
{{ $flight->dpt_airport->icao }}@if($flight->dpt_time), {{ $flight->dpt_time }}@endif
|
<a href="{{route('frontend.airports.show', ['id'=>$flight->dpt_airport_id])}}">
|
||||||
|
{{ $flight->dpt_airport->icao }}</a>@if($flight->dpt_time), {{ $flight->dpt_time }}@endif
|
||||||
<br />
|
<br />
|
||||||
<span class="title">ARR </span>
|
<span class="title">ARR </span>
|
||||||
{{ $flight->arr_airport->icao }}@if($flight->arr_time), {{ $flight->arr_time }}@endif
|
<a href="{{route('frontend.airports.show', ['id'=>$flight->arr_airport_id])}}">
|
||||||
|
{{ $flight->arr_airport->icao }}</a>@if($flight->arr_time), {{ $flight->arr_time }}@endif
|
||||||
<br />
|
<br />
|
||||||
@if($flight->distance)
|
@if($flight->distance)
|
||||||
<span class="title">DISTANCE </span>
|
<span class="title">DISTANCE </span>
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
<div class="card border-blue-bottom">
|
<div class="card border-blue-bottom">
|
||||||
<div class="card-block" style="min-height: 0px">
|
<div class="card-block" style="min-height: 0px">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-2 text-center">
|
<div class="col-12">
|
||||||
<h5>
|
<h5>
|
||||||
<a class="text-c" href="{{ route('frontend.pireps.show', [$pirep->id]) }}">
|
<a class="text-c" href="{{ route('frontend.pireps.show', [$pirep->id]) }}">
|
||||||
{{ $pirep->ident }}
|
{{ $pirep->ident }}
|
||||||
</a>
|
</a>
|
||||||
|
-
|
||||||
|
<a href="{{route('frontend.airports.show', ['id' => $pirep->dpt_airport_id])}}">
|
||||||
|
{{ $pirep->dpt_airport_id }}</a>
|
||||||
|
|
||||||
|
<span class="description"> to </span>
|
||||||
|
|
||||||
|
<a href="{{route('frontend.airports.show', ['id' => $pirep->arr_airport_id])}}">
|
||||||
|
{{ $pirep->arr_airport_id }}</a>
|
||||||
</h5>
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 text-center">
|
||||||
<div>
|
<div>
|
||||||
@if($pirep->state === PirepState::PENDING)
|
@if($pirep->state === PirepState::PENDING)
|
||||||
<div class="badge badge-warning">
|
<div class="badge badge-warning">
|
||||||
@@ -24,14 +34,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr>
|
|
||||||
<td width="20%" nowrap><span class="title">DEP </span></td>
|
|
||||||
<td>{{ $pirep->dpt_airport_id }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td nowrap><span class="title">ARR </span></td>
|
|
||||||
<td>{{ $pirep->arr_airport_id }} </td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td nowrap><span class="title">Flight Time </span></td>
|
<td nowrap><span class="title">Flight Time </span></td>
|
||||||
<td>{{ Utils::minutesToTimeString($pirep->flight_time) }}</td>
|
<td>{{ Utils::minutesToTimeString($pirep->flight_time) }}</td>
|
||||||
|
|||||||
@@ -35,9 +35,11 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Departure/Arrival</td>
|
<td>Departure/Arrival</td>
|
||||||
<td>
|
<td>
|
||||||
{{ $pirep->dpt_airport->icao }} - {{ $pirep->dpt_airport->name }}
|
<a href="{{route('frontend.airports.show', ['id' => $pirep->dpt_airport_id])}}">
|
||||||
|
{{ $pirep->dpt_airport->full_name }}</a>
|
||||||
<span class="description">to</span>
|
<span class="description">to</span>
|
||||||
{{ $pirep->arr_airport->icao }} - {{ $pirep->arr_airport->name }}
|
<a href="{{route('frontend.airports.show', ['id' => $pirep->arr_airport_id])}}">
|
||||||
|
{{ $pirep->arr_airport->full_name }}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
phpvms.map.render_airspace_map({
|
phpvms.map.render_airspace_map({
|
||||||
lat: "{{$config['lat']}}",
|
lat: "{{$config['lat']}}",
|
||||||
lon: "{{$config['lon']}}",
|
lon: "{{$config['lon']}}",
|
||||||
|
metar_wms: {!! json_encode(config('map.metar_wms')) !!},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
64
resources/views/layouts/default/widgets/check_wx.blade.php
Normal file
64
resources/views/layouts/default/widgets/check_wx.blade.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
@if(!$data)
|
||||||
|
<p>METAR/TAF data could not be retrieved</p>
|
||||||
|
@else
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div style="line-height:1.5em;min-height: 3em;">
|
||||||
|
{{$data->raw_text}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">Updated: {{$data->observed}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Conditions</td>
|
||||||
|
<td>
|
||||||
|
{{$data->flight_category}},
|
||||||
|
@if($unit_temp === 'f')
|
||||||
|
{{$data->temperature->fahrenheit}}°F
|
||||||
|
@else
|
||||||
|
{{$data->temperature->celsius}}°C
|
||||||
|
@endif
|
||||||
|
, visibility
|
||||||
|
@if($unit_dist === 'km')
|
||||||
|
{{intval(str_replace(',', '', $data->visibility->meters)) / 1000}}
|
||||||
|
@else
|
||||||
|
{{$data->visibility->miles}}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{$data->humidity_percent}}% humidity
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Barometer</td>
|
||||||
|
<td>{{ $data->barometer->hg }}hg/{{ $data->barometer->mb }}mb</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Clouds</td>
|
||||||
|
<td>
|
||||||
|
@foreach($data->clouds as $cloud)
|
||||||
|
<p>
|
||||||
|
{{$cloud->text}} @
|
||||||
|
@if($unit_alt === 'ft')
|
||||||
|
{{$cloud->base_feet_agl}}
|
||||||
|
@else
|
||||||
|
{{$cloud->base_meters_agl}}
|
||||||
|
@endif
|
||||||
|
{{$unit_alt}}
|
||||||
|
</p>
|
||||||
|
@endforeach
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Wind</td>
|
||||||
|
<td>
|
||||||
|
{{$data->wind->speed_kts}}kts @ {{$data->wind->degrees}},
|
||||||
|
@if(property_exists($data->wind, 'gusts_kts'))
|
||||||
|
gusts to {{$data->wind->gusts_kts}}
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
@endif
|
||||||
@@ -12,6 +12,7 @@ mix.copy('node_modules/bootstrap3/fonts/*.woff2', 'public/assets/admin/fonts/');
|
|||||||
mix.copy('node_modules/x-editable/dist/bootstrap3-editable/img/*', 'public/assets/admin/img/');
|
mix.copy('node_modules/x-editable/dist/bootstrap3-editable/img/*', 'public/assets/admin/img/');
|
||||||
mix.copy('node_modules/jquery/dist/jquery.js', 'public/assets/global/js/');
|
mix.copy('node_modules/jquery/dist/jquery.js', 'public/assets/global/js/');
|
||||||
mix.copy('node_modules/flag-icon-css/flags/', 'public/assets/global/flags/');
|
mix.copy('node_modules/flag-icon-css/flags/', 'public/assets/global/flags/');
|
||||||
|
mix.copy('node_modules/leaflet/dist/images/', 'public/assets/global/css/images/');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DEFAULT SKIN FRONTEND FILES
|
* DEFAULT SKIN FRONTEND FILES
|
||||||
@@ -89,6 +90,7 @@ mix.styles([
|
|||||||
'node_modules/flag-icon-css/css/flag-icon.css',
|
'node_modules/flag-icon-css/css/flag-icon.css',
|
||||||
], 'public/assets/global/css/vendor.css')
|
], 'public/assets/global/css/vendor.css')
|
||||||
.options({
|
.options({
|
||||||
|
//processCssUrls: true,
|
||||||
compressed: true
|
compressed: true
|
||||||
})
|
})
|
||||||
.sourceMaps();
|
.sourceMaps();
|
||||||
|
|||||||
Reference in New Issue
Block a user