2015-02-22 11:51:58 +00:00
// -*- mode: javascript; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2015-01-07 17:35:32 +00:00
"use strict" ;
2013-05-21 20:28:16 +00:00
// Define our global variables
2016-07-02 11:55:38 +00:00
var OLMap = null ;
var StaticFeatures = new ol . Collection ( ) ;
2016-08-22 21:48:17 +00:00
var SiteCircleFeatures = new ol . Collection ( ) ;
2016-07-02 11:55:38 +00:00
var PlaneIconFeatures = new ol . Collection ( ) ;
var PlaneTrailFeatures = new ol . Collection ( ) ;
2013-05-21 20:28:16 +00:00
var Planes = { } ;
2015-01-06 20:15:25 +00:00
var PlanesOrdered = [ ] ;
2016-08-24 20:28:13 +00:00
var PlaneFilter = { } ;
2013-05-21 20:28:16 +00:00
var SelectedPlane = null ;
2016-08-19 19:43:20 +00:00
var SelectedAllPlanes = false ;
2017-01-18 22:14:53 +00:00
var HighlightedPlane = null ;
2015-01-22 14:17:12 +00:00
var FollowSelected = false ;
2017-01-31 17:07:39 +00:00
var infoBoxOriginalPosition = { } ;
2017-02-22 18:17:18 +00:00
var customAltitudeColors = true ;
2020-12-11 16:42:24 +00:00
var myAdsbStatsSiteUrl = null ;
2013-05-18 21:54:59 +00:00
2021-02-25 05:35:05 +00:00
var ADSB _Enabled = true ;
var UAT _Enabled = false ;
2015-01-07 16:32:58 +00:00
var SpecialSquawks = {
'7500' : { cssClass : 'squawk7500' , markerColor : 'rgb(255, 85, 85)' , text : 'Aircraft Hijacking' } ,
'7600' : { cssClass : 'squawk7600' , markerColor : 'rgb(0, 255, 255)' , text : 'Radio Failure' } ,
'7700' : { cssClass : 'squawk7700' , markerColor : 'rgb(255, 255, 0)' , text : 'General Emergency' }
2015-01-06 20:15:25 +00:00
} ;
2013-05-09 14:59:26 +00:00
2013-05-25 08:56:32 +00:00
// Get current map settings
2020-03-01 17:20:53 +00:00
var CenterLat , CenterLon , ZoomLvl , MapType , SiteCirclesCount , SiteCirclesBaseDistance , SiteCirclesInterval ;
2013-05-25 08:56:32 +00:00
2020-12-08 20:44:14 +00:00
var SkyAwareVersion = "unknown version" ;
2015-01-07 16:32:58 +00:00
var RefreshInterval = 1000 ;
2014-12-10 17:05:22 +00:00
2015-01-07 16:32:58 +00:00
var PlaneRowTemplate = null ;
2015-01-06 20:15:25 +00:00
2015-01-07 16:32:58 +00:00
var TrackedAircraft = 0 ;
2015-01-07 17:35:32 +00:00
var TrackedAircraftPositions = 0 ;
var TrackedHistorySize = 0 ;
var SitePosition = null ;
2015-01-06 20:15:25 +00:00
2015-02-11 00:15:48 +00:00
var LastReceiverTimestamp = 0 ;
2015-01-07 18:43:08 +00:00
var StaleReceiverCount = 0 ;
var FetchPending = null ;
2021-02-25 05:35:05 +00:00
var FetchPending _UAT = null ;
2015-01-07 18:43:08 +00:00
2015-01-13 19:10:55 +00:00
var MessageCountHistory = [ ] ;
2021-02-25 05:35:05 +00:00
var MessageCountHistory _UAT = [ ] ;
2015-02-22 11:51:58 +00:00
var MessageRate = 0 ;
2021-02-25 05:35:05 +00:00
var UatMessageRate = 0 ;
2015-01-13 19:10:55 +00:00
2015-01-11 12:02:25 +00:00
var NBSP = '\u00a0' ;
2017-01-23 20:02:45 +00:00
var layers ;
2020-07-21 16:32:39 +00:00
var layerGroup ;
2017-01-23 20:02:45 +00:00
2021-02-09 04:33:50 +00:00
var ActiveFilterCount = 0 ;
2020-12-14 06:34:40 +00:00
var altitude _slider = null ;
2020-12-14 14:37:16 +00:00
var speed _slider = null ;
2020-12-14 06:34:40 +00:00
2021-02-22 17:37:00 +00:00
var AircraftLabels = false ;
2017-01-26 22:32:45 +00:00
// piaware vs flightfeeder
var isFlightFeeder = false ;
2020-07-21 15:00:32 +00:00
var checkbox _div _map = new Map ( [
[ '#icao_col_checkbox' , '#icao' ] ,
[ '#flag_col_checkbox' , '#flag' ] ,
[ '#ident_col_checkbox' , '#flight' ] ,
[ '#reg_col_checkbox' , '#registration' ] ,
[ '#ac_col_checkbox' , '#aircraft_type' ] ,
[ '#squawk_col_checkbox' , '#squawk' ] ,
[ '#alt_col_checkbox' , '#altitude' ] ,
[ '#speed_col_checkbox' , '#speed' ] ,
[ '#vrate_col_checkbox' , '#vert_rate' ] ,
[ '#distance_col_checkbox' , '#distance' ] ,
[ '#heading_col_checkbox' , '#track' ] ,
[ '#messages_col_checkbox' , '#msgs' ] ,
[ '#msg_age_col_checkbox' , '#seen' ] ,
[ '#rssi_col_checkbox' , '#rssi' ] ,
[ '#lat_col_checkbox' , '#lat' ] ,
[ '#lon_col_checkbox' , '#lon' ] ,
[ '#datasource_col_checkbox' , '#data_source' ] ,
[ '#airframes_col_checkbox' , '#airframes_mode_s_link' ] ,
[ '#fa_modes_link_checkbox' , '#flightaware_mode_s_link' ] ,
[ '#fa_photo_link_checkbox' , '#flightaware_photo_link' ] ,
] ) ;
2021-02-10 01:06:35 +00:00
var DefaultMinMaxFilters = {
'nautical' : { min : 0 , maxSpeed : 1000 , maxAltitude : 65000 } , // kt, ft
'metric' : { min : 0 , maxSpeed : 1000 , maxAltitude : 20000 } , // km/h, m
'imperial' : { min : 0 , maxSpeed : 600 , maxAltitude : 65000 } // mph, ft
} ;
2021-02-25 05:35:05 +00:00
// Update Planes with data in aircraft json
// receiver_source will specify where the aircraft.json originated from (dump1090-fa or skyaware978)
function processReceiverUpdate ( data , receiver _source ) {
// Loop through all the planes in the data packet
2015-01-15 21:01:14 +00:00
var now = data . now ;
var acs = data . aircraft ;
2021-02-25 05:35:05 +00:00
if ( receiver _source === "skyaware978" ) {
// Detect stats reset (i.e. if MessageCountHistory array is > 0 and the latest value > the "messages" field in the data packet)
if ( MessageCountHistory _UAT . length > 0 && MessageCountHistory _UAT [ MessageCountHistory _UAT . length - 1 ] . messages > data . messages ) {
MessageCountHistory _UAT = [ { 'time' : MessageCountHistory _UAT [ MessageCountHistory _UAT . length - 1 ] . time ,
'messages' : 0 } ] ;
}
2015-01-15 21:01:14 +00:00
2021-02-25 05:35:05 +00:00
// Maintain a 30 second rollinng history of message counts
MessageCountHistory _UAT . push ( { 'time' : now , 'messages' : data . messages } ) ;
// .. and clean up any old values
if ( ( now - MessageCountHistory _UAT [ 0 ] . time ) > 30 )
MessageCountHistory _UAT . shift ( ) ;
} else {
// Detect stats reset (i.e. if MessageCountHistory array is > 0 and the latest value > the "messages" field in the data packet)
if ( MessageCountHistory . length > 0 && MessageCountHistory [ MessageCountHistory . length - 1 ] . messages > data . messages ) {
MessageCountHistory = [ { 'time' : MessageCountHistory [ MessageCountHistory . length - 1 ] . time ,
'messages' : 0 } ] ;
}
// Maintain a 30 second rollinng history of message counts
MessageCountHistory . push ( { 'time' : now , 'messages' : data . messages } ) ;
// .. and clean up any old values
if ( ( now - MessageCountHistory [ 0 ] . time ) > 30 )
MessageCountHistory . shift ( ) ;
}
2015-01-15 21:01:14 +00:00
2020-12-14 16:39:34 +00:00
for ( var j = 0 ; j < acs . length ; j ++ ) {
2015-01-15 21:01:14 +00:00
var ac = acs [ j ] ;
var hex = ac . hex ;
2016-09-07 19:20:42 +00:00
var squawk = ac . squawk ;
2015-01-15 21:01:14 +00:00
var plane = null ;
2020-12-14 16:39:34 +00:00
// Do we already have this plane object in Planes?
// If not make it.
2015-01-15 21:01:14 +00:00
2020-12-14 16:39:34 +00:00
if ( Planes [ hex ] ) {
plane = Planes [ hex ] ;
} else {
plane = new PlaneObject ( hex ) ;
2016-08-24 20:28:13 +00:00
plane . filter = PlaneFilter ;
2015-01-15 21:01:14 +00:00
plane . tr = PlaneRowTemplate . cloneNode ( true ) ;
2015-08-22 00:38:38 +00:00
2015-01-22 13:21:47 +00:00
if ( hex [ 0 ] === '~' ) {
// Non-ICAO address
plane . tr . cells [ 0 ] . textContent = hex . substring ( 1 ) ;
2015-01-22 22:19:17 +00:00
$ ( plane . tr ) . css ( 'font-style' , 'italic' ) ;
2015-08-30 16:16:40 +00:00
} else {
plane . tr . cells [ 0 ] . textContent = hex ;
2015-09-01 11:19:23 +00:00
}
// set flag image if available
if ( ShowFlags && plane . icaorange . flag _image !== null ) {
$ ( 'img' , plane . tr . cells [ 1 ] ) . attr ( 'src' , FlagPath + plane . icaorange . flag _image ) ;
$ ( 'img' , plane . tr . cells [ 1 ] ) . attr ( 'title' , plane . icaorange . country ) ;
} else {
$ ( 'img' , plane . tr . cells [ 1 ] ) . css ( 'display' , 'none' ) ;
2015-01-22 13:21:47 +00:00
}
2016-10-25 20:09:27 +00:00
plane . tr . addEventListener ( 'click' , function ( h , evt ) {
if ( evt . srcElement instanceof HTMLAnchorElement ) {
evt . stopPropagation ( ) ;
return ;
}
if ( ! $ ( "#map_container" ) . is ( ":visible" ) ) {
showMap ( ) ;
}
selectPlaneByHex ( h , false ) ;
adjustSelectedInfoBlockPosition ( ) ;
evt . preventDefault ( ) ;
} . bind ( undefined , hex ) ) ;
plane . tr . addEventListener ( 'dblclick' , function ( h , evt ) {
if ( ! $ ( "#map_container" ) . is ( ":visible" ) ) {
showMap ( ) ;
}
selectPlaneByHex ( h , true ) ;
adjustSelectedInfoBlockPosition ( ) ;
evt . preventDefault ( ) ;
} . bind ( undefined , hex ) ) ;
Planes [ hex ] = plane ;
2015-01-15 21:01:14 +00:00
PlanesOrdered . push ( plane ) ;
2020-12-14 16:39:34 +00:00
}
2015-01-15 21:01:14 +00:00
2020-12-14 16:39:34 +00:00
// Call the function update
2021-02-25 05:35:05 +00:00
plane . updateData ( now , ac , receiver _source ) ;
2020-12-14 16:39:34 +00:00
}
2015-01-15 21:01:14 +00:00
}
2013-05-21 20:28:16 +00:00
function fetchData ( ) {
2021-03-08 15:28:39 +00:00
if ( ADSB _Enabled ) {
if ( FetchPending !== null && FetchPending . state ( ) == 'pending' ) {
// don't double up on fetches, let the last one resolve
return ;
}
2015-01-07 18:43:08 +00:00
2021-03-08 15:28:39 +00:00
FetchPending = $ . ajax ( { url : 'data/aircraft.json' ,
timeout : 5000 ,
cache : false ,
dataType : 'json' } ) ;
FetchPending . done ( function ( data ) {
process _aircraft _json ( data , 'dump1090-fa' ) ;
} ) ;
2021-02-25 05:35:05 +00:00
2021-03-08 15:28:39 +00:00
FetchPending . fail ( function ( jqxhr , status , error ) {
$ ( "#update_error_detail" ) . text ( "AJAX call failed (" + status + ( error ? ( ": " + error ) : "" ) + "). Maybe dump1090 is no longer running?" ) ;
$ ( "#update_error" ) . css ( 'display' , 'block' ) ;
} ) ;
}
2021-02-25 05:35:05 +00:00
// Fetch UAT if enabled
if ( UAT _Enabled ) {
if ( FetchPending _UAT !== null && FetchPending _UAT . state ( ) == 'pending' ) {
// don't double up on fetches, let the last one resolve
return ;
}
FetchPending _UAT = $ . ajax ( { url : 'data-978/aircraft.json' ,
timeout : 5000 ,
cache : false ,
dataType : 'json' } ) ;
FetchPending _UAT . done ( function ( data ) {
// Process UAT aircraft.json here
process _aircraft _json ( data , 'skyaware978' ) ;
} ) ;
FetchPending _UAT . fail ( function ( jqxhr , status , error ) {
$ ( "#uat_update_error_detail" ) . text ( "AJAX call failed (" + status + ( error ? ( ": " + error ) : "" ) + "). Maybe skyaware978 is no longer running?" ) ;
$ ( "#uat_update_error" ) . css ( 'display' , 'block' ) ;
} ) ;
}
}
// Process an aircraft.json and update Planes.
// receiver_source will specify where the aircraft.json originated from (dump1090-fa or skyaware978)
function process _aircraft _json ( data , receiver _source ) {
var now = data . now ;
processReceiverUpdate ( data , receiver _source ) ;
// update timestamps, visibility, history track for all planes - not only those updated
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
var plane = PlanesOrdered [ i ] ;
plane . updateTick ( now , LastReceiverTimestamp ) ;
}
selectNewPlanes ( ) ;
refreshTableInfo ( ) ;
refreshSelected ( ) ;
refreshHighlighted ( ) ;
// Check for stale receiver data
if ( LastReceiverTimestamp === now ) {
StaleReceiverCount ++ ;
if ( StaleReceiverCount > 5 ) {
$ ( "#update_error_detail" ) . text ( "The data from dump1090 hasn't been updated in a while. Maybe dump1090 is no longer running?" ) ;
$ ( "#update_error" ) . css ( 'display' , 'block' ) ;
}
} else {
StaleReceiverCount = 0 ;
LastReceiverTimestamp = now ;
$ ( "#update_error" ) . css ( 'display' , 'none' ) ;
}
2013-05-09 14:59:26 +00:00
}
2015-01-15 21:01:14 +00:00
var PositionHistorySize = 0 ;
2021-02-25 05:35:05 +00:00
var UatPositionHistorySize = 0 ;
2013-05-21 20:28:16 +00:00
function initialize ( ) {
2015-01-22 14:33:42 +00:00
// Set page basics
2015-02-22 11:51:58 +00:00
document . title = PageName ;
2017-01-26 22:32:45 +00:00
flightFeederCheck ( ) ;
2015-01-22 14:33:42 +00:00
2020-12-11 16:42:24 +00:00
setStatsLink ( ) ;
2015-01-06 20:15:25 +00:00
PlaneRowTemplate = document . getElementById ( "plane_row_template" ) ;
2017-01-19 22:21:55 +00:00
refreshClock ( ) ;
2015-01-15 22:23:15 +00:00
$ ( "#loader" ) . removeClass ( "hidden" ) ;
2018-05-09 14:20:45 +00:00
2018-05-09 14:33:26 +00:00
if ( ExtendedData || window . location . hash == '#extended' ) {
2018-05-09 14:20:45 +00:00
$ ( "#extendedData" ) . removeClass ( "hidden" ) ;
}
2016-08-18 20:48:57 +00:00
// Set up map/sidebar splitter
2018-07-30 22:51:18 +00:00
$ ( "#sidebar_container" ) . resizable ( {
handles : {
w : '#splitter'
} ,
minWidth : 350
} ) ;
// Set up datablock splitter
$ ( '#selected_infoblock' ) . resizable ( {
handles : {
s : '#splitter-infoblock'
} ,
containment : "#sidebar_container" ,
minHeight : 50
} ) ;
2016-08-18 20:48:57 +00:00
2018-07-31 21:12:03 +00:00
$ ( '#close-button' ) . on ( 'click' , function ( ) {
if ( SelectedPlane !== null ) {
var selectedPlane = Planes [ SelectedPlane ] ;
SelectedPlane = null ;
selectedPlane . selected = null ;
selectedPlane . clearLines ( ) ;
selectedPlane . updateMarker ( ) ;
refreshSelected ( ) ;
refreshHighlighted ( ) ;
$ ( '#selected_infoblock' ) . hide ( ) ;
}
} ) ;
2018-07-30 22:51:18 +00:00
// this is a little hacky, but the best, most consitent way of doing this. change the margin bottom of the table container to the height of the overlay
$ ( '#selected_infoblock' ) . on ( 'resize' , function ( ) {
$ ( '#sidebar_canvas' ) . css ( 'margin-bottom' , $ ( '#selected_infoblock' ) . height ( ) + 'px' ) ;
} ) ;
// look at the window resize to resize the pop-up infoblock so it doesn't float off the bottom or go off the top
$ ( window ) . on ( 'resize' , function ( ) {
var topCalc = ( $ ( window ) . height ( ) - $ ( '#selected_infoblock' ) . height ( ) - 60 ) ;
// check if the top will be less than zero, which will be overlapping/off the screen, and set the top correctly.
if ( topCalc < 0 ) {
topCalc = 0 ;
$ ( '#selected_infoblock' ) . css ( 'height' , ( $ ( window ) . height ( ) - 60 ) + 'px' ) ;
}
$ ( '#selected_infoblock' ) . css ( 'top' , topCalc + 'px' ) ;
} ) ;
2016-08-31 20:45:29 +00:00
2018-07-30 22:51:18 +00:00
// to make the infoblock responsive
$ ( '#sidebar_container' ) . on ( 'resize' , function ( ) {
if ( $ ( '#sidebar_container' ) . width ( ) < 500 ) {
$ ( '#selected_infoblock' ) . addClass ( 'infoblock-container-small' ) ;
} else {
$ ( '#selected_infoblock' ) . removeClass ( 'infoblock-container-small' ) ;
}
} ) ;
2016-08-19 22:57:20 +00:00
// Set up event handlers for buttons
2016-08-18 20:48:57 +00:00
$ ( "#toggle_sidebar_button" ) . click ( toggleSidebarVisibility ) ;
2016-08-19 15:58:48 +00:00
$ ( "#expand_sidebar_button" ) . click ( expandSidebar ) ;
2016-08-19 22:57:20 +00:00
$ ( "#show_map_button" ) . click ( showMap ) ;
2016-08-19 15:58:48 +00:00
2016-08-19 22:57:20 +00:00
// Set initial element visibility
2016-08-19 15:58:48 +00:00
$ ( "#show_map_button" ) . hide ( ) ;
2020-03-02 20:48:45 +00:00
$ ( "#range_ring_column" ) . hide ( ) ;
2016-08-19 22:37:43 +00:00
setColumnVisibility ( ) ;
2016-08-19 15:58:48 +00:00
2016-08-22 21:48:17 +00:00
// Initialize other controls
initializeUnitsSelector ( ) ;
2017-02-22 18:17:18 +00:00
// check if the altitude color values are default to enable the altitude filter
if ( ColorByAlt . air . h . length === 3 && ColorByAlt . air . h [ 0 ] . alt === 2000 && ColorByAlt . air . h [ 0 ] . val === 20 && ColorByAlt . air . h [ 1 ] . alt === 10000 && ColorByAlt . air . h [ 1 ] . val === 140 && ColorByAlt . air . h [ 2 ] . alt === 40000 && ColorByAlt . air . h [ 2 ] . val === 300 ) {
customAltitudeColors = false ;
}
2021-02-10 01:06:35 +00:00
create _filter _sliders ( ) ;
2020-12-14 14:37:16 +00:00
2020-12-02 21:26:45 +00:00
$ ( "#aircraft_type_filter_form" ) . submit ( onFilterByAircraftType ) ;
$ ( "#aircraft_type_filter_reset_button" ) . click ( onResetAircraftTypeFilter ) ;
2017-01-23 20:02:45 +00:00
2020-12-07 16:26:56 +00:00
$ ( "#aircraft_ident_filter_form" ) . submit ( onFilterByAircraftIdent ) ;
$ ( "#aircraft_ident_filter_reset_button" ) . click ( onResetAircraftIdentFilter ) ;
2017-01-23 20:02:45 +00:00
$ ( '#settingsCog' ) . on ( 'click' , function ( ) {
$ ( '#settings_infoblock' ) . toggle ( ) ;
2020-07-21 15:00:32 +00:00
} ) ;
2017-01-30 20:23:23 +00:00
$ ( '#settings_close' ) . on ( 'click' , function ( ) {
$ ( '#settings_infoblock' ) . hide ( ) ;
} ) ;
2017-01-26 19:38:47 +00:00
$ ( '#groundvehicle_filter' ) . on ( 'click' , function ( ) {
filterGroundVehicles ( true ) ;
refreshSelected ( ) ;
refreshHighlighted ( ) ;
refreshTableInfo ( ) ;
} ) ;
$ ( '#blockedmlat_filter' ) . on ( 'click' , function ( ) {
filterBlockedMLAT ( true ) ;
refreshSelected ( ) ;
refreshHighlighted ( ) ;
refreshTableInfo ( ) ;
} ) ;
2017-01-23 20:02:45 +00:00
$ ( '#grouptype_checkbox' ) . on ( 'click' , function ( ) {
2021-02-22 17:02:20 +00:00
toggleGroupByDataType ( true ) ;
} ) ;
$ ( '#aircraft_label_checkbox' ) . on ( 'click' , function ( ) {
toggleAircraftLabels ( true ) ;
} ) ;
2017-01-23 20:02:45 +00:00
2017-02-10 20:41:48 +00:00
$ ( '#altitude_checkbox' ) . on ( 'click' , function ( ) {
toggleAltitudeChart ( true ) ;
} ) ;
2017-01-23 20:02:45 +00:00
$ ( '#selectall_checkbox' ) . on ( 'click' , function ( ) {
2020-02-20 18:48:05 +00:00
toggleAllPlanes ( true ) ;
2017-01-23 20:02:45 +00:00
} )
2020-07-21 15:00:32 +00:00
$ ( '#select_all_column_checkbox' ) . on ( 'click' , function ( ) {
toggleAllColumns ( true ) ;
} )
2020-12-07 19:37:04 +00:00
$ ( '#adsb_datasource_checkbox' ) . on ( 'click' , function ( ) {
toggleADSBAircraft ( true ) ;
2020-12-07 22:18:16 +00:00
refreshDataSourceFilters ( ) ;
2020-12-07 19:37:04 +00:00
} )
2021-02-25 05:35:05 +00:00
$ ( '#uat_datasource_checkbox' ) . on ( 'click' , function ( ) {
toggleUATAircraft ( true ) ;
refreshDataSourceFilters ( ) ;
} )
2020-12-07 19:37:04 +00:00
$ ( '#mlat_datasource_checkbox' ) . on ( 'click' , function ( ) {
toggleMLATAircraft ( true ) ;
2020-12-07 22:18:16 +00:00
refreshDataSourceFilters ( ) ;
2020-12-07 19:37:04 +00:00
} )
$ ( '#other_datasource_checkbox' ) . on ( 'click' , function ( ) {
toggleOtherAircraft ( true ) ;
2020-12-07 22:18:16 +00:00
refreshDataSourceFilters ( ) ;
2020-12-07 19:37:04 +00:00
} )
$ ( '#tisb_datasource_checkbox' ) . on ( 'click' , function ( ) {
toggleTISBAircraft ( true ) ;
2020-12-07 22:18:16 +00:00
refreshDataSourceFilters ( ) ;
2020-12-07 19:37:04 +00:00
} )
2020-12-09 23:34:32 +00:00
$ ( '#column_select_button' ) . on ( 'click' , function ( ) {
2020-12-10 00:55:00 +00:00
this . classList . toggle ( "config_button_active" ) ;
2020-12-09 23:34:32 +00:00
$ ( '#column_select_panel' ) . toggle ( ) ;
} ) ;
$ ( '#filter_button' ) . on ( 'click' , function ( ) {
2020-12-10 00:55:00 +00:00
this . classList . toggle ( "config_button_active" ) ;
2020-12-09 23:34:32 +00:00
$ ( '#filter_panel' ) . toggle ( ) ;
} ) ;
2020-12-11 16:42:24 +00:00
$ ( '#stats_page_button' ) . on ( 'click' , function ( ) {
if ( myAdsbStatsSiteUrl ) {
window . open ( myAdsbStatsSiteUrl ) ;
}
} ) ;
2020-07-21 15:00:32 +00:00
// Event handlers for to column checkboxes
checkbox _div _map . forEach ( function ( checkbox , div ) {
$ ( div ) . on ( 'click' , function ( ) {
toggleColumn ( checkbox , div , true ) ;
} ) ;
} ) ;
2016-08-18 20:48:57 +00:00
// Force map to redraw if sidebar container is resized - use a timer to debounce
var mapResizeTimeout ;
$ ( "#sidebar_container" ) . on ( "resize" , function ( ) {
clearTimeout ( mapResizeTimeout ) ;
2016-08-19 23:45:39 +00:00
mapResizeTimeout = setTimeout ( updateMapSize , 10 ) ;
2016-08-18 20:48:57 +00:00
} ) ;
2020-12-08 17:15:17 +00:00
// Initialize settings from local storage
2017-01-26 19:38:47 +00:00
filterGroundVehicles ( false ) ;
filterBlockedMLAT ( false ) ;
2017-02-10 20:41:48 +00:00
toggleAltitudeChart ( false ) ;
2020-02-20 18:48:05 +00:00
toggleAllPlanes ( false ) ;
toggleGroupByDataType ( false ) ;
2021-02-22 17:02:20 +00:00
toggleAircraftLabels ( false ) ;
2020-07-21 15:00:32 +00:00
toggleAllColumns ( false ) ;
2020-12-07 19:37:04 +00:00
toggleADSBAircraft ( false ) ;
2021-02-25 05:35:05 +00:00
toggleUATAircraft ( false ) ;
2020-12-07 19:37:04 +00:00
toggleMLATAircraft ( false ) ;
toggleOtherAircraft ( false ) ;
toggleTISBAircraft ( false ) ;
2020-12-07 22:18:16 +00:00
refreshDataSourceFilters ( ) ;
2017-01-26 19:38:47 +00:00
2021-02-25 05:35:05 +00:00
// Get 978 receiver metadata if present
$ . ajax ( { url : 'data-978/receiver.json' ,
timeout : 5000 ,
cache : false ,
dataType : 'json' } )
. done ( function ( data ) {
console . log ( 'SkyAware978 enabled' )
UAT _Enabled = true ;
UatPositionHistorySize = data . history ;
} )
. fail ( function ( data ) {
console . warn ( 'Error reading SkyAware978 receiver.json. SkyAware978 may be disabled' )
UAT _Enabled = false ;
} ) ;
2014-12-10 17:05:22 +00:00
// Get receiver metadata, reconfigure using it, then continue
// with initialization
2021-02-25 06:00:43 +00:00
$ . ajax ( { url : 'data/receiver.json' ,
2015-01-17 21:02:17 +00:00
timeout : 5000 ,
cache : false ,
dataType : 'json' } )
2014-12-10 17:05:22 +00:00
. done ( function ( data ) {
2021-02-25 05:35:05 +00:00
console . log ( 'dump1090-fa enabled' ) ;
ADSB _Enabled = true ;
2014-12-10 21:34:05 +00:00
if ( typeof data . lat !== "undefined" ) {
2014-12-10 17:05:22 +00:00
SiteShow = true ;
2014-12-10 21:34:05 +00:00
SiteLat = data . lat ;
SiteLon = data . lon ;
2015-01-07 23:54:54 +00:00
DefaultCenterLat = data . lat ;
DefaultCenterLon = data . lon ;
2014-12-10 17:05:22 +00:00
}
2020-12-08 20:44:14 +00:00
SkyAwareVersion = data . version ;
2014-12-10 17:05:22 +00:00
RefreshInterval = data . refresh ;
2015-01-15 21:01:14 +00:00
PositionHistorySize = data . history ;
} )
2015-01-17 21:02:17 +00:00
2021-02-25 05:35:05 +00:00
. fail ( function ( data ) {
console . warn ( 'Error reading dump1090-fa receiver.json. dump1090-fa may be disabled' ) ;
ADSB _Enabled = false ;
} )
2015-01-15 21:01:14 +00:00
. always ( function ( ) {
initialize _map ( ) ;
start _load _history ( ) ;
} ) ;
}
2021-02-10 01:06:35 +00:00
function create _filter _sliders ( ) {
var maxAltitude = DefaultMinMaxFilters [ DisplayUnits ] . maxAltitude ;
var minAltitude = DefaultMinMaxFilters [ DisplayUnits ] . min ;
var maxSpeed = DefaultMinMaxFilters [ DisplayUnits ] . maxSpeed ;
var minSpeed = DefaultMinMaxFilters [ DisplayUnits ] . min ;
altitude _slider = document . getElementById ( 'altitude_slider' ) ;
noUiSlider . create ( altitude _slider , {
start : [ minAltitude , maxAltitude ] ,
connect : true ,
range : {
'min' : minAltitude ,
'max' : maxAltitude
} ,
step : 25 ,
format : {
to : ( v ) => parseFloat ( v ) . toFixed ( 0 ) ,
from : ( v ) => parseFloat ( v ) . toFixed ( 0 )
}
} ) ;
// Change text to reflect slider values
var minAltitudeInput = document . getElementById ( 'minAltitudeText' ) ,
maxAltitudeInput = document . getElementById ( 'maxAltitudeText' ) ;
altitude _slider . noUiSlider . on ( 'update' , function ( values , handle ) {
if ( handle ) {
maxAltitudeInput . innerHTML = values [ handle ] ;
} else {
minAltitudeInput . innerHTML = values [ handle ] ;
}
} ) ;
// 'Set' event - Whenever a slider is changed to a new value, this event is fired. This function will trigger every time a slider stops changing, including after calls to the .set() method. This event can be considered as the 'end of slide'.
altitude _slider . noUiSlider . on ( 'set' , function ( values , handle ) {
onFilterByAltitude ( ) ;
} ) ;
speed _slider = document . getElementById ( 'speed_slider' ) ;
noUiSlider . create ( speed _slider , {
start : [ minSpeed , maxSpeed ] ,
connect : true ,
range : {
'min' : minSpeed ,
'max' : maxSpeed
} ,
step : 5 ,
format : {
to : ( v ) => parseFloat ( v ) . toFixed ( 0 ) ,
from : ( v ) => parseFloat ( v ) . toFixed ( 0 )
}
} ) ;
// Change text to reflect slider values
var minSpeedInput = document . getElementById ( 'minSpeedText' ) ,
maxSpeedInput = document . getElementById ( 'maxSpeedText' ) ;
speed _slider . noUiSlider . on ( 'update' , function ( values , handle ) {
if ( handle ) {
maxSpeedInput . innerHTML = values [ handle ] ;
} else {
minSpeedInput . innerHTML = values [ handle ] ;
}
} ) ;
// 'Set' event - Whenever a slider is changed to a new value, this event is fired. This function will trigger every time a slider stops changing, including after calls to the .set() method. This event can be considered as the 'end of slide'.
speed _slider . noUiSlider . on ( 'set' , function ( values , handle ) {
onFilterBySpeed ( ) ;
} ) ;
}
function reset _filter _sliders ( ) {
var maxAltitude = DefaultMinMaxFilters [ DisplayUnits ] . maxAltitude ;
var minAltitude = DefaultMinMaxFilters [ DisplayUnits ] . min ;
var maxSpeed = DefaultMinMaxFilters [ DisplayUnits ] . maxSpeed ;
var minSpeed = DefaultMinMaxFilters [ DisplayUnits ] . min ;
altitude _slider . noUiSlider . updateOptions ( {
start : [ minAltitude , maxAltitude ] ,
range : {
'min' : minAltitude ,
'max' : maxAltitude
}
} ) ;
speed _slider . noUiSlider . updateOptions ( {
start : [ minSpeed , maxSpeed ] ,
range : {
'min' : minSpeed ,
'max' : maxSpeed
}
} ) ;
// Update filters
updatePlaneFilter ( ) ;
}
2021-02-25 05:35:05 +00:00
var CurrentHistoryFetch = 0 ;
2018-07-30 22:51:18 +00:00
var PositionHistoryBuffer = [ ] ;
2017-07-29 16:52:24 +00:00
var HistoryItemsReturned = 0 ;
2021-02-25 05:35:05 +00:00
var TotalPositionHistorySize = 0 ;
2015-01-15 21:01:14 +00:00
function start _load _history ( ) {
2021-02-25 05:35:05 +00:00
let url = new URL ( window . location . href ) ;
let params = new URLSearchParams ( url . search ) ;
// Get total number of history.json files to load
TotalPositionHistorySize = PositionHistorySize + UatPositionHistorySize ;
if ( TotalPositionHistorySize > 0 && params . get ( 'nohistory' ) !== 'true' ) {
$ ( "#loader_progress" ) . attr ( 'max' , TotalPositionHistorySize ) ;
console . log ( "Starting to load history (" + TotalPositionHistorySize + " items)" ) ;
// Load dump1090 history.json files
for ( var i = 0 ; i < PositionHistorySize ; i ++ ) {
2021-02-25 06:00:43 +00:00
load _history _item ( i , 'data' ) ;
2021-02-25 05:35:05 +00:00
CurrentHistoryFetch ++ ;
}
// Load skyaware978 history.json files
for ( var i = 0 ; i < UatPositionHistorySize ; i ++ ) {
load _history _item ( i , 'data-978' ) ;
CurrentHistoryFetch ++ ;
}
} else {
// Nothing to load
end _load _history ( ) ;
}
2015-01-15 21:01:14 +00:00
}
2021-02-25 05:35:05 +00:00
// Loads a history json file
function load _history _item ( i , source ) {
var historyfile = 'history_' + i + '.json' ;
console . log ( 'Loading ' + source + ' ' + historyfile ) ;
$ ( "#loader_progress" ) . attr ( 'value' , CurrentHistoryFetch ) ;
var receiver _source = ( source == "data-978" ? "skyaware978" : "dump1090-fa" ) ;
2015-01-15 21:01:14 +00:00
2021-02-25 05:35:05 +00:00
$ . ajax ( { url : source + '/' + historyfile ,
2015-01-15 21:01:14 +00:00
timeout : 5000 ,
cache : false ,
dataType : 'json' } )
. done ( function ( data ) {
2021-02-25 06:00:43 +00:00
// Tag history.json files with the source we fetched from (/data or /data-978)
2021-02-25 05:35:05 +00:00
data [ "source" ] = receiver _source ;
2020-12-14 16:39:34 +00:00
PositionHistoryBuffer . push ( data ) ;
HistoryItemsReturned ++ ;
2021-02-25 05:35:05 +00:00
if ( HistoryItemsReturned == TotalPositionHistorySize ) {
// End load history when all files have been loaded
2020-12-14 16:39:34 +00:00
end _load _history ( ) ;
}
2014-12-10 17:05:22 +00:00
} )
2015-01-15 21:01:14 +00:00
. fail ( function ( jqxhr , status , error ) {
2020-12-14 16:39:34 +00:00
//Doesn't matter if it failed, we'll just be missing a data point
HistoryItemsReturned ++ ;
2021-02-25 05:35:05 +00:00
if ( HistoryItemsReturned == TotalPositionHistorySize ) {
// End load history when all files have been loaded
end _load _history ( ) ;
}
2015-01-15 21:01:14 +00:00
} ) ;
}
function end _load _history ( ) {
$ ( "#loader" ) . addClass ( "hidden" ) ;
console . log ( "Done loading history" ) ;
if ( PositionHistoryBuffer . length > 0 ) {
var now , last = 0 ;
// Sort history by timestamp
console . log ( "Sorting history" ) ;
PositionHistoryBuffer . sort ( function ( x , y ) { return ( x . now - y . now ) ; } ) ;
// Process history
for ( var h = 0 ; h < PositionHistoryBuffer . length ; ++ h ) {
now = PositionHistoryBuffer [ h ] . now ;
2017-07-29 18:18:56 +00:00
console . log ( "Applying history " + ( h + 1 ) + "/" + PositionHistoryBuffer . length + " at: " + now ) ;
2021-02-25 05:35:05 +00:00
processReceiverUpdate ( PositionHistoryBuffer [ h ] , PositionHistoryBuffer [ h ] . source ) ;
2015-01-15 21:01:14 +00:00
2021-02-25 05:35:05 +00:00
// Update track
2015-01-15 21:01:14 +00:00
console . log ( "Updating tracks at: " + now ) ;
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
var plane = PlanesOrdered [ i ] ;
2019-07-27 15:50:41 +00:00
plane . updateTrack ( now , last ) ;
2015-01-15 21:01:14 +00:00
}
last = now ;
}
// Final pass to update all planes to their latest state
console . log ( "Final history cleanup pass" ) ;
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
var plane = PlanesOrdered [ i ] ;
plane . updateTick ( now ) ;
}
2015-02-11 00:15:48 +00:00
LastReceiverTimestamp = last ;
2015-01-15 21:01:14 +00:00
}
PositionHistoryBuffer = null ;
console . log ( "Completing init" ) ;
refreshTableInfo ( ) ;
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2015-01-15 21:01:14 +00:00
reaper ( ) ;
// Setup our timer to poll from the server.
window . setInterval ( fetchData , RefreshInterval ) ;
window . setInterval ( reaper , 60000 ) ;
2015-02-11 00:15:21 +00:00
// And kick off one refresh immediately.
fetchData ( ) ;
2020-08-07 18:47:32 +00:00
// update the display layout from any URL query strings
applyUrlQueryStrings ( ) ;
}
// Function to apply any URL query value to the map before we start
function applyUrlQueryStrings ( ) {
// if asked, toggle featrues at start
let url = new URL ( window . location . href ) ;
let params = new URLSearchParams ( url . search ) ;
// be sure we start with a 'clean' layout, but only if we need it
var allOptions = [
'banner' ,
'altitudeChart' ,
'aircraftTrails' ,
'map' ,
'sidebar' ,
'zoomOut' ,
'zoomIn' ,
'moveNorth' ,
'moveSouth' ,
'moveWest' ,
'moveEast' ,
'displayUnits' ,
'rangeRings' ,
'ringCount' ,
'ringBaseDistance' ,
'ringInterval'
]
var needReset = false ;
for ( var option of allOptions ) {
if ( params . has ( option ) ) {
needReset = true ;
break ;
}
}
if ( needReset ) {
resetMap ( ) ;
}
if ( params . get ( 'banner' ) === 'hide' ) {
hideBanner ( ) ;
}
if ( params . get ( 'altitudeChart' ) === 'hide' ) {
$ ( '#altitude_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
$ ( '#altitude_chart' ) . hide ( ) ;
}
if ( params . get ( 'altitudeChart' ) === 'show' ) {
$ ( '#altitude_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
$ ( '#altitude_chart' ) . show ( ) ;
}
if ( params . get ( 'aircraftTrails' ) === 'show' ) {
selectAllPlanes ( ) ;
}
if ( params . get ( 'aircraftTrails' ) === 'hide' ) {
deselectAllPlanes ( ) ;
}
if ( params . get ( 'map' ) === 'show' ) {
showMap ( ) ;
}
if ( params . get ( 'map' ) === 'hide' ) {
expandSidebar ( ) ;
}
if ( params . get ( 'sidebar' ) === 'show' ) {
$ ( "#sidebar_container" ) . show ( ) ;
updateMapSize ( ) ;
}
if ( params . get ( 'sidebar' ) === 'hide' ) {
$ ( "#sidebar_container" ) . hide ( ) ;
updateMapSize ( ) ;
}
if ( params . get ( 'zoomOut' ) ) {
zoomMap ( params . get ( 'zoomOut' ) , true ) ;
}
if ( params . get ( 'zoomIn' ) ) {
zoomMap ( params . get ( 'zoomIn' ) , false ) ;
}
if ( params . get ( 'moveNorth' ) ) {
moveMap ( params . get ( 'moveNorth' ) , true , false ) ;
}
if ( params . get ( 'moveSouth' ) ) {
moveMap ( params . get ( 'moveSouth' ) , true , true ) ;
}
if ( params . get ( 'moveEast' ) ) {
moveMap ( params . get ( 'moveEast' ) , false , false ) ;
}
if ( params . get ( 'moveWest' ) ) {
moveMap ( params . get ( 'moveWest' ) , false , true ) ;
}
if ( params . get ( 'displayUnits' ) ) {
setDisplayUnits ( params . get ( 'displayUnits' ) ) ;
}
if ( params . get ( 'rangeRings' ) ) {
setRangeRingVisibility ( params . get ( 'rangeRings' ) ) ;
}
if ( params . get ( 'ringCount' ) ) {
setRingCount ( params . get ( 'ringCount' ) ) ;
}
if ( params . get ( 'ringBaseDistance' ) ) {
setRingBaseDistance ( params . get ( 'ringBaseDistance' ) ) ;
}
if ( params . get ( 'ringInterval' ) ) {
setRingInterval ( params . get ( 'ringInterval' ) ) ;
}
2014-12-10 17:05:22 +00:00
}
2016-07-24 15:13:04 +00:00
// Make a LineString with 'points'-number points
// that is a closed circle on the sphere such that the
// great circle distance from 'center' to each point is
// 'radius' meters
function make _geodesic _circle ( center , radius , points ) {
var angularDistance = radius / 6378137.0 ;
var lon1 = center [ 0 ] * Math . PI / 180.0 ;
var lat1 = center [ 1 ] * Math . PI / 180.0 ;
2020-07-21 16:32:39 +00:00
var geom ;
2016-07-24 15:13:04 +00:00
for ( var i = 0 ; i <= points ; ++ i ) {
2020-07-21 16:32:39 +00:00
var bearing = i * 2 * Math . PI / points ;
var lat2 = Math . asin ( Math . sin ( lat1 ) * Math . cos ( angularDistance ) +
Math . cos ( lat1 ) * Math . sin ( angularDistance ) * Math . cos ( bearing ) ) ;
var lon2 = lon1 + Math . atan2 ( Math . sin ( bearing ) * Math . sin ( angularDistance ) * Math . cos ( lat1 ) ,
Math . cos ( angularDistance ) - Math . sin ( lat1 ) * Math . sin ( lat2 ) ) ;
lat2 = lat2 * 180.0 / Math . PI ;
lon2 = lon2 * 180.0 / Math . PI ;
if ( ! geom ) {
geom = new ol . geom . LineString ( [ [ lon2 , lat2 ] ] ) ;
} else {
2016-07-24 15:13:04 +00:00
geom . appendCoordinate ( [ lon2 , lat2 ] ) ;
2020-07-21 16:32:39 +00:00
}
2016-07-24 15:13:04 +00:00
}
return geom ;
}
2014-12-10 17:05:22 +00:00
// Initalizes the map and starts up our timers to call various functions
2015-01-15 21:01:14 +00:00
function initialize _map ( ) {
2015-01-07 23:54:54 +00:00
// Load stored map settings if present
CenterLat = Number ( localStorage [ 'CenterLat' ] ) || DefaultCenterLat ;
CenterLon = Number ( localStorage [ 'CenterLon' ] ) || DefaultCenterLon ;
ZoomLvl = Number ( localStorage [ 'ZoomLvl' ] ) || DefaultZoomLvl ;
2016-07-02 20:12:31 +00:00
MapType = localStorage [ 'MapType' ] ;
2020-02-20 20:16:14 +00:00
var groupByDataTypeBox = localStorage . getItem ( 'groupByDataType' ) ;
2015-01-06 20:15:25 +00:00
2015-01-07 23:54:54 +00:00
// Set SitePosition, initialize sorting
2015-01-06 20:15:25 +00:00
if ( SiteShow && ( typeof SiteLat !== 'undefined' ) && ( typeof SiteLon !== 'undefined' ) ) {
2016-07-02 11:55:38 +00:00
SitePosition = [ SiteLon , SiteLat ] ;
2020-02-20 20:16:14 +00:00
if ( groupByDataTypeBox === 'deselected' ) {
sortByDistance ( ) ;
}
2015-01-06 20:15:25 +00:00
} else {
SitePosition = null ;
2016-09-12 21:06:25 +00:00
PlaneRowTemplate . cells [ 9 ] . style . display = 'none' ; // hide distance column
2015-01-07 01:19:05 +00:00
document . getElementById ( "distance" ) . style . display = 'none' ; // hide distance header
2020-02-20 20:16:14 +00:00
if ( groupByDataTypeBox === 'deselected' ) {
sortByAltitude ( ) ;
}
2015-01-06 20:15:25 +00:00
}
2015-09-01 11:19:23 +00:00
// Maybe hide flag info
if ( ! ShowFlags ) {
PlaneRowTemplate . cells [ 1 ] . style . display = 'none' ; // hide flag column
document . getElementById ( "flag" ) . style . display = 'none' ; // hide flag header
document . getElementById ( "infoblock_country" ) . style . display = 'none' ; // hide country row
}
2016-08-04 20:18:54 +00:00
// Initialize OL3
2015-10-26 12:59:38 +00:00
2017-01-23 20:02:45 +00:00
layers = createBaseLayers ( ) ;
2015-10-26 12:59:38 +00:00
2016-07-02 11:55:38 +00:00
var iconsLayer = new ol . layer . Vector ( {
2016-08-04 20:18:54 +00:00
name : 'ac_positions' ,
type : 'overlay' ,
2016-07-03 12:55:14 +00:00
title : 'Aircraft positions' ,
2016-07-02 17:45:03 +00:00
source : new ol . source . Vector ( {
features : PlaneIconFeatures ,
} )
2016-07-02 11:55:38 +00:00
} ) ;
2016-07-03 12:55:14 +00:00
layers . push ( new ol . layer . Group ( {
title : 'Overlays' ,
layers : [
new ol . layer . Vector ( {
2016-08-04 20:18:54 +00:00
name : 'site_pos' ,
type : 'overlay' ,
2016-07-03 12:55:14 +00:00
title : 'Site position and range rings' ,
source : new ol . source . Vector ( {
features : StaticFeatures ,
} )
} ) ,
new ol . layer . Vector ( {
2016-08-04 20:18:54 +00:00
name : 'ac_trail' ,
type : 'overlay' ,
2016-07-03 12:55:14 +00:00
title : 'Selected aircraft trail' ,
source : new ol . source . Vector ( {
features : PlaneTrailFeatures ,
} )
} ) ,
2016-07-03 13:54:36 +00:00
iconsLayer
2016-07-03 12:55:14 +00:00
]
} ) ) ;
2016-07-02 11:55:38 +00:00
2016-08-04 20:18:54 +00:00
var foundType = false ;
2017-02-03 16:50:37 +00:00
var baseCount = 0 ;
2016-08-04 20:18:54 +00:00
2020-07-21 16:32:39 +00:00
layerGroup = new ol . layer . Group ( {
layers : layers
} )
ol . control . LayerSwitcher . forEachRecursive ( layerGroup , function ( lyr ) {
2016-08-04 20:18:54 +00:00
if ( ! lyr . get ( 'name' ) )
return ;
if ( lyr . get ( 'type' ) === 'base' ) {
2017-02-03 16:50:37 +00:00
baseCount ++ ;
2016-08-04 20:18:54 +00:00
if ( MapType === lyr . get ( 'name' ) ) {
foundType = true ;
lyr . setVisible ( true ) ;
} else {
lyr . setVisible ( false ) ;
}
lyr . on ( 'change:visible' , function ( evt ) {
if ( evt . target . getVisible ( ) ) {
MapType = localStorage [ 'MapType' ] = evt . target . get ( 'name' ) ;
}
} ) ;
} else if ( lyr . get ( 'type' ) === 'overlay' ) {
var visible = localStorage [ 'layer_' + lyr . get ( 'name' ) ] ;
if ( visible != undefined ) {
// javascript, why must you taunt me with gratuitous type problems
lyr . setVisible ( visible === "true" ) ;
}
lyr . on ( 'change:visible' , function ( evt ) {
localStorage [ 'layer_' + evt . target . get ( 'name' ) ] = evt . target . getVisible ( ) ;
} ) ;
}
} )
if ( ! foundType ) {
2020-07-21 16:32:39 +00:00
ol . control . LayerSwitcher . forEachRecursive ( layerGroup , function ( lyr ) {
2016-08-04 20:18:54 +00:00
if ( foundType )
return ;
if ( lyr . get ( 'type' ) === 'base' ) {
lyr . setVisible ( true ) ;
foundType = true ;
}
} ) ;
}
OLMap = new ol . Map ( {
2016-07-02 11:55:38 +00:00
target : 'map_canvas' ,
2016-07-02 20:12:31 +00:00
layers : layers ,
2016-07-02 11:55:38 +00:00
view : new ol . View ( {
center : ol . proj . fromLonLat ( [ CenterLon , CenterLat ] ) ,
zoom : ZoomLvl
2016-07-02 16:09:16 +00:00
} ) ,
controls : [ new ol . control . Zoom ( ) ,
new ol . control . Rotate ( ) ,
2017-01-25 22:33:28 +00:00
new ol . control . Attribution ( { collapsed : true } ) ,
2017-02-03 16:50:37 +00:00
new ol . control . ScaleLine ( { units : DisplayUnits } )
2016-07-02 20:12:31 +00:00
] ,
2016-07-02 17:45:03 +00:00
loadTilesWhileAnimating : true ,
loadTilesWhileInteracting : true
2016-07-02 11:55:38 +00:00
} ) ;
2016-03-31 19:09:12 +00:00
2017-02-03 16:50:37 +00:00
if ( baseCount > 1 ) {
OLMap . addControl ( new ol . control . LayerSwitcher ( ) ) ;
}
2013-05-31 07:04:11 +00:00
// Listeners for newly created Map
2016-07-02 11:55:38 +00:00
OLMap . getView ( ) . on ( 'change:center' , function ( event ) {
var center = ol . proj . toLonLat ( OLMap . getView ( ) . getCenter ( ) , OLMap . getView ( ) . getProjection ( ) ) ;
localStorage [ 'CenterLon' ] = center [ 0 ]
localStorage [ 'CenterLat' ] = center [ 1 ]
2015-01-22 14:17:12 +00:00
if ( FollowSelected ) {
// On manual navigation, disable follow
var selected = Planes [ SelectedPlane ] ;
2018-07-30 22:51:18 +00:00
if ( typeof selected === 'undefined' ||
( Math . abs ( center [ 0 ] - selected . position [ 0 ] ) > 0.0001 &&
Math . abs ( center [ 1 ] - selected . position [ 1 ] ) > 0.0001 ) ) {
2015-01-22 14:17:12 +00:00
FollowSelected = false ;
2015-01-22 21:31:02 +00:00
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2015-01-22 14:17:12 +00:00
}
}
} ) ;
2013-05-31 07:04:11 +00:00
2016-07-02 11:55:38 +00:00
OLMap . getView ( ) . on ( 'change:resolution' , function ( event ) {
2016-09-16 10:03:54 +00:00
ZoomLvl = localStorage [ 'ZoomLvl' ] = OLMap . getView ( ) . getZoom ( ) ;
for ( var plane in Planes ) {
Planes [ plane ] . updateMarker ( false ) ;
} ;
2015-01-22 14:17:12 +00:00
} ) ;
2016-03-31 19:09:12 +00:00
2016-07-02 17:11:05 +00:00
OLMap . on ( [ 'click' , 'dblclick' ] , function ( evt ) {
var hex = evt . map . forEachFeatureAtPixel ( evt . pixel ,
function ( feature , layer ) {
return feature . hex ;
} ,
2020-07-21 16:32:39 +00:00
{
layerFilter : function ( layer ) {
return ( layer === iconsLayer ) ;
} ,
hitTolerance : 5 ,
} ) ;
2016-07-02 17:11:05 +00:00
if ( hex ) {
selectPlaneByHex ( hex , ( evt . type === 'dblclick' ) ) ;
2016-08-31 22:59:24 +00:00
adjustSelectedInfoBlockPosition ( ) ;
2016-07-02 17:11:05 +00:00
evt . stopPropagation ( ) ;
2016-08-30 20:22:34 +00:00
} else {
deselectAllPlanes ( ) ;
2016-07-02 17:11:05 +00:00
evt . stopPropagation ( ) ;
2016-07-02 16:11:33 +00:00
}
2015-10-26 23:03:34 +00:00
} ) ;
2017-01-18 22:14:53 +00:00
// show the hover box
OLMap . on ( 'pointermove' , function ( evt ) {
var hex = evt . map . forEachFeatureAtPixel ( evt . pixel ,
function ( feature , layer ) {
return feature . hex ;
} ,
2020-07-21 16:32:39 +00:00
{
layerFilter : function ( layer ) {
return ( layer === iconsLayer ) ;
} ,
hitTolerance : 5 ,
}
2017-01-18 22:14:53 +00:00
) ;
if ( hex ) {
highlightPlaneByHex ( hex ) ;
} else {
removeHighlight ( ) ;
}
} )
2017-01-23 20:02:45 +00:00
// handle the layer settings pane checkboxes
OLMap . once ( 'postrender' , function ( e ) {
toggleLayer ( '#nexrad_checkbox' , 'nexrad' ) ;
toggleLayer ( '#sitepos_checkbox' , 'site_pos' ) ;
toggleLayer ( '#actrail_checkbox' , 'ac_trail' ) ;
toggleLayer ( '#acpositions_checkbox' , 'ac_positions' ) ;
} ) ;
2013-05-26 20:34:38 +00:00
// Add home marker if requested
2015-01-06 20:15:25 +00:00
if ( SitePosition ) {
2016-07-02 11:55:38 +00:00
var markerStyle = new ol . style . Style ( {
image : new ol . style . Circle ( {
radius : 7 ,
snapToPixel : false ,
fill : new ol . style . Fill ( { color : 'black' } ) ,
stroke : new ol . style . Stroke ( {
color : 'white' , width : 2
} )
} )
} ) ;
var feature = new ol . Feature ( new ol . geom . Point ( ol . proj . fromLonLat ( SitePosition ) ) ) ;
feature . setStyle ( markerStyle ) ;
StaticFeatures . push ( feature ) ;
2020-03-02 20:48:45 +00:00
$ ( '#range_ring_column' ) . show ( ) ;
setRangeRings ( ) ;
$ ( '#range_rings_button' ) . click ( onSetRangeRings ) ;
$ ( "#range_ring_form" ) . validate ( {
errorPlacement : function ( error , element ) {
return true ;
} ,
rules : {
ringCount : {
number : true ,
min : 0
} ,
baseRing : {
number : true ,
min : 0
} ,
ringInterval : {
number : true ,
min : 0
}
}
} ) ;
2015-12-21 17:40:39 +00:00
if ( SiteCircles ) {
2016-08-22 21:48:17 +00:00
createSiteCircleFeatures ( ) ;
2015-12-21 17:40:39 +00:00
}
2013-05-26 20:34:38 +00:00
}
2015-12-21 17:42:05 +00:00
// Add terrain-limit rings. To enable this:
//
// create a panorama for your receiver location on heywhatsthat.com
//
// note the "view" value from the URL at the top of the panorama
// i.e. the XXXX in http://www.heywhatsthat.com/?view=XXXX
//
// fetch a json file from the API for the altitudes you want to see:
//
// wget -O /usr/share/dump1090-mutability/html/upintheair.json \
2015-12-23 10:10:05 +00:00
// 'http://www.heywhatsthat.com/api/upintheair.json?id=XXXX&refraction=0.25&alts=3048,9144'
2015-12-21 17:42:05 +00:00
//
// NB: altitudes are in _meters_, you can specify a list of altitudes
// kick off an ajax request that will add the rings when it's done
var request = $ . ajax ( { url : 'upintheair.json' ,
timeout : 5000 ,
cache : true ,
dataType : 'json' } ) ;
request . done ( function ( data ) {
2016-07-02 11:55:38 +00:00
var ringStyle = new ol . style . Style ( {
fill : null ,
stroke : new ol . style . Stroke ( {
color : '#000000' ,
width : 1
} )
} ) ;
2015-12-21 17:42:05 +00:00
for ( var i = 0 ; i < data . rings . length ; ++ i ) {
2020-10-02 15:52:51 +00:00
var geom = new ol . geom . LineString ( [ ] ) ;
2015-12-21 17:42:05 +00:00
var points = data . rings [ i ] . points ;
2016-07-02 11:55:38 +00:00
if ( points . length > 0 ) {
for ( var j = 0 ; j < points . length ; ++ j ) {
geom . appendCoordinate ( [ points [ j ] [ 1 ] , points [ j ] [ 0 ] ] ) ;
}
geom . appendCoordinate ( [ points [ 0 ] [ 1 ] , points [ 0 ] [ 0 ] ] ) ;
geom . transform ( 'EPSG:4326' , 'EPSG:3857' ) ;
var feature = new ol . Feature ( geom ) ;
feature . setStyle ( ringStyle ) ;
StaticFeatures . push ( feature ) ;
2015-12-21 17:42:05 +00:00
}
}
} ) ;
request . fail ( function ( jqxhr , status , error ) {
// no rings available, do nothing
} ) ;
2013-05-09 14:59:26 +00:00
}
2016-08-22 21:48:17 +00:00
function createSiteCircleFeatures ( ) {
// Clear existing circles first
SiteCircleFeatures . forEach ( function ( circleFeature ) {
StaticFeatures . remove ( circleFeature ) ;
} ) ;
SiteCircleFeatures . clear ( ) ;
2017-01-23 22:27:03 +00:00
var circleStyle = function ( distance ) {
return new ol . style . Style ( {
2016-08-22 21:48:17 +00:00
fill : null ,
stroke : new ol . style . Stroke ( {
color : '#000000' ,
width : 1
2017-01-23 22:27:03 +00:00
} ) ,
text : new ol . style . Text ( {
font : '10px Helvetica Neue, sans-serif' ,
fill : new ol . style . Fill ( { color : '#000' } ) ,
offsetY : - 8 ,
2017-01-25 00:10:06 +00:00
text : format _distance _long ( distance , DisplayUnits , 0 )
2017-01-23 22:27:03 +00:00
} )
} ) ;
} ;
2016-08-22 21:48:17 +00:00
var conversionFactor = 1000.0 ;
if ( DisplayUnits === "nautical" ) {
conversionFactor = 1852.0 ;
} else if ( DisplayUnits === "imperial" ) {
conversionFactor = 1609.0 ;
}
2020-03-01 17:20:53 +00:00
for ( var i = 0 ; i < SiteCirclesCount ; ++ i ) {
var distance = ( SiteCirclesBaseDistance + ( SiteCirclesInterval * i ) ) * conversionFactor ;
2016-08-22 21:48:17 +00:00
var circle = make _geodesic _circle ( SitePosition , distance , 360 ) ;
circle . transform ( 'EPSG:4326' , 'EPSG:3857' ) ;
var feature = new ol . Feature ( circle ) ;
2017-01-23 22:27:03 +00:00
feature . setStyle ( circleStyle ( distance ) ) ;
2016-08-22 21:48:17 +00:00
StaticFeatures . push ( feature ) ;
SiteCircleFeatures . push ( feature ) ;
}
}
2013-05-21 20:28:16 +00:00
// This looks for planes to reap out of the master Planes variable
function reaper ( ) {
2015-01-07 01:19:05 +00:00
//console.log("Reaping started..");
2015-01-06 20:15:25 +00:00
2016-09-07 19:20:42 +00:00
// Look for planes where we have seen no messages for >300 seconds
2015-01-06 20:15:25 +00:00
var newPlanes = [ ] ;
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
var plane = PlanesOrdered [ i ] ;
2015-01-07 01:19:05 +00:00
if ( plane . seen > 300 ) {
2016-09-07 19:20:42 +00:00
// Reap it.
2015-01-07 01:19:05 +00:00
plane . tr . parentNode . removeChild ( plane . tr ) ;
plane . tr = null ;
2016-10-25 20:09:27 +00:00
delete Planes [ plane . icao ] ;
2015-01-07 01:19:05 +00:00
plane . destroy ( ) ;
2016-09-07 19:20:42 +00:00
} else {
2015-01-06 20:15:25 +00:00
// Keep it.
newPlanes . push ( plane ) ;
2016-09-07 19:20:42 +00:00
}
} ;
2015-01-06 20:15:25 +00:00
PlanesOrdered = newPlanes ;
refreshTableInfo ( ) ;
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2015-01-07 17:18:33 +00:00
}
2015-02-20 10:42:29 +00:00
// Page Title update function
function refreshPageTitle ( ) {
2017-01-26 22:32:45 +00:00
if ( ! PlaneCountInTitle && ! MessageRateInTitle ) {
document . title = PageName ;
2015-02-22 11:51:58 +00:00
return ;
2017-01-26 22:32:45 +00:00
}
2015-02-22 11:51:58 +00:00
2020-08-09 05:33:59 +00:00
var aircraftCount = "" ;
var rate = "" ;
2015-02-22 11:51:58 +00:00
if ( PlaneCountInTitle ) {
2020-08-09 05:33:59 +00:00
aircraftCount += TrackedAircraft ;
2015-02-22 11:51:58 +00:00
}
2020-08-08 23:26:57 +00:00
if ( MessageRateInTitle && MessageRate ) {
2020-08-09 05:33:59 +00:00
rate += ' - ' + MessageRate . toFixed ( 1 ) + ' msg/sec' ;
2015-02-22 11:51:58 +00:00
}
2020-08-09 05:33:59 +00:00
document . title = '(' + aircraftCount + ') ' + PageName + rate ;
2015-02-20 10:42:29 +00:00
}
2013-05-21 20:28:16 +00:00
// Refresh the detail window about the plane
function refreshSelected ( ) {
2021-02-25 05:35:05 +00:00
updateMessageRates ( ) ;
refreshPageTitle ( ) ;
2015-02-22 11:51:58 +00:00
var selected = false ;
2021-02-25 05:35:05 +00:00
if ( typeof SelectedPlane !== 'undefined' && SelectedPlane != "ICAO" && SelectedPlane != null ) {
selected = Planes [ SelectedPlane ] ;
2015-01-06 20:15:25 +00:00
}
2016-08-30 20:07:54 +00:00
$ ( '#dump1090_infoblock' ) . css ( 'display' , 'block' ) ;
2020-12-08 20:44:14 +00:00
$ ( '#skyaware_version' ) . text ( 'SkyAware ' + SkyAwareVersion ) ;
2016-08-30 20:07:54 +00:00
$ ( '#dump1090_total_ac' ) . text ( TrackedAircraft ) ;
$ ( '#dump1090_total_ac_positions' ) . text ( TrackedAircraftPositions ) ;
$ ( '#dump1090_total_history' ) . text ( TrackedHistorySize ) ;
2021-02-09 04:33:50 +00:00
$ ( '#active_filter_count' ) . text ( ActiveFilterCount ) ;
2016-08-30 20:07:54 +00:00
2021-03-08 15:28:39 +00:00
if ( ADSB _Enabled ) {
$ ( '#adsb_datasource_checkbox, #adsb_datasource_label' ) . show ( ) ;
$ ( '#adsb_message_rate_row' ) . show ( ) ;
if ( MessageRate !== null ) {
$ ( '#dump1090_message_rate' ) . text ( MessageRate . toFixed ( 1 ) + '/sec' ) ;
}
} else {
$ ( '#adsb_datasource_checkbox, #adsb_datasource_label' ) . hide ( ) ;
$ ( '#adsb_message_rate_row' ) . hide ( ) ;
2021-02-25 05:35:05 +00:00
}
2021-02-25 15:42:16 +00:00
if ( UAT _Enabled ) {
2021-02-25 19:06:16 +00:00
$ ( '#uat_datasource_checkbox, #uat_datasource_label' ) . show ( ) ;
2021-02-25 15:42:16 +00:00
$ ( '#uat_message_rate_row' ) . show ( ) ;
if ( UatMessageRate !== null ) {
$ ( '#uat_message_rate' ) . text ( UatMessageRate . toFixed ( 1 ) + '/sec' ) ;
}
} else {
2021-02-25 19:06:16 +00:00
$ ( '#uat_datasource_checkbox, #uat_datasource_label' ) . hide ( ) ;
2021-02-25 15:42:16 +00:00
$ ( '#uat_message_rate_row' ) . hide ( ) ;
2016-08-30 20:07:54 +00:00
}
setSelectedInfoBlockVisibility ( ) ;
2015-02-22 11:51:58 +00:00
2016-08-30 20:07:54 +00:00
if ( ! selected ) {
2015-01-06 20:15:25 +00:00
return ;
}
2016-08-30 21:38:41 +00:00
2015-01-06 20:15:25 +00:00
if ( selected . flight !== null && selected . flight !== "" ) {
$ ( '#selected_callsign' ) . text ( selected . flight ) ;
2013-05-28 09:15:18 +00:00
} else {
2015-01-22 17:35:20 +00:00
$ ( '#selected_callsign' ) . text ( 'n/a' ) ;
2015-01-06 20:15:25 +00:00
}
2018-07-30 22:51:18 +00:00
$ ( '#selected_flightaware_link' ) . html ( getFlightAwareModeSLink ( selected . icao , selected . flight , "Visit Flight Page" ) ) ;
2015-02-24 21:51:30 +00:00
if ( selected . registration !== null ) {
$ ( '#selected_registration' ) . text ( selected . registration ) ;
} else {
2018-08-15 21:54:43 +00:00
$ ( '#selected_registration' ) . text ( "n/a" ) ;
2015-02-24 21:51:30 +00:00
}
if ( selected . icaotype !== null ) {
$ ( '#selected_icaotype' ) . text ( selected . icaotype ) ;
} else {
2018-08-15 20:41:47 +00:00
$ ( '#selected_icaotype' ) . text ( "n/a" ) ;
2015-02-24 21:51:30 +00:00
}
2017-01-19 20:55:48 +00:00
// Not using this logic for the redesigned info panel at the time, but leaving it in if/when adding it back
// var emerg = document.getElementById('selected_emergency');
// if (selected.squawk in SpecialSquawks) {
// emerg.className = SpecialSquawks[selected.squawk].cssClass;
// emerg.textContent = NBSP + 'Squawking: ' + SpecialSquawks[selected.squawk].text + NBSP ;
// } else {
// emerg.className = 'hidden';
// }
2015-01-06 20:15:25 +00:00
2020-12-08 17:15:17 +00:00
$ ( "#selected_altitude" ) . text ( format _altitude _long ( selected . altitude , selected . vert _rate , DisplayUnits ) ) ;
$ ( '#selected_onground' ) . text ( format _onground ( selected . altitude ) ) ;
2018-08-08 16:37:26 +00:00
2015-01-06 20:15:25 +00:00
if ( selected . squawk === null || selected . squawk === '0000' ) {
$ ( '#selected_squawk' ) . text ( 'n/a' ) ;
} else {
$ ( '#selected_squawk' ) . text ( selected . squawk ) ;
2013-05-28 09:15:18 +00:00
}
2020-12-08 17:15:17 +00:00
$ ( '#selected_speed' ) . text ( format _speed _long ( selected . gs , DisplayUnits ) ) ;
$ ( '#selected_ias' ) . text ( format _speed _long ( selected . ias , DisplayUnits ) ) ;
$ ( '#selected_tas' ) . text ( format _speed _long ( selected . tas , DisplayUnits ) ) ;
$ ( '#selected_vertical_rate' ) . text ( format _vert _rate _long ( selected . baro _rate , DisplayUnits ) ) ;
$ ( '#selected_vertical_rate_geo' ) . text ( format _vert _rate _long ( selected . geom _rate , DisplayUnits ) ) ;
2015-01-22 15:31:35 +00:00
$ ( '#selected_icao' ) . text ( selected . icao . toUpperCase ( ) ) ;
2015-01-23 19:17:07 +00:00
$ ( '#airframes_post_icao' ) . attr ( 'value' , selected . icao ) ;
2020-12-08 17:15:17 +00:00
$ ( '#selected_track' ) . text ( format _track _long ( selected . track ) ) ;
2015-01-06 20:15:25 +00:00
if ( selected . seen <= 1 ) {
$ ( '#selected_seen' ) . text ( 'now' ) ;
} else {
2015-02-10 21:49:37 +00:00
$ ( '#selected_seen' ) . text ( selected . seen . toFixed ( 1 ) + 's' ) ;
2015-01-06 20:15:25 +00:00
}
2020-02-20 22:27:12 +00:00
if ( selected . seen _pos <= 1 ) {
$ ( '#selected_seen_pos' ) . text ( 'now' ) ;
} else {
$ ( '#selected_seen_pos' ) . text ( selected . seen _pos . toFixed ( 1 ) + 's' ) ;
}
2015-09-01 11:19:23 +00:00
$ ( '#selected_country' ) . text ( selected . icaorange . country ) ;
if ( ShowFlags && selected . icaorange . flag _image !== null ) {
$ ( '#selected_flag' ) . removeClass ( 'hidden' ) ;
$ ( '#selected_flag img' ) . attr ( 'src' , FlagPath + selected . icaorange . flag _image ) ;
$ ( '#selected_flag img' ) . attr ( 'title' , selected . icaorange . country ) ;
} else {
$ ( '#selected_flag' ) . addClass ( 'hidden' ) ;
}
2015-08-30 16:16:40 +00:00
2020-12-08 17:15:17 +00:00
if ( selected . position === null ) {
2015-01-06 20:15:25 +00:00
$ ( '#selected_position' ) . text ( 'n/a' ) ;
2015-01-22 14:17:12 +00:00
$ ( '#selected_follow' ) . addClass ( 'hidden' ) ;
2015-01-06 20:15:25 +00:00
} else {
2020-02-20 22:27:12 +00:00
$ ( '#selected_position' ) . text ( format _latlng ( selected . position ) ) ;
$ ( '#position_age' ) . text ( selected . seen _pos . toFixed ( 1 ) + 's' ) ;
2015-01-22 14:17:12 +00:00
$ ( '#selected_follow' ) . removeClass ( 'hidden' ) ;
2015-01-22 21:31:02 +00:00
if ( FollowSelected ) {
$ ( '#selected_follow' ) . css ( 'font-weight' , 'bold' ) ;
2016-07-02 13:44:14 +00:00
OLMap . getView ( ) . setCenter ( ol . proj . fromLonLat ( selected . position ) ) ;
2015-01-22 21:31:02 +00:00
} else {
$ ( '#selected_follow' ) . css ( 'font-weight' , 'normal' ) ;
}
2020-12-08 17:15:17 +00:00
}
2021-02-25 05:35:05 +00:00
var datasource = selected . getDataSource ( ) ;
if ( datasource === "uat" ) {
$ ( '#selected_source' ) . text ( "UAT" ) ;
} else if ( datasource === "adsb_icao" ) {
2020-12-08 17:15:17 +00:00
$ ( '#selected_source' ) . text ( "ADS-B" ) ;
2021-02-25 05:35:05 +00:00
} else if ( datasource === "tisb_trackfile" || datasource === "tisb_icao" || datasource === "tisb_other" ) {
2020-12-08 17:15:17 +00:00
$ ( '#selected_source' ) . text ( "TIS-B" ) ;
2021-02-25 05:35:05 +00:00
} else if ( datasource === "mlat" ) {
2020-12-08 17:15:17 +00:00
$ ( '#selected_source' ) . text ( "MLAT" ) ;
} else {
$ ( '#selected_source' ) . text ( "Other" ) ;
}
$ ( '#selected_category' ) . text ( selected . category ? selected . category : "n/a" ) ;
2016-08-22 21:48:17 +00:00
$ ( '#selected_sitedist' ) . text ( format _distance _long ( selected . sitedist , DisplayUnits ) ) ;
2015-01-22 15:31:35 +00:00
$ ( '#selected_rssi' ) . text ( selected . rssi . toFixed ( 1 ) + ' dBFS' ) ;
2016-08-30 21:38:41 +00:00
$ ( '#selected_message_count' ) . text ( selected . messages ) ;
2020-12-08 17:15:17 +00:00
$ ( '#selected_photo_link' ) . html ( getFlightAwarePhotoLink ( selected . registration ) ) ;
$ ( '#selected_altitude_geom' ) . text ( format _altitude _long ( selected . alt _geom , selected . geom _rate , DisplayUnits ) ) ;
2017-06-15 21:36:23 +00:00
$ ( '#selected_mag_heading' ) . text ( format _track _long ( selected . mag _heading ) ) ;
$ ( '#selected_true_heading' ) . text ( format _track _long ( selected . true _heading ) ) ;
$ ( '#selected_ias' ) . text ( format _speed _long ( selected . ias , DisplayUnits ) ) ;
$ ( '#selected_tas' ) . text ( format _speed _long ( selected . tas , DisplayUnits ) ) ;
2017-06-15 22:42:05 +00:00
if ( selected . mach == null ) {
$ ( '#selected_mach' ) . text ( 'n/a' ) ;
} else {
$ ( '#selected_mach' ) . text ( selected . mach . toFixed ( 3 ) ) ;
}
if ( selected . roll == null ) {
$ ( '#selected_roll' ) . text ( 'n/a' ) ;
} else {
$ ( '#selected_roll' ) . text ( selected . roll . toFixed ( 1 ) ) ;
}
if ( selected . track _rate == null ) {
2018-07-30 22:51:18 +00:00
$ ( '#selected_trackrate' ) . text ( 'n/a' ) ;
2017-06-15 22:42:05 +00:00
} else {
2018-07-30 22:51:18 +00:00
$ ( '#selected_trackrate' ) . text ( selected . track _rate . toFixed ( 2 ) ) ;
2017-06-15 22:42:05 +00:00
}
2017-06-15 21:36:23 +00:00
$ ( '#selected_geom_rate' ) . text ( format _vert _rate _long ( selected . geom _rate , DisplayUnits ) ) ;
2018-03-08 21:41:29 +00:00
if ( selected . nav _qnh == null ) {
$ ( '#selected_nav_qnh' ) . text ( "n/a" ) ;
2017-06-15 21:36:23 +00:00
} else {
2018-03-08 21:41:29 +00:00
$ ( '#selected_nav_qnh' ) . text ( selected . nav _qnh . toFixed ( 1 ) + " hPa" ) ;
2017-06-15 21:36:23 +00:00
}
2018-03-08 21:41:29 +00:00
$ ( '#selected_nav_altitude' ) . text ( format _altitude _long ( selected . nav _altitude , 0 , DisplayUnits ) ) ;
$ ( '#selected_nav_heading' ) . text ( format _track _long ( selected . nav _heading ) ) ;
if ( selected . nav _modes == null ) {
$ ( '#selected_nav_modes' ) . text ( "n/a" ) ;
2017-06-16 09:40:22 +00:00
} else {
2018-03-08 21:41:29 +00:00
$ ( '#selected_nav_modes' ) . text ( selected . nav _modes . join ( ) ) ;
2021-02-25 05:35:05 +00:00
}
if ( selected . nic _baro == null ) {
$ ( '#selected_nic_baro' ) . text ( "n/a" ) ;
} else {
if ( selected . nic _baro == 1 ) {
$ ( '#selected_nic_baro' ) . text ( "cross-checked" ) ;
} else {
$ ( '#selected_nic_baro' ) . text ( "not cross-checked" ) ;
}
}
2018-08-02 18:04:44 +00:00
2021-02-25 05:35:05 +00:00
$ ( '#selected_nac_p' ) . text ( format _nac _p ( selected . nac _p ) ) ;
$ ( '#selected_nac_v' ) . text ( format _nac _v ( selected . nac _v ) ) ;
if ( selected . rc == null ) {
$ ( '#selected_rc' ) . text ( "n/a" ) ;
} else if ( selected . rc == 0 ) {
$ ( '#selected_rc' ) . text ( "unknown" ) ;
} else {
$ ( '#selected_rc' ) . text ( format _distance _short ( selected . rc , DisplayUnits ) ) ;
}
2018-08-02 18:04:44 +00:00
2021-02-25 05:35:05 +00:00
if ( selected . sil == null || selected . sil _type == null ) {
$ ( '#selected_sil' ) . text ( "n/a" ) ;
} else {
var sampleRate = "" ;
var silDesc = "" ;
if ( selected . sil _type == "perhour" ) {
sampleRate = " per flight hour" ;
} else if ( selected . sil _type == "persample" ) {
sampleRate = " per sample" ;
}
switch ( selected . sil ) {
case 0 :
silDesc = "> 1× 10<sup>-3</sup>" ;
break ;
case 1 :
silDesc = "≤ 1× 10<sup>-3</sup>" ;
break ;
case 2 :
silDesc = "≤ 1× 10<sup>-5</sup>" ;
break ;
case 3 :
silDesc = "≤ 1× 10<sup>-7</sup>" ;
break ;
default :
silDesc = "n/a" ;
sampleRate = "" ;
break ;
}
$ ( '#selected_sil' ) . html ( silDesc + sampleRate ) ;
}
2017-06-15 22:42:05 +00:00
if ( selected . version == null ) {
2021-02-25 05:35:05 +00:00
$ ( '#selected_version' ) . text ( 'N/A' ) ;
2017-06-15 22:42:05 +00:00
} else if ( selected . version == 0 ) {
$ ( '#selected_version' ) . text ( 'v0 (DO-260)' ) ;
} else if ( selected . version == 1 ) {
$ ( '#selected_version' ) . text ( 'v1 (DO-260A)' ) ;
} else if ( selected . version == 2 ) {
$ ( '#selected_version' ) . text ( 'v2 (DO-260B)' ) ;
} else {
$ ( '#selected_version' ) . text ( 'v' + selected . version ) ;
}
2018-07-30 22:51:18 +00:00
2021-02-25 05:35:05 +00:00
if ( selected . uat _version == null ) {
$ ( '#selected_uat_version' ) . text ( 'N/A' ) ;
} else if ( selected . uat _version == 0 ) {
$ ( '#selected_uat_version' ) . text ( 'v0 (DO-282)' ) ;
} else if ( selected . uat _version == 1 ) {
$ ( '#selected_uat_version' ) . text ( 'v1 (DO-282A)' ) ;
} else if ( selected . uat _version == 2 ) {
$ ( '#selected_uat_version' ) . text ( 'v2 (DO-282B)' ) ;
} else {
$ ( '#selected_uat_version' ) . text ( 'v' + selected . uat _version ) ;
}
}
// Calculate 1090 and 978 Message rate using the rolling history of Message Counts recorded from processing aircraft.json
function updateMessageRates ( ) {
if ( MessageCountHistory . length > 1 ) {
var message _time _delta = MessageCountHistory [ MessageCountHistory . length - 1 ] . time - MessageCountHistory [ 0 ] . time ;
var message _count _delta = MessageCountHistory [ MessageCountHistory . length - 1 ] . messages - MessageCountHistory [ 0 ] . messages ;
if ( message _time _delta > 0 )
MessageRate = message _count _delta / message _time _delta ;
} else {
MessageRate = null ;
2018-07-30 22:51:18 +00:00
}
2015-01-06 20:15:25 +00:00
2021-02-25 05:35:05 +00:00
if ( MessageCountHistory _UAT . length > 1 ) {
var message _time _delta = MessageCountHistory _UAT [ MessageCountHistory _UAT . length - 1 ] . time - MessageCountHistory _UAT [ 0 ] . time ;
var message _count _delta = MessageCountHistory _UAT [ MessageCountHistory _UAT . length - 1 ] . messages - MessageCountHistory _UAT [ 0 ] . messages ;
if ( message _time _delta > 0 )
UatMessageRate = message _count _delta / message _time _delta ;
} else {
UatMessageRate = null ;
}
}
2017-01-18 22:14:53 +00:00
function refreshHighlighted ( ) {
// this is following nearly identical logic, etc, as the refreshSelected function, but doing less junk for the highlighted pane
var highlighted = false ;
if ( typeof HighlightedPlane !== 'undefined' && HighlightedPlane !== null ) {
highlighted = Planes [ HighlightedPlane ] ;
}
2018-07-30 22:51:18 +00:00
var infoBox = $ ( '#highlighted_infoblock' ) ;
2019-09-04 16:43:13 +00:00
2019-09-03 17:34:00 +00:00
// no highlighted plane or in process of removing plane
if ( ! highlighted || ! highlighted . marker ) {
2019-09-04 16:43:13 +00:00
infoBox . fadeOut ( ) ;
2017-01-18 22:14:53 +00:00
return ;
2018-07-30 22:51:18 +00:00
}
var mapCanvas = $ ( '#map_canvas' ) ;
var markerCoordinates = highlighted . marker . getGeometry ( ) . getCoordinates ( ) ;
2019-12-06 01:06:18 +00:00
var markerPosition = OLMap . getPixelFromCoordinate ( markerCoordinates ) ;
var x = markerPosition [ 0 ] ;
var y = markerPosition [ 1 ] ;
if ( x < 0 || y < 0 || x > mapCanvas . width ( ) || y > mapCanvas . height ( ) ) {
infoBox . fadeOut ( ) ;
return ;
}
x = x + 20 ;
y = y + 60 ;
2019-12-06 01:13:17 +00:00
var w = infoBox . outerWidth ( ) + 20 ;
var h = infoBox . outerHeight ( ) ;
2019-12-06 01:06:18 +00:00
if ( x > mapCanvas . width ( ) - w ) {
x -= w + 20 ;
}
if ( y > mapCanvas . height ( ) - h ) {
y -= h ;
}
2019-12-09 17:32:03 +00:00
if ( infoBox . css ( 'visibility' , 'visible' ) ) {
infoBox . animate ( { left : x , top : y } , 500 ) ;
} else {
2019-12-09 17:55:09 +00:00
infoBox . css ( { left : x , top : y } ) ;
2018-07-30 22:51:18 +00:00
}
2019-12-06 01:06:18 +00:00
infoBox . fadeIn ( 100 ) ;
2018-07-30 22:51:18 +00:00
2017-01-18 22:14:53 +00:00
if ( highlighted . flight !== null && highlighted . flight !== "" ) {
$ ( '#highlighted_callsign' ) . text ( highlighted . flight ) ;
} else {
$ ( '#highlighted_callsign' ) . text ( 'n/a' ) ;
}
if ( highlighted . icaotype !== null ) {
$ ( '#higlighted_icaotype' ) . text ( highlighted . icaotype ) ;
} else {
2018-08-15 16:50:14 +00:00
$ ( '#higlighted_icaotype' ) . text ( "n/a" ) ;
2017-01-18 22:14:53 +00:00
}
2021-02-25 05:35:05 +00:00
var datasource = highlighted . getDataSource ( ) ;
if ( datasource === "uat" ) {
$ ( '#highlighted_source' ) . text ( "UAT" ) ;
} else if ( datasource === "adsb_icao" ) {
2018-08-15 16:21:35 +00:00
$ ( '#highlighted_source' ) . text ( "ADS-B" ) ;
2021-02-25 05:35:05 +00:00
} else if ( datasource === "tisb_trackfile" || datasource === "tisb_icao" || datasource === "tisb_other" ) {
2018-08-15 16:21:35 +00:00
$ ( '#highlighted_source' ) . text ( "TIS-B" ) ;
2021-02-25 05:35:05 +00:00
} else if ( datasource === "mlat" ) {
2018-08-15 16:21:35 +00:00
$ ( '#highlighted_source' ) . text ( "MLAT" ) ;
} else {
$ ( '#highlighted_source' ) . text ( "Other" ) ;
}
if ( highlighted . registration !== null ) {
$ ( '#highlighted_registration' ) . text ( highlighted . registration ) ;
} else {
2018-08-15 21:54:43 +00:00
$ ( '#highlighted_registration' ) . text ( "n/a" ) ;
2018-08-15 16:21:35 +00:00
}
2017-01-18 22:14:53 +00:00
$ ( '#highlighted_speed' ) . text ( format _speed _long ( highlighted . speed , DisplayUnits ) ) ;
$ ( "#highlighted_altitude" ) . text ( format _altitude _long ( highlighted . altitude , highlighted . vert _rate , DisplayUnits ) ) ;
$ ( '#highlighted_icao' ) . text ( highlighted . icao . toUpperCase ( ) ) ;
}
2017-01-19 22:21:55 +00:00
function refreshClock ( ) {
$ ( '#clock_div' ) . text ( new Date ( ) . toLocaleString ( ) ) ;
var c = setTimeout ( refreshClock , 500 ) ;
}
2017-01-18 22:14:53 +00:00
function removeHighlight ( ) {
HighlightedPlane = null ;
refreshHighlighted ( ) ;
}
2015-01-07 17:18:33 +00:00
// Refreshes the larger table of all the planes
2015-01-06 20:15:25 +00:00
function refreshTableInfo ( ) {
2021-02-25 05:35:05 +00:00
var show _squawk _warning = false ;
2017-01-20 17:52:38 +00:00
2021-02-25 05:35:05 +00:00
TrackedAircraft = 0
TrackedAircraftPositions = 0
TrackedHistorySize = 0
2015-01-06 20:15:25 +00:00
2021-02-25 05:35:05 +00:00
$ ( ".altitudeUnit" ) . text ( get _unit _label ( "altitude" , DisplayUnits ) ) ;
$ ( ".speedUnit" ) . text ( get _unit _label ( "speed" , DisplayUnits ) ) ;
$ ( ".distanceUnit" ) . text ( get _unit _label ( "distance" , DisplayUnits ) ) ;
$ ( ".verticalRateUnit" ) . text ( get _unit _label ( "verticalRate" , DisplayUnits ) ) ;
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
var tableplane = PlanesOrdered [ i ] ;
TrackedHistorySize += tableplane . history _size ;
if ( tableplane . seen >= 58 || tableplane . isFiltered ( ) ) {
tableplane . tr . className = "plane_table_row hidden" ;
} else {
TrackedAircraft ++ ;
var classes = "plane_table_row" ;
if ( tableplane . position !== null && tableplane . seen _pos < 60 ) {
++ TrackedAircraftPositions ;
}
var datasource = tableplane . getDataSource ( ) ;
if ( datasource === "uat" ) {
classes += " uat" ;
} else if ( datasource === "adsb_icao" ) {
classes += " vPosition" ;
} else if ( datasource === "tisb_trackfile" || datasource === "tisb_icao" || datasource === "tisb_other" ) {
classes += " tisb" ;
} else if ( datasource === "mlat" ) {
classes += " mlat" ;
} else {
classes += " other" ;
}
if ( tableplane . icao == SelectedPlane )
classes += " selected" ;
if ( tableplane . squawk in SpecialSquawks ) {
classes = classes + " " + SpecialSquawks [ tableplane . squawk ] . cssClass ;
show _squawk _warning = true ;
}
// ICAO doesn't change
if ( tableplane . flight ) {
tableplane . tr . cells [ 2 ] . innerHTML = getFlightAwareModeSLink ( tableplane . icao , tableplane . flight , tableplane . flight ) ;
2021-02-25 15:42:16 +00:00
tableplane . tr . cells [ 2 ] . className = "ident_normal" ;
} else if ( tableplane . registration !== null ) {
// Show registration with special styling if ident is not present
tableplane . tr . cells [ 2 ] . innerHTML = getFlightAwareIdentLink ( tableplane . registration , tableplane . registration ) ;
tableplane . tr . cells [ 2 ] . className = "ident_fallback" ;
2021-02-25 05:35:05 +00:00
} else {
2021-02-25 15:42:16 +00:00
tableplane . tr . cells [ 2 ] . innerHTML = "" ;
tableplane . tr . cells [ 2 ] . className = "" ;
}
2021-02-25 05:35:05 +00:00
tableplane . tr . cells [ 3 ] . textContent = ( tableplane . registration !== null ? tableplane . registration : "" ) ;
tableplane . tr . cells [ 4 ] . textContent = ( tableplane . icaotype !== null ? tableplane . icaotype : "" ) ;
tableplane . tr . cells [ 5 ] . textContent = ( tableplane . squawk !== null ? tableplane . squawk : "" ) ;
tableplane . tr . cells [ 6 ] . innerHTML = format _altitude _brief ( tableplane . altitude , tableplane . vert _rate , DisplayUnits ) ;
tableplane . tr . cells [ 7 ] . textContent = format _speed _brief ( tableplane . gs , DisplayUnits ) ;
tableplane . tr . cells [ 8 ] . textContent = format _vert _rate _brief ( tableplane . vert _rate , DisplayUnits ) ;
tableplane . tr . cells [ 9 ] . textContent = format _distance _brief ( tableplane . sitedist , DisplayUnits ) ;
tableplane . tr . cells [ 10 ] . textContent = format _track _brief ( tableplane . track ) ;
tableplane . tr . cells [ 11 ] . textContent = tableplane . messages ;
tableplane . tr . cells [ 12 ] . textContent = tableplane . seen . toFixed ( 0 ) ;
tableplane . tr . cells [ 13 ] . textContent = ( tableplane . rssi !== null ? tableplane . rssi : "" ) ;
tableplane . tr . cells [ 14 ] . textContent = ( tableplane . position !== null ? tableplane . position [ 1 ] . toFixed ( 4 ) : "" ) ;
tableplane . tr . cells [ 15 ] . textContent = ( tableplane . position !== null ? tableplane . position [ 0 ] . toFixed ( 4 ) : "" ) ;
tableplane . tr . cells [ 16 ] . textContent = format _data _source ( tableplane . getDataSource ( ) ) ;
tableplane . tr . cells [ 17 ] . innerHTML = getAirframesModeSLink ( tableplane . icao ) ;
tableplane . tr . cells [ 18 ] . innerHTML = getFlightAwareModeSLink ( tableplane . icao , tableplane . flight ) ;
tableplane . tr . cells [ 19 ] . innerHTML = getFlightAwarePhotoLink ( tableplane . registration ) ;
tableplane . tr . className = classes ;
}
2017-01-20 17:52:38 +00:00
}
2021-02-25 05:35:05 +00:00
if ( show _squawk _warning ) {
$ ( "#SpecialSquawkWarning" ) . css ( 'display' , 'block' ) ;
2015-01-05 23:20:03 +00:00
} else {
2021-02-25 05:35:05 +00:00
$ ( "#SpecialSquawkWarning" ) . css ( 'display' , 'none' ) ;
2015-01-05 23:20:03 +00:00
}
2015-01-06 20:15:25 +00:00
2021-02-25 05:35:05 +00:00
resortTable ( ) ;
2013-05-18 21:54:59 +00:00
}
2015-01-06 20:15:25 +00:00
//
// ---- table sorting ----
//
2015-01-07 22:16:49 +00:00
function compareAlpha ( xa , ya ) {
2015-01-06 20:15:25 +00:00
if ( xa === ya )
2015-01-07 22:16:49 +00:00
return 0 ;
2015-01-06 20:15:25 +00:00
if ( xa < ya )
return - 1 ;
return 1 ;
}
2015-01-05 23:20:03 +00:00
2015-01-07 22:16:49 +00:00
function compareNumeric ( xf , yf ) {
2015-01-06 20:15:25 +00:00
if ( Math . abs ( xf - yf ) < 1e-9 )
2015-01-07 22:16:49 +00:00
return 0 ;
2015-01-06 20:15:25 +00:00
return xf - yf ;
2013-05-18 21:54:59 +00:00
}
2015-01-17 12:27:13 +00:00
function sortByICAO ( ) { sortBy ( 'icao' , compareAlpha , function ( x ) { return x . icao ; } ) ; }
2020-07-02 15:43:23 +00:00
function sortByFlight ( ) { sortBy ( 'flight' , compareAlpha , function ( x ) { return x . flight ? x . flight : x . registration ; } ) ; }
2016-08-19 22:37:43 +00:00
function sortByRegistration ( ) { sortBy ( 'registration' , compareAlpha , function ( x ) { return x . registration ; } ) ; }
function sortByAircraftType ( ) { sortBy ( 'icaotype' , compareAlpha , function ( x ) { return x . icaotype ; } ) ; }
2015-01-17 12:27:13 +00:00
function sortBySquawk ( ) { sortBy ( 'squawk' , compareAlpha , function ( x ) { return x . squawk ; } ) ; }
function sortByAltitude ( ) { sortBy ( 'altitude' , compareNumeric , function ( x ) { return ( x . altitude == "ground" ? - 1e9 : x . altitude ) ; } ) ; }
2017-06-15 21:41:32 +00:00
function sortBySpeed ( ) { sortBy ( 'speed' , compareNumeric , function ( x ) { return x . gs ; } ) ; }
2016-08-19 22:37:43 +00:00
function sortByVerticalRate ( ) { sortBy ( 'vert_rate' , compareNumeric , function ( x ) { return x . vert _rate ; } ) ; }
2015-01-17 12:27:13 +00:00
function sortByDistance ( ) { sortBy ( 'sitedist' , compareNumeric , function ( x ) { return x . sitedist ; } ) ; }
function sortByTrack ( ) { sortBy ( 'track' , compareNumeric , function ( x ) { return x . track ; } ) ; }
function sortByMsgs ( ) { sortBy ( 'msgs' , compareNumeric , function ( x ) { return x . messages ; } ) ; }
function sortBySeen ( ) { sortBy ( 'seen' , compareNumeric , function ( x ) { return x . seen ; } ) ; }
2015-09-01 11:19:23 +00:00
function sortByCountry ( ) { sortBy ( 'country' , compareAlpha , function ( x ) { return x . icaorange . country ; } ) ; }
2016-08-19 22:37:43 +00:00
function sortByRssi ( ) { sortBy ( 'rssi' , compareNumeric , function ( x ) { return x . rssi } ) ; }
function sortByLatitude ( ) { sortBy ( 'lat' , compareNumeric , function ( x ) { return ( x . position !== null ? x . position [ 1 ] : null ) } ) ; }
function sortByLongitude ( ) { sortBy ( 'lon' , compareNumeric , function ( x ) { return ( x . position !== null ? x . position [ 0 ] : null ) } ) ; }
function sortByDataSource ( ) { sortBy ( 'data_source' , compareAlpha , function ( x ) { return x . getDataSource ( ) } ) ; }
2015-01-06 20:15:25 +00:00
2015-01-17 12:27:13 +00:00
var sortId = '' ;
var sortCompare = null ;
var sortExtract = null ;
var sortAscending = true ;
2015-01-06 20:15:25 +00:00
2015-01-17 12:27:13 +00:00
function sortFunction ( x , y ) {
var xv = x . _sort _value ;
var yv = y . _sort _value ;
2013-05-18 21:54:59 +00:00
2015-01-17 12:27:13 +00:00
// always sort missing values at the end, regardless of
// ascending/descending sort
2015-01-19 23:28:04 +00:00
if ( xv == null && yv == null ) return x . _sort _pos - y . _sort _pos ;
2015-01-17 12:27:13 +00:00
if ( xv == null ) return 1 ;
if ( yv == null ) return - 1 ;
2015-01-06 20:15:25 +00:00
2015-01-17 12:27:13 +00:00
var c = sortAscending ? sortCompare ( xv , yv ) : sortCompare ( yv , xv ) ;
if ( c !== 0 ) return c ;
return x . _sort _pos - y . _sort _pos ;
}
2015-01-06 20:15:25 +00:00
function resortTable ( ) {
2015-01-07 22:16:49 +00:00
// number the existing rows so we can do a stable sort
// regardless of whether sort() is stable or not.
2015-01-17 12:27:13 +00:00
// Also extract the sort comparison value.
2015-01-06 20:15:25 +00:00
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
2015-01-07 22:16:49 +00:00
PlanesOrdered [ i ] . _sort _pos = i ;
2015-01-17 12:27:13 +00:00
PlanesOrdered [ i ] . _sort _value = sortExtract ( PlanesOrdered [ i ] ) ;
2015-01-06 20:15:25 +00:00
}
2015-01-17 12:27:13 +00:00
PlanesOrdered . sort ( sortFunction ) ;
2015-01-05 23:20:03 +00:00
2015-01-06 20:15:25 +00:00
var tbody = document . getElementById ( 'tableinfo' ) . tBodies [ 0 ] ;
for ( var i = 0 ; i < PlanesOrdered . length ; ++ i ) {
tbody . appendChild ( PlanesOrdered [ i ] . tr ) ;
}
}
2013-05-18 21:54:59 +00:00
2015-01-17 12:27:13 +00:00
function sortBy ( id , sc , se ) {
2020-02-20 20:16:14 +00:00
if ( id !== 'data_source' ) {
$ ( '#grouptype_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
localStorage . setItem ( 'groupByDataType' , 'deselected' ) ;
}
2015-01-06 20:15:25 +00:00
if ( id === sortId ) {
sortAscending = ! sortAscending ;
2015-01-07 22:16:49 +00:00
PlanesOrdered . reverse ( ) ; // this correctly flips the order of rows that compare equal
2015-01-06 20:15:25 +00:00
} else {
sortAscending = true ;
}
2013-05-12 12:15:18 +00:00
2015-01-06 20:15:25 +00:00
sortId = id ;
2015-01-17 12:27:13 +00:00
sortCompare = sc ;
sortExtract = se ;
2015-01-06 20:15:25 +00:00
resortTable ( ) ;
2013-05-11 10:15:09 +00:00
}
2015-01-22 21:28:35 +00:00
function selectPlaneByHex ( hex , autofollow ) {
2015-01-06 20:15:25 +00:00
//console.log("select: " + hex);
2013-05-24 02:15:37 +00:00
// If SelectedPlane has something in it, clear out the selected
2016-08-19 19:43:20 +00:00
if ( SelectedAllPlanes ) {
deselectAllPlanes ( ) ;
}
2013-05-22 17:09:12 +00:00
if ( SelectedPlane != null ) {
2015-01-07 17:32:20 +00:00
Planes [ SelectedPlane ] . selected = false ;
2015-01-07 01:19:05 +00:00
Planes [ SelectedPlane ] . clearLines ( ) ;
Planes [ SelectedPlane ] . updateMarker ( ) ;
$ ( Planes [ SelectedPlane ] . tr ) . removeClass ( "selected" ) ;
2018-07-30 22:51:18 +00:00
// scroll the infoblock back to the top for the next plane to be selected
$ ( '.infoblock-container' ) . scrollTop ( 0 ) ;
2013-05-22 17:09:12 +00:00
}
2013-05-22 03:26:40 +00:00
2016-07-02 17:10:37 +00:00
// If we are clicking the same plane, we are deselecting it.
2016-08-19 19:43:20 +00:00
// (unless it was a doubleclick..)
2016-07-02 17:10:37 +00:00
if ( SelectedPlane === hex && ! autofollow ) {
2016-08-19 19:43:20 +00:00
hex = null ;
}
2015-01-07 01:19:05 +00:00
2016-08-19 19:43:20 +00:00
if ( hex !== null ) {
2013-05-24 02:15:37 +00:00
// Assign the new selected
SelectedPlane = hex ;
2015-01-07 17:32:20 +00:00
Planes [ SelectedPlane ] . selected = true ;
2015-01-07 01:19:05 +00:00
Planes [ SelectedPlane ] . updateLines ( ) ;
Planes [ SelectedPlane ] . updateMarker ( ) ;
2016-08-19 19:43:20 +00:00
$ ( Planes [ SelectedPlane ] . tr ) . addClass ( "selected" ) ;
2013-05-25 15:53:56 +00:00
} else {
2013-05-25 20:57:10 +00:00
SelectedPlane = null ;
2013-05-24 02:15:37 +00:00
}
2015-01-06 20:15:25 +00:00
2016-08-19 19:43:20 +00:00
if ( SelectedPlane !== null && autofollow ) {
FollowSelected = true ;
if ( OLMap . getView ( ) . getZoom ( ) < 8 )
OLMap . getView ( ) . setZoom ( 8 ) ;
} else {
FollowSelected = false ;
}
2015-01-22 23:12:41 +00:00
2016-08-19 19:43:20 +00:00
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
}
function highlightPlaneByHex ( hex ) {
if ( hex != null ) {
HighlightedPlane = hex ;
}
2016-08-19 19:43:20 +00:00
}
// loop through the planes and mark them as selected to show the paths for all planes
function selectAllPlanes ( ) {
2017-01-18 22:14:53 +00:00
HighlightedPlane = null ;
2016-08-19 19:43:20 +00:00
// if all planes are already selected, deselect them all
if ( SelectedAllPlanes ) {
deselectAllPlanes ( ) ;
} else {
// If SelectedPlane has something in it, clear out the selected
if ( SelectedPlane != null ) {
Planes [ SelectedPlane ] . selected = false ;
Planes [ SelectedPlane ] . clearLines ( ) ;
Planes [ SelectedPlane ] . updateMarker ( ) ;
$ ( Planes [ SelectedPlane ] . tr ) . removeClass ( "selected" ) ;
}
SelectedPlane = null ;
2016-09-15 11:38:11 +00:00
SelectedAllPlanes = true ;
2016-08-19 19:43:20 +00:00
for ( var key in Planes ) {
2016-08-24 20:28:13 +00:00
if ( Planes [ key ] . visible && ! Planes [ key ] . isFiltered ( ) ) {
2016-08-19 19:43:20 +00:00
Planes [ key ] . selected = true ;
Planes [ key ] . updateLines ( ) ;
Planes [ key ] . updateMarker ( ) ;
}
}
}
2017-01-23 20:02:45 +00:00
$ ( '#selectall_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
2016-08-19 19:43:20 +00:00
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2016-08-19 19:43:20 +00:00
}
// on refreshes, try to find new planes and mark them as selected
function selectNewPlanes ( ) {
if ( SelectedAllPlanes ) {
for ( var key in Planes ) {
2016-08-24 20:28:13 +00:00
if ( ! Planes [ key ] . visible || Planes [ key ] . isFiltered ( ) ) {
2016-08-19 19:43:20 +00:00
Planes [ key ] . selected = false ;
2016-08-19 20:52:48 +00:00
Planes [ key ] . clearLines ( ) ;
2016-08-19 19:43:20 +00:00
Planes [ key ] . updateMarker ( ) ;
} else {
if ( Planes [ key ] . selected !== true ) {
Planes [ key ] . selected = true ;
Planes [ key ] . updateLines ( ) ;
Planes [ key ] . updateMarker ( ) ;
}
}
}
}
}
2020-02-20 18:48:05 +00:00
function toggleGroupByDataType ( switchToggle ) {
if ( typeof localStorage [ 'groupByDataType' ] === 'undefined' ) {
localStorage . setItem ( 'groupByDataType' , 'deselected' ) ;
}
var groupByDataType = localStorage . getItem ( 'groupByDataType' ) ;
if ( switchToggle === true ) {
groupByDataType = ( groupByDataType === 'deselected' ) ? 'selected' : 'deselected' ;
}
if ( groupByDataType === 'deselected' ) {
$ ( '#grouptype_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
} else {
sortByDataSource ( ) ;
$ ( '#grouptype_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
}
localStorage . setItem ( 'groupByDataType' , groupByDataType ) ;
}
2021-02-22 17:02:20 +00:00
function toggleAircraftLabels ( switchToggle ) {
if ( typeof localStorage [ 'showAircraftLabels' ] === 'undefined' ) {
localStorage . setItem ( 'showAircraftLabels' , 'deselected' ) ;
}
var showAircraftLabels = localStorage . getItem ( 'showAircraftLabels' ) ;
if ( switchToggle === true ) {
showAircraftLabels = ( showAircraftLabels === 'deselected' ) ? 'selected' : 'deselected' ;
}
if ( showAircraftLabels === 'deselected' ) {
2021-02-22 17:37:00 +00:00
// hide aircraft labels
AircraftLabels = false ;
2021-02-22 17:02:20 +00:00
$ ( '#aircraft_label_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
} else {
2021-02-22 17:37:00 +00:00
// show aicraft labels
AircraftLabels = true ;
2021-02-22 17:02:20 +00:00
$ ( '#aircraft_label_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
}
2021-02-22 17:37:00 +00:00
localStorage . setItem ( 'showAircraftLabels' , showAircraftLabels ) ;
2021-02-22 17:02:20 +00:00
}
2020-02-20 18:48:05 +00:00
function toggleAllPlanes ( switchToggle ) {
if ( typeof localStorage [ 'allPlanesSelection' ] === 'undefined' ) {
localStorage . setItem ( 'allPlanesSelection' , 'deselected' ) ;
}
var allPlanesSelection = localStorage . getItem ( 'allPlanesSelection' ) ;
if ( switchToggle === true ) {
allPlanesSelection = ( allPlanesSelection === 'deselected' ) ? 'selected' : 'deselected' ;
}
if ( allPlanesSelection === 'deselected' ) {
deselectAllPlanes ( ) ;
} else {
selectAllPlanes ( ) ;
}
localStorage . setItem ( 'allPlanesSelection' , allPlanesSelection ) ;
}
2016-08-19 19:43:20 +00:00
// deselect all the planes
function deselectAllPlanes ( ) {
for ( var key in Planes ) {
Planes [ key ] . selected = false ;
Planes [ key ] . clearLines ( ) ;
Planes [ key ] . updateMarker ( ) ;
$ ( Planes [ key ] . tr ) . removeClass ( "selected" ) ;
}
2017-01-23 20:02:45 +00:00
$ ( '#selectall_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
2016-08-19 19:43:20 +00:00
SelectedPlane = null ;
SelectedAllPlanes = false ;
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2015-01-22 14:17:12 +00:00
}
function toggleFollowSelected ( ) {
FollowSelected = ! FollowSelected ;
2016-07-02 13:44:14 +00:00
if ( FollowSelected && OLMap . getView ( ) . getZoom ( ) < 8 )
OLMap . getView ( ) . setZoom ( 8 ) ;
2015-01-22 23:12:41 +00:00
refreshSelected ( ) ;
2013-05-09 14:59:26 +00:00
}
2013-05-30 17:32:36 +00:00
function resetMap ( ) {
2015-01-07 23:54:54 +00:00
// Reset localStorage values and map settings
localStorage [ 'CenterLat' ] = CenterLat = DefaultCenterLat ;
localStorage [ 'CenterLon' ] = CenterLon = DefaultCenterLon ;
localStorage [ 'ZoomLvl' ] = ZoomLvl = DefaultZoomLvl ;
2020-03-02 19:19:57 +00:00
// Reset to default range rings
2020-03-01 17:20:53 +00:00
localStorage [ 'SiteCirclesCount' ] = SiteCirclesCount = DefaultSiteCirclesCount ;
localStorage [ 'SiteCirclesBaseDistance' ] = SiteCirclesBaseDistance = DefaultSiteCirclesBaseDistance ;
localStorage [ 'SiteCirclesInterval' ] = SiteCirclesInterval = DefaultSiteCirclesInterval ;
2020-03-02 19:19:57 +00:00
setRangeRings ( ) ;
createSiteCircleFeatures ( ) ;
2015-01-07 23:54:54 +00:00
// Set and refresh
2016-07-02 13:44:14 +00:00
OLMap . getView ( ) . setZoom ( ZoomLvl ) ;
OLMap . getView ( ) . setCenter ( ol . proj . fromLonLat ( [ CenterLon , CenterLat ] ) ) ;
2013-05-31 07:29:51 +00:00
2015-01-22 21:35:59 +00:00
selectPlaneByHex ( null , false ) ;
2013-05-30 17:32:36 +00:00
}
2016-08-18 20:48:57 +00:00
function updateMapSize ( ) {
OLMap . updateSize ( ) ;
}
function toggleSidebarVisibility ( e ) {
2020-08-07 18:47:32 +00:00
if ( e ) {
e . preventDefault ( ) ;
}
2016-08-18 20:48:57 +00:00
$ ( "#sidebar_container" ) . toggle ( ) ;
2016-09-16 11:40:06 +00:00
$ ( "#expand_sidebar_control" ) . toggle ( ) ;
2016-08-18 20:48:57 +00:00
$ ( "#toggle_sidebar_button" ) . toggleClass ( "show_sidebar" ) ;
$ ( "#toggle_sidebar_button" ) . toggleClass ( "hide_sidebar" ) ;
updateMapSize ( ) ;
}
2016-08-19 15:58:48 +00:00
function expandSidebar ( e ) {
2020-08-07 18:47:32 +00:00
if ( e ) {
e . preventDefault ( ) ;
}
2016-08-19 15:58:48 +00:00
$ ( "#map_container" ) . hide ( )
2016-09-16 11:40:06 +00:00
$ ( "#toggle_sidebar_control" ) . hide ( ) ;
2016-08-19 15:58:48 +00:00
$ ( "#splitter" ) . hide ( ) ;
2016-08-19 22:57:20 +00:00
$ ( "#sudo_buttons" ) . hide ( ) ;
2016-08-19 15:58:48 +00:00
$ ( "#show_map_button" ) . show ( ) ;
$ ( "#sidebar_container" ) . width ( "100%" ) ;
2016-08-19 22:37:43 +00:00
setColumnVisibility ( ) ;
2016-08-30 20:07:54 +00:00
setSelectedInfoBlockVisibility ( ) ;
2016-08-19 15:58:48 +00:00
updateMapSize ( ) ;
}
function showMap ( ) {
$ ( "#map_container" ) . show ( )
2016-09-16 11:40:06 +00:00
$ ( "#toggle_sidebar_control" ) . show ( ) ;
2016-08-19 15:58:48 +00:00
$ ( "#splitter" ) . show ( ) ;
2016-08-19 22:57:20 +00:00
$ ( "#sudo_buttons" ) . show ( ) ;
2016-08-19 15:58:48 +00:00
$ ( "#show_map_button" ) . hide ( ) ;
2016-09-12 22:20:42 +00:00
$ ( "#sidebar_container" ) . width ( "470px" ) ;
2016-08-19 22:37:43 +00:00
setColumnVisibility ( ) ;
2016-08-30 20:07:54 +00:00
setSelectedInfoBlockVisibility ( ) ;
2016-08-19 15:58:48 +00:00
updateMapSize ( ) ;
}
function showColumn ( table , columnId , visible ) {
var index = $ ( columnId ) . index ( ) ;
if ( index >= 0 ) {
var cells = $ ( table ) . find ( "td:nth-child(" + ( index + 1 ) . toString ( ) + ")" ) ;
if ( visible ) {
cells . show ( ) ;
} else {
cells . hide ( ) ;
}
}
}
2016-08-19 22:37:43 +00:00
function setColumnVisibility ( ) {
var mapIsVisible = $ ( "#map_container" ) . is ( ":visible" ) ;
var infoTable = $ ( "#tableinfo" ) ;
2020-07-21 15:00:32 +00:00
var defaultCheckBoxes = [
'#icao_col_checkbox' ,
'#flag_col_checkbox' ,
'#ident_col_checkbox' ,
'#squawk_col_checkbox' ,
'#alt_col_checkbox' ,
'#speed_col_checkbox' ,
'#distance_col_checkbox' ,
'#heading_col_checkbox' ,
'#messages_col_checkbox' ,
'#msg_age_col_checkbox'
]
// Show default columns if checkboxes have not been set
for ( var i = 0 ; i < defaultCheckBoxes . length ; i ++ ) {
var checkBoxdiv = defaultCheckBoxes [ i ] ;
var columnDiv = checkbox _div _map . get ( checkBoxdiv )
if ( typeof localStorage [ checkBoxdiv ] === 'undefined' ) {
$ ( checkBoxdiv ) . addClass ( 'settingsCheckboxChecked' ) ;
localStorage . setItem ( checkBoxdiv , 'selected' ) ;
showColumn ( infoTable , columnDiv , true ) ;
}
}
// Now check local storage checkbox status
checkbox _div _map . forEach ( function ( div , checkbox ) {
var status = localStorage . getItem ( checkbox ) ;
if ( status === 'selected' ) {
$ ( checkbox ) . addClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , true ) ;
} else {
$ ( checkbox ) . removeClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , false ) ;
}
} ) ;
2016-08-19 22:37:43 +00:00
}
2016-08-22 21:48:17 +00:00
2016-08-30 20:07:54 +00:00
function setSelectedInfoBlockVisibility ( ) {
var mapIsVisible = $ ( "#map_container" ) . is ( ":visible" ) ;
var planeSelected = ( typeof SelectedPlane !== 'undefined' && SelectedPlane != null && SelectedPlane != "ICAO" ) ;
if ( planeSelected && mapIsVisible ) {
$ ( '#selected_infoblock' ) . show ( ) ;
2018-07-30 22:51:18 +00:00
$ ( '#sidebar_canvas' ) . css ( 'margin-bottom' , $ ( '#selected_infoblock' ) . height ( ) + 'px' ) ;
2016-08-30 20:07:54 +00:00
}
else {
$ ( '#selected_infoblock' ) . hide ( ) ;
2018-07-30 22:51:18 +00:00
$ ( '#sidebar_canvas' ) . css ( 'margin-bottom' , 0 ) ;
2018-07-31 21:12:03 +00:00
}
2016-08-30 20:07:54 +00:00
}
2016-08-31 22:59:24 +00:00
// Reposition selected plane info box if it overlaps plane marker
function adjustSelectedInfoBlockPosition ( ) {
if ( typeof Planes === 'undefined' || typeof SelectedPlane === 'undefined' || Planes === null ) {
return ;
}
var selectedPlane = Planes [ SelectedPlane ] ;
if ( selectedPlane === undefined || selectedPlane === null || selectedPlane . marker === undefined || selectedPlane . marker === null ) {
return ;
}
try {
// Get marker position
var marker = selectedPlane . marker ;
var markerCoordinates = selectedPlane . marker . getGeometry ( ) . getCoordinates ( ) ;
2018-07-30 22:51:18 +00:00
var markerPosition = OLMap . getPixelFromCoordinate ( markerCoordinates ) ;
2016-08-31 22:59:24 +00:00
// Get map size
var mapCanvas = $ ( '#map_canvas' ) ;
var mapExtent = getExtent ( 0 , 0 , mapCanvas . width ( ) , mapCanvas . height ( ) ) ;
// Check for overlap
if ( isPointInsideExtent ( markerPosition [ 0 ] , markerPosition [ 1 ] , infoBoxExtent ) ) {
// Array of possible new positions for info box
var candidatePositions = [ ] ;
2017-02-06 18:23:21 +00:00
candidatePositions . push ( { x : 40 , y : 60 } ) ;
candidatePositions . push ( { x : 40 , y : markerPosition [ 1 ] + 80 } ) ;
2016-08-31 22:59:24 +00:00
// Find new position
for ( var i = 0 ; i < candidatePositions . length ; i ++ ) {
var candidatePosition = candidatePositions [ i ] ;
2016-09-01 21:15:03 +00:00
var candidateExtent = getExtent ( candidatePosition . x , candidatePosition . y , infoBox . outerWidth ( ) , infoBox . outerHeight ( ) ) ;
2016-08-31 22:59:24 +00:00
if ( ! isPointInsideExtent ( markerPosition [ 0 ] , markerPosition [ 1 ] , candidateExtent ) && isPointInsideExtent ( candidatePosition . x , candidatePosition . y , mapExtent ) ) {
// Found a new position that doesn't overlap marker - move box to that position
infoBox . css ( "left" , candidatePosition . x ) ;
infoBox . css ( "top" , candidatePosition . y ) ;
return ;
}
}
}
}
catch ( e ) { }
}
function getExtent ( x , y , width , height ) {
return {
xMin : x ,
yMin : y ,
xMax : x + width - 1 ,
yMax : y + height - 1 ,
} ;
}
function isPointInsideExtent ( x , y , extent ) {
return x >= extent . xMin && x <= extent . xMax && y >= extent . yMin && y <= extent . yMax ;
}
2016-08-22 21:48:17 +00:00
function initializeUnitsSelector ( ) {
// Get display unit preferences from local storage
if ( ! localStorage . getItem ( 'displayUnits' ) ) {
localStorage [ 'displayUnits' ] = "nautical" ;
}
var displayUnits = localStorage [ 'displayUnits' ] ;
DisplayUnits = displayUnits ;
2017-01-30 17:58:29 +00:00
setAltitudeLegend ( displayUnits ) ;
2016-08-22 21:48:17 +00:00
// Initialize drop-down
var unitsSelector = $ ( "#units_selector" ) ;
unitsSelector . val ( displayUnits ) ;
unitsSelector . on ( "change" , onDisplayUnitsChanged ) ;
}
function onDisplayUnitsChanged ( e ) {
2020-08-07 18:47:32 +00:00
if ( e ) {
var displayUnits = e . target . value ;
// Save display units to local storage
localStorage [ 'displayUnits' ] = displayUnits ;
}
DisplayUnits = localStorage [ 'displayUnits' ] ;
setAltitudeLegend ( DisplayUnits ) ;
2017-01-30 17:58:29 +00:00
2016-08-24 20:28:13 +00:00
// Update filters
updatePlaneFilter ( ) ;
2016-08-22 21:48:17 +00:00
// Refresh data
refreshTableInfo ( ) ;
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2016-08-22 21:48:17 +00:00
2021-02-10 01:06:35 +00:00
// Reset filter sliders on Display Units change
reset _filter _sliders ( ) ;
2016-08-22 21:48:17 +00:00
// Redraw range rings
2016-09-12 21:06:25 +00:00
if ( SitePosition !== null && SitePosition !== undefined && SiteCircles ) {
2016-08-22 21:48:17 +00:00
createSiteCircleFeatures ( ) ;
}
// Reset map scale line units
OLMap . getControls ( ) . forEach ( function ( control ) {
if ( control instanceof ol . control . ScaleLine ) {
2020-08-07 18:47:32 +00:00
control . setUnits ( DisplayUnits ) ;
2016-08-22 21:48:17 +00:00
}
} ) ;
}
2016-08-22 23:15:06 +00:00
2017-01-30 17:58:29 +00:00
function setAltitudeLegend ( units ) {
if ( units === 'metric' ) {
$ ( '#altitude_chart_button' ) . addClass ( 'altitudeMeters' ) ;
} else {
$ ( '#altitude_chart_button' ) . removeClass ( 'altitudeMeters' ) ;
}
}
2020-12-14 06:34:40 +00:00
function onFilterByAltitude ( ) {
2016-08-24 20:28:13 +00:00
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
var selectedPlane = Planes [ SelectedPlane ] ;
if ( selectedPlane !== undefined && selectedPlane !== null && selectedPlane . isFiltered ( ) ) {
SelectedPlane = null ;
selectedPlane . selected = false ;
selectedPlane . clearLines ( ) ;
selectedPlane . updateMarker ( ) ;
refreshSelected ( ) ;
2017-01-18 22:14:53 +00:00
refreshHighlighted ( ) ;
2016-08-24 20:28:13 +00:00
}
}
2020-12-14 14:37:16 +00:00
function onFilterBySpeed ( ) {
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
}
2020-12-02 21:26:45 +00:00
function onFilterByAircraftType ( e ) {
e . preventDefault ( ) ;
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
}
function onResetAircraftTypeFilter ( e ) {
$ ( "#aircraft_type_filter" ) . val ( "" ) ;
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
}
2020-12-07 16:26:56 +00:00
function onFilterByAircraftIdent ( e ) {
e . preventDefault ( ) ;
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
}
function onResetAircraftIdentFilter ( e ) {
$ ( "#aircraft_ident_filter" ) . val ( "" ) ;
updatePlaneFilter ( ) ;
refreshTableInfo ( ) ;
}
2017-01-26 19:38:47 +00:00
function filterGroundVehicles ( switchFilter ) {
if ( typeof localStorage [ 'groundVehicleFilter' ] === 'undefined' ) {
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'groundVehicleFilter' , 'not_filtered' ) ;
2017-01-26 19:38:47 +00:00
}
2020-02-20 18:48:05 +00:00
var groundFilter = localStorage . getItem ( 'groundVehicleFilter' ) ;
2017-01-26 19:38:47 +00:00
if ( switchFilter === true ) {
groundFilter = ( groundFilter === 'not_filtered' ) ? 'filtered' : 'not_filtered' ;
}
if ( groundFilter === 'not_filtered' ) {
$ ( '#groundvehicle_filter' ) . addClass ( 'settingsCheckboxChecked' ) ;
} else {
$ ( '#groundvehicle_filter' ) . removeClass ( 'settingsCheckboxChecked' ) ;
}
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'groundVehicleFilter' , groundFilter ) ;
2017-01-26 19:38:47 +00:00
PlaneFilter . groundVehicles = groundFilter ;
}
function filterBlockedMLAT ( switchFilter ) {
if ( typeof localStorage [ 'blockedMLATFilter' ] === 'undefined' ) {
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'blockedMLATFilter' , 'not_filtered' ) ;
2017-01-26 19:38:47 +00:00
}
2020-02-20 18:48:05 +00:00
var blockedMLATFilter = localStorage . getItem ( 'blockedMLATFilter' ) ;
2017-01-26 19:38:47 +00:00
if ( switchFilter === true ) {
blockedMLATFilter = ( blockedMLATFilter === 'not_filtered' ) ? 'filtered' : 'not_filtered' ;
}
if ( blockedMLATFilter === 'not_filtered' ) {
$ ( '#blockedmlat_filter' ) . addClass ( 'settingsCheckboxChecked' ) ;
} else {
$ ( '#blockedmlat_filter' ) . removeClass ( 'settingsCheckboxChecked' ) ;
}
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'blockedMLATFilter' , blockedMLATFilter ) ;
2017-01-26 19:38:47 +00:00
PlaneFilter . blockedMLAT = blockedMLATFilter ;
}
2017-02-10 20:41:48 +00:00
function toggleAltitudeChart ( switchToggle ) {
if ( typeof localStorage [ 'altitudeChart' ] === 'undefined' ) {
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'altitudeChart' , 'show' ) ;
2017-02-10 20:41:48 +00:00
}
2020-02-20 18:48:05 +00:00
var altitudeChartDisplay = localStorage . getItem ( 'altitudeChart' ) ;
2017-02-10 20:41:48 +00:00
if ( switchToggle === true ) {
altitudeChartDisplay = ( altitudeChartDisplay === 'show' ) ? 'hidden' : 'show' ;
}
2020-02-20 18:48:05 +00:00
// if you're using custom colors always hide the chart
if ( customAltitudeColors === true ) {
altitudeChartDisplay = 'hidden' ;
// also hide the control option
$ ( '#altitude_chart_container' ) . hide ( ) ;
}
2017-02-10 20:41:48 +00:00
if ( altitudeChartDisplay === 'show' ) {
$ ( '#altitude_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
$ ( '#altitude_chart' ) . show ( ) ;
} else {
$ ( '#altitude_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
$ ( '#altitude_chart' ) . hide ( ) ;
}
2020-02-20 18:48:05 +00:00
localStorage . setItem ( 'altitudeChart' , altitudeChartDisplay ) ;
2017-02-10 20:41:48 +00:00
}
2016-08-24 20:28:13 +00:00
function updatePlaneFilter ( ) {
2020-12-14 14:37:16 +00:00
// Get min/max altitude values from slider
2020-12-14 06:34:40 +00:00
var minAltitude = document . getElementById ( 'minAltitudeText' ) . innerHTML . trim ( ) ;
var maxAltitude = document . getElementById ( 'maxAltitudeText' ) . innerHTML . trim ( ) ;
2016-08-24 20:28:13 +00:00
PlaneFilter . minAltitude = minAltitude ;
PlaneFilter . maxAltitude = maxAltitude ;
PlaneFilter . altitudeUnits = DisplayUnits ;
2020-12-02 21:26:45 +00:00
2020-12-14 14:37:16 +00:00
// Get min/max speed values from slider
var minSpeedFilter = document . getElementById ( 'minSpeedText' ) . innerHTML . trim ( ) ;
var maxSpeedFilter = document . getElementById ( 'maxSpeedText' ) . innerHTML . trim ( ) ;
PlaneFilter . minSpeedFilter = minSpeedFilter ;
PlaneFilter . maxSpeedFilter = maxSpeedFilter ;
PlaneFilter . speedUnits = DisplayUnits ;
// Get aircraft type code filter from input box
2020-12-09 15:18:05 +00:00
var aircraftTypeCode = $ ( "#aircraft_type_filter" ) . val ( ) . trim ( ) . toUpperCase ( )
2020-12-02 21:26:45 +00:00
if ( aircraftTypeCode === "" ) {
2020-12-07 22:18:16 +00:00
aircraftTypeCode = undefined
2020-12-02 21:26:45 +00:00
}
2020-12-14 14:37:16 +00:00
// Get aircraft ident filter from input box
2020-12-09 15:18:05 +00:00
var aircraftIdent = $ ( "#aircraft_ident_filter" ) . val ( ) . trim ( ) . toUpperCase ( )
2020-12-07 16:26:56 +00:00
if ( aircraftIdent === "" ) {
aircraftIdent = undefined
}
2020-12-02 21:26:45 +00:00
PlaneFilter . aircraftTypeCode = aircraftTypeCode ;
2020-12-07 16:26:56 +00:00
PlaneFilter . aircraftIdent = aircraftIdent ;
2021-02-09 04:33:50 +00:00
2021-02-10 01:06:35 +00:00
var altitudeFilterSet = ( PlaneFilter . minAltitude == DefaultMinMaxFilters [ DisplayUnits ] . min && PlaneFilter . maxAltitude == DefaultMinMaxFilters [ DisplayUnits ] . maxAltitude ) ? 0 : 1 ;
var speedFilterSet = ( PlaneFilter . minSpeedFilter == DefaultMinMaxFilters [ DisplayUnits ] . min && PlaneFilter . maxSpeedFilter == DefaultMinMaxFilters [ DisplayUnits ] . maxSpeed ) ? 0 : 1 ;
2021-02-09 04:33:50 +00:00
var aircraftTypeFilterSet = ( PlaneFilter . aircraftTypeCode == undefined ) ? 0 : 1 ;
var aircraftIdentFilterSet = ( PlaneFilter . aircraftIdent == undefined ) ? 0 : 1 ;
ActiveFilterCount = altitudeFilterSet + speedFilterSet + aircraftTypeFilterSet + aircraftIdentFilterSet ;
2021-02-10 20:40:57 +00:00
var filter = document . getElementById ( 'filter_button' ) ;
filter . style . backgroundColor = ( ActiveFilterCount > 0 ) ? "Lime" : "#FEBC11" ;
2016-08-24 20:28:13 +00:00
}
2020-12-07 22:18:16 +00:00
function refreshDataSourceFilters ( ) {
PlaneFilter . ADSB = ( localStorage . getItem ( 'sourceADSBFilter' ) === 'selected' ) ? true : false ;
PlaneFilter . MLAT = ( localStorage . getItem ( 'sourceMLATFilter' ) === 'selected' ) ? true : false ;
PlaneFilter . Other = ( localStorage . getItem ( 'sourceOtherFilter' ) === 'selected' ) ? true : false ;
PlaneFilter . TISB = ( localStorage . getItem ( 'sourceTISBFilter' ) === 'selected' ) ? true : false ;
2021-02-25 05:35:05 +00:00
PlaneFilter . UAT = ( localStorage . getItem ( 'sourceUATFilter' ) === 'selected' ) ? true : false ;
2016-08-24 20:28:13 +00:00
}
2016-08-30 21:38:41 +00:00
function getFlightAwareIdentLink ( ident , linkText ) {
2016-08-22 23:15:06 +00:00
if ( ident !== null && ident !== "" ) {
2016-08-30 21:38:41 +00:00
if ( ! linkText ) {
linkText = ident ;
}
2021-02-25 15:42:16 +00:00
return "<a target=\"_blank\" href=\"https://flightaware.com/live/flight/" + ident . trim ( ) + "\"><span title=\"Bold ident indicates this is an aircraft registration number\"> " + linkText + "</span></a>" ;
2016-08-22 23:15:06 +00:00
}
return "" ;
}
2016-09-12 23:10:36 +00:00
function getFlightAwareModeSLink ( code , ident , linkText ) {
2016-09-07 19:20:42 +00:00
if ( code !== null && code . length > 0 && code [ 0 ] !== '~' && code !== "000000" ) {
2016-08-30 21:38:41 +00:00
if ( ! linkText ) {
linkText = "FlightAware: " + code . toUpperCase ( ) ;
}
2016-09-12 23:10:36 +00:00
var linkHtml = "<a target=\"_blank\" href=\"https://flightaware.com/live/modes/" + code ;
if ( ident !== null && ident !== "" ) {
linkHtml += "/ident/" + ident . trim ( ) ;
}
linkHtml += "/redirect\">" + linkText + "</a>" ;
return linkHtml ;
2016-08-22 23:15:06 +00:00
}
return "" ;
}
2016-08-23 15:41:58 +00:00
function getFlightAwarePhotoLink ( registration ) {
if ( registration !== null && registration !== "" ) {
2018-08-08 21:41:34 +00:00
return "<a target=\"_blank\" href=\"https://flightaware.com/photos/aircraft/" + registration . replace ( /[^0-9a-z]/ig , '' ) + "\">See Photos</a>" ;
2016-08-23 15:41:58 +00:00
}
return "" ;
}
2016-08-22 23:15:06 +00:00
function getAirframesModeSLink ( code ) {
2016-09-07 19:20:42 +00:00
if ( code !== null && code . length > 0 && code [ 0 ] !== '~' && code !== "000000" ) {
2016-08-22 23:15:06 +00:00
return "<a href=\"http://www.airframes.org/\" onclick=\"$('#airframes_post_icao').attr('value','" + code + "'); document.getElementById('horrible_hack').submit.call(document.getElementById('airframes_post')); return false;\">Airframes.org: " + code . toUpperCase ( ) + "</a>" ;
}
return "" ;
}
2017-01-23 20:02:45 +00:00
// takes in an elemnt jQuery path and the OL3 layer name and toggles the visibility based on clicking it
function toggleLayer ( element , layer ) {
2020-07-21 16:32:39 +00:00
// set initial checked status
ol . control . LayerSwitcher . forEachRecursive ( layerGroup , function ( lyr ) {
2017-01-23 20:02:45 +00:00
if ( lyr . get ( 'name' ) === layer && lyr . getVisible ( ) ) {
$ ( element ) . addClass ( 'settingsCheckboxChecked' ) ;
}
} ) ;
$ ( element ) . on ( 'click' , function ( ) {
var visible = false ;
if ( $ ( element ) . hasClass ( 'settingsCheckboxChecked' ) ) {
visible = true ;
}
2020-07-21 16:32:39 +00:00
ol . control . LayerSwitcher . forEachRecursive ( layerGroup , function ( lyr ) {
2017-01-23 20:02:45 +00:00
if ( lyr . get ( 'name' ) === layer ) {
if ( visible ) {
lyr . setVisible ( false ) ;
$ ( element ) . removeClass ( 'settingsCheckboxChecked' ) ;
} else {
lyr . setVisible ( true ) ;
$ ( element ) . addClass ( 'settingsCheckboxChecked' ) ;
}
}
} ) ;
} ) ;
}
2017-01-26 22:32:45 +00:00
// check status.json if it has a serial number for a flightfeeder
function flightFeederCheck ( ) {
2020-08-07 18:47:32 +00:00
$ . ajax ( '/status.json' , {
success : function ( data ) {
if ( data . type === "flightfeeder" ) {
isFlightFeeder = true ;
updatePiAwareOrFlightFeeder ( ) ;
}
}
} )
2017-01-26 22:32:45 +00:00
}
2020-12-11 16:42:24 +00:00
function setStatsLink ( ) {
$ . ajax ( '/status.json' , {
success : function ( data ) {
2020-12-11 16:56:48 +00:00
if ( data . unclaimed _feeder _id ) {
var claim _link = "https://flightaware.com/adsb/piaware/claim/" + data . unclaimed _feeder _id ;
$ ( '#stats_page_button' ) . text ( "Claim this feeder on FlightAware" )
myAdsbStatsSiteUrl = claim _link ;
} else if ( data . site _url ) {
2020-12-11 16:42:24 +00:00
myAdsbStatsSiteUrl = data . site _url ;
}
}
} )
}
2017-01-26 22:32:45 +00:00
// updates the page to replace piaware with flightfeeder references
function updatePiAwareOrFlightFeeder ( ) {
2020-08-07 18:47:32 +00:00
if ( isFlightFeeder ) {
$ ( '.piAwareLogo' ) . hide ( ) ;
$ ( '.flightfeederLogo' ) . show ( ) ;
PageName = 'FlightFeeder SkyAware' ;
} else {
$ ( '.flightfeederLogo' ) . hide ( ) ;
$ ( '.piAwareLogo' ) . show ( ) ;
PageName = 'PiAware SkyAware' ;
}
refreshPageTitle ( ) ;
}
// Function to hide banner (ex. for a kiosk to show maximum data possible)
function hideBanner ( ) {
document . getElementById ( "header" ) . style . display = 'none' ;
document . getElementById ( "layout_container" ) . style . height = '100%' ;
updateMapSize ( ) ;
}
// Helper function to restrict the range of the inputs
function restrictUrlRequest ( c ) {
let v = parseFloat ( c ) ;
if ( v < 0 ) {
v = 0 ;
} else if ( v > 5 ) {
v = 5 ;
}
return v ;
}
// Function to zoom, but not by too much per 'amount'
function zoomMap ( c , zoomOut ) {
c = restrictUrlRequest ( c ) ;
ZoomLvl = OLMap . getView ( ) . getZoom ( ) ;
if ( zoomOut ) {
ZoomLvl *= Math . pow ( 0.95 , c ) ;
} else {
ZoomLvl /= Math . pow ( 0.95 , c ) ;
}
localStorage [ 'ZoomLvl' ] = ZoomLvl ;
OLMap . getView ( ) . setZoom ( ZoomLvl ) ;
}
// Function to move map at 0.005% of the extent per 'move'
function moveMap ( c , moveVertical , moveDownLeft ) {
c = restrictUrlRequest ( c ) ;
let cn = OLMap . getView ( ) . getCenter ( ) ;
let dist = 0 ;
if ( moveVertical ) {
dist = ol . extent . getHeight ( OLMap . getView ( ) . getProjection ( ) . getExtent ( ) ) ;
} else {
dist = ol . extent . getWidth ( OLMap . getView ( ) . getProjection ( ) . getExtent ( ) ) ;
}
let d = c * ( dist * . 005 ) ;
// 'up' or 'right' needs a negative number
if ( moveDownLeft ) {
d *= - 1.0 ;
}
if ( moveVertical ) {
ol . coordinate . add ( cn , [ 0 , d ] ) ;
} else {
ol . coordinate . add ( cn , [ d , 0 ] ) ;
}
OLMap . getView ( ) . setCenter ( cn ) ;
}
// Function to set displayUnits
function setDisplayUnits ( units ) {
if ( units === 'nautical' ) {
localStorage [ 'displayUnits' ] = "nautical" ;
} else if ( units === 'metric' ) {
localStorage [ 'displayUnits' ] = "metric" ;
} else if ( units === 'imperial' ) {
localStorage [ 'displayUnits' ] = "imperial" ;
}
onDisplayUnitsChanged ( ) ;
}
// Function to set range ring visibility
function setRangeRingVisibility ( showhide ) {
var show = null ;
if ( showhide === 'hide' ) {
$ ( '#sitepos_checkbox' ) . removeClass ( 'settingsCheckboxChecked' )
show = false ;
} else if ( showhide === 'show' ) {
$ ( '#sitepos_checkbox' ) . addClass ( 'settingsCheckboxChecked' )
show = true ;
} else {
return
}
ol . control . LayerSwitcher . forEachRecursive ( layerGroup , function ( lyr ) {
if ( lyr . get ( 'name' ) === 'site_pos' ) {
lyr . setVisible ( show ) ;
}
} ) ;
}
// simple function to set range ring count
function setRingCount ( val ) {
localStorage [ 'SiteCirclesCount' ] = val ;
setRangeRings ( ) ;
createSiteCircleFeatures ( ) ;
}
// simple function to set range ring distance
function setRingBaseDistance ( val ) {
localStorage [ 'SiteCirclesBaseDistance' ] = val ;
setRangeRings ( ) ;
createSiteCircleFeatures ( ) ;
}
// simple function to set range ring interval
function setRingInterval ( val ) {
localStorage [ 'SiteCirclesInterval' ] = val ;
setRangeRings ( ) ;
createSiteCircleFeatures ( ) ;
2017-01-26 22:32:45 +00:00
}
2020-03-01 17:20:53 +00:00
2020-03-02 19:19:57 +00:00
// Set range ring globals and populate form values
function setRangeRings ( ) {
2020-08-07 18:47:32 +00:00
SiteCirclesCount = Number ( localStorage [ 'SiteCirclesCount' ] ) || DefaultSiteCirclesCount ;
SiteCirclesBaseDistance = Number ( localStorage [ 'SiteCirclesBaseDistance' ] ) || DefaultSiteCirclesBaseDistance ;
SiteCirclesInterval = Number ( localStorage [ 'SiteCirclesInterval' ] ) || DefaultSiteCirclesInterval ;
// Populate text fields with current values
$ ( '#range_ring_count' ) . val ( SiteCirclesCount ) ;
$ ( '#range_ring_base' ) . val ( SiteCirclesBaseDistance ) ;
$ ( '#range_ring_interval' ) . val ( SiteCirclesInterval ) ;
2020-03-02 17:40:42 +00:00
}
2020-03-01 17:20:53 +00:00
// redraw range rings with form values
function onSetRangeRings ( ) {
2020-08-07 18:47:32 +00:00
// Save state to localStorage
localStorage . setItem ( 'SiteCirclesCount' , parseFloat ( $ ( "#range_ring_count" ) . val ( ) . trim ( ) ) ) ;
localStorage . setItem ( 'SiteCirclesBaseDistance' , parseFloat ( $ ( "#range_ring_base" ) . val ( ) . trim ( ) ) ) ;
localStorage . setItem ( 'SiteCirclesInterval' , parseFloat ( $ ( "#range_ring_interval" ) . val ( ) . trim ( ) ) ) ;
2020-03-02 19:19:57 +00:00
2020-08-07 18:47:32 +00:00
setRangeRings ( ) ;
2020-03-01 17:20:53 +00:00
2020-08-07 18:47:32 +00:00
createSiteCircleFeatures ( ) ;
2020-03-01 17:20:53 +00:00
}
2020-07-21 15:00:32 +00:00
function toggleColumn ( div , checkbox , toggled ) {
if ( typeof localStorage [ checkbox ] === 'undefined' ) {
localStorage . setItem ( checkbox , 'deselected' ) ;
}
var status = localStorage . getItem ( checkbox ) ;
var infoTable = $ ( "#tableinfo" ) ;
if ( toggled === true ) {
status = ( status === 'deselected' ) ? 'selected' : 'deselected' ;
}
// Toggle checkbox and column visibility
if ( status === 'selected' ) {
$ ( checkbox ) . addClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , true ) ;
} else {
$ ( checkbox ) . removeClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , false ) ;
$ ( '#select_all_column_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
localStorage . setItem ( 'selectAllColumnsCheckbox' , 'deselected' ) ;
}
localStorage . setItem ( checkbox , status ) ;
}
function toggleAllColumns ( switchToggle ) {
if ( typeof localStorage [ 'selectAllColumnsCheckbox' ] === 'undefined' ) {
2020-08-04 19:38:07 +00:00
localStorage . setItem ( 'selectAllColumnsCheckbox' , 'deselected' ) ;
2020-07-21 15:00:32 +00:00
}
var infoTable = $ ( "#tableinfo" ) ;
var selectAllColumnsCheckbox = localStorage . getItem ( 'selectAllColumnsCheckbox' ) ;
if ( switchToggle === true ) {
selectAllColumnsCheckbox = ( selectAllColumnsCheckbox === 'deselected' ) ? 'selected' : 'deselected' ;
checkbox _div _map . forEach ( function ( div , checkbox ) {
if ( selectAllColumnsCheckbox === 'deselected' ) {
$ ( '#select_all_column_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
$ ( checkbox ) . removeClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , false ) ;
} else {
$ ( '#select_all_column_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
$ ( checkbox ) . addClass ( 'settingsCheckboxChecked' ) ;
showColumn ( infoTable , div , true ) ;
}
localStorage . setItem ( checkbox , selectAllColumnsCheckbox ) ;
} ) ;
} ;
if ( selectAllColumnsCheckbox === 'deselected' ) {
$ ( '#select_all_column_checkbox' ) . removeClass ( 'settingsCheckboxChecked' ) ;
} else {
$ ( '#select_all_column_checkbox' ) . addClass ( 'settingsCheckboxChecked' ) ;
}
localStorage . setItem ( 'selectAllColumnsCheckbox' , selectAllColumnsCheckbox ) ;
2020-08-07 18:47:32 +00:00
}
2020-12-07 19:37:04 +00:00
function toggleADSBAircraft ( switchFilter ) {
if ( typeof localStorage [ 'sourceADSBFilter' ] === 'undefined' ) {
2020-12-08 20:34:04 +00:00
localStorage . setItem ( 'sourceADSBFilter' , 'selected' ) ;
2020-12-07 19:37:04 +00:00
}
var sourceADSBFilter = localStorage . getItem ( 'sourceADSBFilter' ) ;
if ( switchFilter === true ) {
2020-12-07 22:18:16 +00:00
sourceADSBFilter = ( sourceADSBFilter === 'deselected' ) ? 'selected' : 'deselected' ;
2020-12-07 19:37:04 +00:00
}
2020-12-07 22:18:16 +00:00
if ( sourceADSBFilter === 'deselected' ) {
2020-12-07 19:37:04 +00:00
$ ( '#adsb_datasource_checkbox' ) . removeClass ( 'sourceCheckboxChecked' ) ;
} else {
$ ( '#adsb_datasource_checkbox' ) . addClass ( 'sourceCheckboxChecked' ) ;
}
localStorage . setItem ( 'sourceADSBFilter' , sourceADSBFilter ) ;
}
2021-02-25 05:35:05 +00:00
function toggleUATAircraft ( switchFilter ) {
if ( typeof localStorage [ 'sourceUATFilter' ] === 'undefined' ) {
localStorage . setItem ( 'sourceUATFilter' , 'selected' ) ;
}
var sourceUATFilter = localStorage . getItem ( 'sourceUATFilter' ) ;
if ( switchFilter === true ) {
sourceUATFilter = ( sourceUATFilter === 'deselected' ) ? 'selected' : 'deselected' ;
}
if ( sourceUATFilter === 'deselected' ) {
$ ( '#uat_datasource_checkbox' ) . removeClass ( 'sourceCheckboxChecked' ) ;
} else {
$ ( '#uat_datasource_checkbox' ) . addClass ( 'sourceCheckboxChecked' ) ;
}
localStorage . setItem ( 'sourceUATFilter' , sourceUATFilter ) ;
}
2020-12-07 19:37:04 +00:00
function toggleMLATAircraft ( switchFilter ) {
if ( typeof localStorage [ 'sourceMLATFilter' ] === 'undefined' ) {
2020-12-08 20:34:04 +00:00
localStorage . setItem ( 'sourceMLATFilter' , 'selected' ) ;
2020-12-07 19:37:04 +00:00
}
var sourceMLATFilter = localStorage . getItem ( 'sourceMLATFilter' ) ;
if ( switchFilter === true ) {
2020-12-07 22:18:16 +00:00
sourceMLATFilter = ( sourceMLATFilter === 'deselected' ) ? 'selected' : 'deselected' ;
2020-12-07 19:37:04 +00:00
}
2020-12-07 22:18:16 +00:00
if ( sourceMLATFilter === 'deselected' ) {
2020-12-07 19:37:04 +00:00
$ ( '#mlat_datasource_checkbox' ) . removeClass ( 'sourceCheckboxChecked' ) ;
} else {
$ ( '#mlat_datasource_checkbox' ) . addClass ( 'sourceCheckboxChecked' ) ;
}
localStorage . setItem ( 'sourceMLATFilter' , sourceMLATFilter ) ;
}
function toggleOtherAircraft ( switchFilter ) {
if ( typeof localStorage [ 'sourceOtherFilter' ] === 'undefined' ) {
2020-12-08 20:34:04 +00:00
localStorage . setItem ( 'sourceOtherFilter' , 'selected' ) ;
2020-12-07 19:37:04 +00:00
}
var sourceOtherFilter = localStorage . getItem ( 'sourceOtherFilter' ) ;
if ( switchFilter === true ) {
2020-12-07 22:18:16 +00:00
sourceOtherFilter = ( sourceOtherFilter === 'deselected' ) ? 'selected' : 'deselected' ;
2020-12-07 19:37:04 +00:00
}
2020-12-07 22:18:16 +00:00
if ( sourceOtherFilter === 'deselected' ) {
2020-12-07 19:37:04 +00:00
$ ( '#other_datasource_checkbox' ) . removeClass ( 'sourceCheckboxChecked' ) ;
} else {
$ ( '#other_datasource_checkbox' ) . addClass ( 'sourceCheckboxChecked' ) ;
}
localStorage . setItem ( 'sourceOtherFilter' , sourceOtherFilter ) ;
}
function toggleTISBAircraft ( switchFilter ) {
if ( typeof localStorage [ 'sourceTISBFilter' ] === 'undefined' ) {
2020-12-08 20:34:04 +00:00
localStorage . setItem ( 'sourceTISBFilter' , 'selected' ) ;
2020-12-07 19:37:04 +00:00
}
var sourceTISBFilter = localStorage . getItem ( 'sourceTISBFilter' ) ;
if ( switchFilter === true ) {
2020-12-07 22:18:16 +00:00
sourceTISBFilter = ( sourceTISBFilter === 'deselected' ) ? 'selected' : 'deselected' ;
2020-12-07 19:37:04 +00:00
}
2020-12-07 22:18:16 +00:00
if ( sourceTISBFilter === 'deselected' ) {
2020-12-07 19:37:04 +00:00
$ ( '#tisb_datasource_checkbox' ) . removeClass ( 'sourceCheckboxChecked' ) ;
} else {
$ ( '#tisb_datasource_checkbox' ) . addClass ( 'sourceCheckboxChecked' ) ;
}
localStorage . setItem ( 'sourceTISBFilter' , sourceTISBFilter ) ;
}