diff --git a/public_html/config.js b/public_html/config.js index 16b6e19..fe54a9e 100644 --- a/public_html/config.js +++ b/public_html/config.js @@ -11,14 +11,11 @@ PlaneCountInTitle = true; MessageRateInTitle = false; // -- Output Settings ------------------------------------- -// Show metric values -// The Metric setting controls whether metric (m, km, km/h) or -// imperial (ft, NM, knots) units are used in the plane table -// and in the detailed plane info. If ShowOtherUnits is true, -// then the other unit will also be shown in the detailed plane -// info. -Metric = false; -ShowOtherUnits = true; +// The DisplayUnits setting controls whether nautical (ft, NM, knots), +// metric (m, km, km/h) or imperial (ft, mi, mph) units are used in the +// plane table and in the detailed plane info. Valid values are +// "nautical", "metric", or "imperial". +DisplayUnits = "nautical"; // -- Map settings ---------------------------------------- // These settings are overridden by any position information @@ -98,7 +95,7 @@ OutlineADSBColor = '#000000'; OutlineMlatColor = '#4040FF'; SiteCircles = true; // true to show circles (only shown if the center marker is shown) -// In nautical miles or km (depending settings value 'Metric') +// In miles, nautical miles, or km (depending settings value 'DisplayUnits') SiteCirclesDistances = new Array(100,150,200); // Show the clocks at the top of the righthand pane? You can disable the clocks if you want here diff --git a/public_html/formatter.js b/public_html/formatter.js index 39fe041..6669dc1 100644 --- a/public_html/formatter.js +++ b/public_html/formatter.js @@ -8,8 +8,23 @@ var DOWN_TRIANGLE='\u25bc'; // U+25BC BLACK DOWN-POINTING TRIANGLE var TrackDirections = ["North","Northeast","East","Southeast","South","Southwest","West","Northwest"]; +var UnitLabels = { + 'altitude': { metric: "m", imperial: "ft", nautical: "ft"}, + 'speed': { metric: "km/h", imperial: "mph", nautical: "kt" }, + 'distance': { metric: "km", imperial: "mi", nautical: "NM" }, + 'verticalRate': { metric: "m/s", imperial: "ft/min", nautical: "ft/min" } +}; + // formatting helpers +function get_unit_label(quantity, systemOfMeasurement) { + var labels = UnitLabels[quantity]; + if (labels !== undefined && labels[systemOfMeasurement] !== undefined) { + return labels[systemOfMeasurement]; + } + return ""; +} + // track in degrees (0..359) function format_track_brief(track) { if (track === null){ @@ -31,7 +46,7 @@ function format_track_long(track) { // altitude (input: alt in feet) // brief will always show either Metric or Imperial -function format_altitude_brief(alt, vr) { +function format_altitude_brief(alt, vr, displayUnits) { var alt_text; if (alt === null){ @@ -40,7 +55,7 @@ function format_altitude_brief(alt, vr) { return "ground"; } - if (Metric) { + if (displayUnits === "metric") { alt_text = Math.round(alt / 3.2828) + NBSP; // Altitude to meters } else { alt_text = Math.round(alt) + NBSP; @@ -57,14 +72,16 @@ function format_altitude_brief(alt, vr) { } // alt in ft -function _alt_to_unit(alt, m) { - if (m) - return Math.round(alt / 3.2828) + NBSP + "m"; +function _alt_to_unit(alt, displayUnits) { + var unitLabel = get_unit_label("altitude", displayUnits); + + if (displayUnits === "metric") + return Math.round(alt / 3.2828) + NBSP + unitLabel; else - return Math.round(alt) + NBSP + "ft"; + return Math.round(alt) + NBSP + unitLabel; } -function format_altitude_long(alt, vr) { +function format_altitude_long(alt, vr, displayUnits) { var alt_text = ""; if (alt === null) { @@ -73,14 +90,8 @@ function format_altitude_long(alt, vr) { return "on ground"; } - // Primary unit - alt_text = _alt_to_unit(alt, Metric); + alt_text = _alt_to_unit(alt, displayUnits); - // Secondary unit - if (ShowOtherUnits) { - alt_text = alt_text + ' | ' + _alt_to_unit(alt, !Metric); - } - if (vr > 128) { return UP_TRIANGLE + NBSP + alt_text; } else if (vr < -128) { @@ -91,13 +102,15 @@ function format_altitude_long(alt, vr) { } //input: speed in kts -function format_speed_brief(speed) { +function format_speed_brief(speed, displayUnits) { if (speed === null) { return ""; } - - if (Metric) { + + if (displayUnits === "metric") { return Math.round(speed * 1.852); // knots to kilometers per hour + } else if (displayUnits === "imperial") { + return Math.round(speed * 1.151); // knots to miles per hour } else { return Math.round(speed); // knots } @@ -105,67 +118,78 @@ function format_speed_brief(speed) { // speed in kts -function _speed_to_unit(speed, m) { - if (m) - return Math.round(speed * 1.852) + NBSP + "km/h"; +function _speed_to_unit(speed, displayUnits) { + var unitLabel = get_unit_label("speed", displayUnits); + + if (displayUnits === "metric") + return Math.round(speed * 1.852) + NBSP + unitLabel; + else if (displayUnits === "imperial") + return Math.round(speed * 1.151) + NBSP + unitLabel; else - return Math.round(speed) + NBSP + "kt"; + return Math.round(speed) + NBSP + unitLabel; } -function format_speed_long(speed) { +function format_speed_long(speed, displayUnits) { if (speed === null) { return "n/a"; } - // Primary unit - var speed_text = _speed_to_unit(speed, Metric); + var speed_text = _speed_to_unit(speed, displayUnits); - // Secondary unit - if (ShowOtherUnits) { - speed_text = speed_text + ' | ' + _speed_to_unit(speed, !Metric); - } - return speed_text; } // dist in meters -function format_distance_brief(dist) { +function format_distance_brief(dist, displayUnits) { if (dist === null) { return ""; } - if (Metric) { + if (displayUnits === "metric") { return (dist/1000).toFixed(1); // meters to kilometers + } else if (displayUnits === "imperial") { + return (dist/1609).toFixed(1); // meters to miles } else { - return (dist/1852).toFixed(1); // meters to nautocal miles + return (dist/1852).toFixed(1); // meters to nautical miles } } // dist in metres -function _dist_to_unit(dist, m) { - if (m) - return (dist/1000).toFixed(1) + NBSP + "km"; +function _dist_to_unit(dist, displayUnits) { + var unitLabel = get_unit_label("distance", displayUnits); + + if (displayUnits === "metric") + return (dist/1000).toFixed(1) + NBSP + unitLabel; + else if (displayUnits === "imperial") + return (dist/1609).toFixed(1) + NBSP + unitLabel; else - return (dist/1852).toFixed(1) + NBSP + "NM"; + return (dist/1852).toFixed(1) + NBSP + unitLabel; } -function format_distance_long(dist) { +function format_distance_long(dist, displayUnits) { if (dist === null) { return "n/a"; } - // Primary unit - var dist_text = _dist_to_unit(dist, Metric); - - // Secondary unit - if (ShowOtherUnits) { - dist_text = dist_text + ' | ' + _dist_to_unit(dist, !Metric); - } + var dist_text = _dist_to_unit(dist, displayUnits); return dist_text; } +// rate in ft/min +function format_vert_rate_brief(rate, displayUnits) { + if (rate === null) { + return ""; + } + + if (displayUnits === "metric") { + return (rate/196.85).toFixed(1); // ft/min to m/s + } else { + return Math.round(rate); + } +} + // p is a [lon, lat] coordinate function format_latlng(p) { return p[1].toFixed(3) + DEGREES + "," + NBSP + p[0].toFixed(3) + DEGREES; diff --git a/public_html/index.html b/public_html/index.html index b72ac14..d78c1e4 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -160,6 +160,15 @@ +
+ + +
+
@@ -170,10 +179,10 @@ - - - - + + + + diff --git a/public_html/script.js b/public_html/script.js index ed453ea..667a45e 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -4,6 +4,7 @@ // Define our global variables var OLMap = null; var StaticFeatures = new ol.Collection(); +var SiteCircleFeatures = new ol.Collection(); var PlaneIconFeatures = new ol.Collection(); var PlaneTrailFeatures = new ol.Collection(); var Planes = {}; @@ -222,6 +223,9 @@ function initialize() { $("#show_map_button").hide(); setColumnVisibility(); + // Initialize other controls + initializeUnitsSelector(); + // Force map to redraw if sidebar container is resized - use a timer to debounce var mapResizeTimeout; $("#sidebar_container").on("resize", function() { @@ -470,7 +474,7 @@ function initialize_map() { controls: [new ol.control.Zoom(), new ol.control.Rotate(), new ol.control.Attribution({collapsed: false}), - new ol.control.ScaleLine({units: Metric ? "metric" : "nautical"}), + new ol.control.ScaleLine({units: DisplayUnits}), new ol.control.LayerSwitcher() ], loadTilesWhileAnimating: true, @@ -531,26 +535,7 @@ function initialize_map() { StaticFeatures.push(feature); if (SiteCircles) { - var circleStyle = new ol.style.Style({ - fill: null, - stroke: new ol.style.Stroke({ - color: '#000000', - width: 1 - }) - }); - - for (var i=0; i < SiteCirclesDistances.length; ++i) { - var distance = SiteCirclesDistances[i] * 1000.0; - if (!Metric) { - distance *= 1.852; - } - - var circle = make_geodesic_circle(SitePosition, distance, 360); - circle.transform('EPSG:4326', 'EPSG:3857'); - var feature = new ol.Feature(circle); - feature.setStyle(circleStyle); - StaticFeatures.push(feature); - } + createSiteCircleFeatures(); } } @@ -604,6 +589,39 @@ function initialize_map() { }); } +function createSiteCircleFeatures() { + // Clear existing circles first + SiteCircleFeatures.forEach(function(circleFeature) { + StaticFeatures.remove(circleFeature); + }); + SiteCircleFeatures.clear(); + + var circleStyle = new ol.style.Style({ + fill: null, + stroke: new ol.style.Stroke({ + color: '#000000', + width: 1 + }) + }); + + var conversionFactor = 1000.0; + if (DisplayUnits === "nautical") { + conversionFactor = 1852.0; + } else if (DisplayUnits === "imperial") { + conversionFactor = 1609.0; + } + + for (var i=0; i < SiteCirclesDistances.length; ++i) { + var distance = SiteCirclesDistances[i] * conversionFactor; + var circle = make_geodesic_circle(SitePosition, distance, 360); + circle.transform('EPSG:4326', 'EPSG:3857'); + var feature = new ol.Feature(circle); + feature.setStyle(circleStyle); + StaticFeatures.push(feature); + SiteCircleFeatures.push(feature); + } +} + // This looks for planes to reap out of the master Planes variable function reaper() { //console.log("Reaping started.."); @@ -716,7 +734,7 @@ function refreshSelected() { emerg.className = 'hidden'; } - $("#selected_altitude").text(format_altitude_long(selected.altitude, selected.vert_rate)); + $("#selected_altitude").text(format_altitude_long(selected.altitude, selected.vert_rate, DisplayUnits)); if (selected.squawk === null || selected.squawk === '0000') { $('#selected_squawk').text('n/a'); @@ -724,7 +742,7 @@ function refreshSelected() { $('#selected_squawk').text(selected.squawk); } - $('#selected_speed').text(format_speed_long(selected.speed)); + $('#selected_speed').text(format_speed_long(selected.speed, DisplayUnits)); $('#selected_icao').text(selected.icao.toUpperCase()); $('#airframes_post_icao').attr('value',selected.icao); $('#selected_track').text(format_track_long(selected.track)); @@ -763,7 +781,7 @@ function refreshSelected() { } } - $('#selected_sitedist').text(format_distance_long(selected.sitedist)); + $('#selected_sitedist').text(format_distance_long(selected.sitedist, DisplayUnits)); $('#selected_rssi').text(selected.rssi.toFixed(1) + ' dBFS'); } @@ -804,18 +822,23 @@ function refreshTableInfo() { 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].textContent = format_altitude_brief(tableplane.altitude, tableplane.vert_rate); - tableplane.tr.cells[7].textContent = format_speed_brief(tableplane.speed); - tableplane.tr.cells[8].textContent = (tableplane.vert_rate !== null ? tableplane.vert_rate : ""); - tableplane.tr.cells[9].textContent = format_distance_brief(tableplane.sitedist); + tableplane.tr.cells[6].textContent = format_altitude_brief(tableplane.altitude, tableplane.vert_rate, DisplayUnits); + tableplane.tr.cells[7].textContent = format_speed_brief(tableplane.speed, 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] : ""); - tableplane.tr.cells[15].textContent = (tableplane.position !== null ? tableplane.position[0] : ""); + 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.className = classes; + + $("#header_altitude_unit").text(get_unit_label("altitude", DisplayUnits)); + $("#header_speed_unit").text(get_unit_label("speed", DisplayUnits)); + $("#header_distance_unit").text(get_unit_label("distance", DisplayUnits)); + $("#header_vert_rate_unit").text(get_unit_label("verticalRate", DisplayUnits)); } } @@ -1073,7 +1096,7 @@ function showMap() { $("#splitter").show(); $("#sudo_buttons").show(); $("#show_map_button").hide(); - $("#sidebar_container").width("410px"); + $("#sidebar_container").width("420px"); setColumnVisibility(); updateMapSize(); } @@ -1102,3 +1125,40 @@ function setColumnVisibility() { showColumn(infoTable, "#lon", !mapIsVisible); showColumn(infoTable, "#data_source", !mapIsVisible); } + +function initializeUnitsSelector() { + // Get display unit preferences from local storage + if (!localStorage.getItem('displayUnits')) { + localStorage['displayUnits'] = "nautical"; + } + var displayUnits = localStorage['displayUnits']; + DisplayUnits = displayUnits; + + // Initialize drop-down + var unitsSelector = $("#units_selector"); + unitsSelector.val(displayUnits); + unitsSelector.on("change", onDisplayUnitsChanged); +} + +function onDisplayUnitsChanged(e) { + var displayUnits = event.target.value; + // Save display units to local storage + localStorage['displayUnits'] = displayUnits; + DisplayUnits = displayUnits; + + // Refresh data + refreshTableInfo(); + refreshSelected(); + + // Redraw range rings + if (SiteCircleFeatures) { + createSiteCircleFeatures(); + } + + // Reset map scale line units + OLMap.getControls().forEach(function(control) { + if (control instanceof ol.control.ScaleLine) { + control.setUnits(displayUnits); + } + }); +} diff --git a/public_html/style.css b/public_html/style.css index 6f5b942..e712c72 100644 --- a/public_html/style.css +++ b/public_html/style.css @@ -78,7 +78,7 @@ html, body { #sidebar_container { display: flex; - width: 410px; + width: 420px; left: 0 !important; } @@ -108,6 +108,10 @@ div#loader { z-index: 99; position: absolute; left: 0; top: 0; bottom: 0; right: #tableinfo, #sudo_buttons { font-size: x-small; font-family: monospace; } +#units_selector { + margin: 10px 0 10px 0; +} + .vPosition { font-weight: bold; background-color: #d5ffd5; } .mlat { font-weight: bold; background-color: #d5d5ff; } .squawk7500 { font-weight: bold; background-color: #ff5555; }
Registration Aircraft type SquawkAltitudeSpeedVertical RateDistanceAltitude ()Speed ()Vertical Rate ()Distance () Track Msgs Age