diff --git a/public_html/images/icon-information@2x.png b/public_html/images/icon-information@2x.png new file mode 100644 index 0000000..ec261ce Binary files /dev/null and b/public_html/images/icon-information@2x.png differ diff --git a/public_html/images/toggle-height@2x.png b/public_html/images/toggle-height@2x.png new file mode 100644 index 0000000..b127fc2 Binary files /dev/null and b/public_html/images/toggle-height@2x.png differ diff --git a/public_html/images/toggle-width@2x.png b/public_html/images/toggle-width@2x.png new file mode 100644 index 0000000..626757a Binary files /dev/null and b/public_html/images/toggle-width@2x.png differ diff --git a/public_html/index.html b/public_html/index.html index 48bb634..577523c 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -2,13 +2,13 @@ - + - + @@ -22,7 +22,7 @@ - + PiAware Skyview @@ -63,182 +63,7 @@
- +
@@ -263,6 +88,14 @@
+
+ + +
Overlay Toggles
@@ -326,114 +159,476 @@
diff --git a/public_html/script.js b/public_html/script.js index 8d58106..fcf928a 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -203,11 +203,47 @@ function initialize() { } // Set up map/sidebar splitter - $("#sidebar_container").resizable({handles: {w: '#splitter'}}); + $("#sidebar_container").resizable({ + handles: { + w: '#splitter' + }, + minWidth: 350 + }); - // Set up aircraft information panel - $("#selected_infoblock").draggable({containment: "parent"}); + // Set up datablock splitter + $('#selected_infoblock').resizable({ + handles: { + s: '#splitter-infoblock' + }, + containment: "#sidebar_container", + minHeight: 50 + }); + // 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'); + }); + + // to make the infoblock responsive + $('#sidebar_container').on('resize', function() { + console.log('sidebar resize', $('#sidebar_canvas').width()); + if ($('#sidebar_container').width() < 500) { + $('#selected_infoblock').addClass('infoblock-container-small'); + } else { + $('#selected_infoblock').removeClass('infoblock-container-small'); + } + }); + // Set up event handlers for buttons $("#toggle_sidebar_button").click(toggleSidebarVisibility); $("#expand_sidebar_button").click(expandSidebar); @@ -331,21 +367,26 @@ function initialize() { } var CurrentHistoryFetch = null; -var PositionHistoryBuffer = [] +var PositionHistoryBuffer = []; var HistoryItemsReturned = 0; function start_load_history() { - if (PositionHistorySize > 0 && window.location.hash != '#nohistory') { - $("#loader_progress").attr('max',PositionHistorySize); - console.log("Starting to load history (" + PositionHistorySize + " items)"); - //Load history items in parallel - for (var i = 0; i < PositionHistorySize; i++) { - load_history_item(i); - } - } + if (PositionHistorySize > 0 && window.location.hash != '#nohistory') { + $("#loader_progress").attr('max',PositionHistorySize); + console.log("Starting to load history (" + PositionHistorySize + " items)"); + //Load history items in parallel + for (var i = 0; i < PositionHistorySize; i++) { + load_history_item(i); + } + } } function load_history_item(i) { + if (i >= PositionHistorySize) { + end_load_history(); + } + console.log("Loading history #" + i); + $("#loader_progress").attr('value',i); $.ajax({ url: 'data/history_' + i + '.json', timeout: 5000, @@ -353,20 +394,20 @@ function load_history_item(i) { dataType: 'json' }) .done(function(data) { - PositionHistoryBuffer.push(data); - HistoryItemsReturned++; - $("#loader_progress").attr('value',HistoryItemsReturned); - if (HistoryItemsReturned == PositionHistorySize) { - end_load_history(); - } + PositionHistoryBuffer.push(data); + HistoryItemsReturned++; + $("#loader_progress").attr('value',HistoryItemsReturned); + if (HistoryItemsReturned == PositionHistorySize) { + end_load_history(); + } }) .fail(function(jqxhr, status, error) { - //Doesn't matter if it failed, we'll just be missing a data point - HistoryItemsReturned++; - if (HistoryItemsReturned == PositionHistorySize) { - end_load_history(); - } + //Doesn't matter if it failed, we'll just be missing a data point + HistoryItemsReturned++; + if (HistoryItemsReturned == PositionHistorySize) { + end_load_history(); + } }); } @@ -587,9 +628,9 @@ function initialize_map() { if (FollowSelected) { // On manual navigation, disable follow var selected = Planes[SelectedPlane]; - if (typeof selected === 'undefined' || - (Math.abs(center[0] - selected.position[0]) > 0.0001 && - Math.abs(center[1] - selected.position[1]) > 0.0001)) { + if (typeof selected === 'undefined' || + (Math.abs(center[0] - selected.position[0]) > 0.0001 && + Math.abs(center[1] - selected.position[1]) > 0.0001)){ FollowSelected = false; refreshSelected(); refreshHighlighted(); @@ -856,7 +897,7 @@ function refreshSelected() { } else { $('#selected_callsign').text('n/a'); } - $('#selected_flightaware_link').html(getFlightAwareModeSLink(selected.icao, selected.flight, "FlightAware.com")); + $('#selected_flightaware_link').html(getFlightAwareModeSLink(selected.icao, selected.flight, "Visit Flight Page")); if (selected.registration !== null) { $('#selected_registration').text(selected.registration); @@ -879,7 +920,7 @@ function refreshSelected() { // emerg.className = 'hidden'; // } - $("#selected_altitude").text(format_altitude_long(selected.altitude, selected.vert_rate, DisplayUnits)); + $("#selected_altitude").text(format_altitude_long(selected.altitude, selected.vert_rate, DisplayUnits)); if (selected.squawk === null || selected.squawk === '0000') { $('#selected_squawk').text('n/a'); @@ -887,11 +928,14 @@ function refreshSelected() { $('#selected_squawk').text(selected.squawk); } - $('#selected_gs').text(format_speed_long(selected.gs, DisplayUnits)); - $('#selected_vertical_rate').text(format_vert_rate_long(selected.vert_rate, DisplayUnits)); + $('#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)); $('#selected_icao').text(selected.icao.toUpperCase()); $('#airframes_post_icao').attr('value',selected.icao); - $('#selected_track').text(format_track_long(selected.track)); + $('#selected_track').text(format_track_long(selected.track)); if (selected.seen <= 1) { $('#selected_seen').text('now'); @@ -917,8 +961,8 @@ function refreshSelected() { $('#selected_position').text(format_latlng(selected.position)); } else { $('#selected_position').text(format_latlng(selected.position)); - } - + } + $('#selected_follow').removeClass('hidden'); if (FollowSelected) { $('#selected_follow').css('font-weight', 'bold'); @@ -927,21 +971,22 @@ function refreshSelected() { $('#selected_follow').css('font-weight', 'normal'); } } - if (selected.getDataSource() === "adsb_icao") { - $('#selected_source').text("ADS-B"); - } else if (selected.getDataSource() === "tisb_trackfile" || selected.getDataSource() === "tisb_icao" || selected.getDataSource() === "tisb_other") { - $('#selected_source').text("TIS-B"); - } else if (selected.getDataSource() === "mlat") { - $('#selected_source').text("MLAT"); - } else { - $('#selected_source').text("Other"); - } + if (selected.getDataSource() === "adsb_icao") { + $('#selected_source').text("ADS-B"); + } else if (selected.getDataSource() === "tisb_trackfile" || selected.getDataSource() === "tisb_icao" || selected.getDataSource() === "tisb_other") { + $('#selected_source').text("TIS-B"); + } else if (selected.getDataSource() === "mlat") { + $('#selected_source').text("MLAT"); + } else { + $('#selected_source').text("Other"); + } + $('#selected_category').text(selected.category ? selected.category : "n/a"); $('#selected_sitedist').text(format_distance_long(selected.sitedist, DisplayUnits)); $('#selected_rssi').text(selected.rssi.toFixed(1) + ' dBFS'); $('#selected_message_count').text(selected.messages); - $('#selected_photo_link').html(getFlightAwarePhotoLink(selected.registration)); - - $('#selected_alt_geom').text(format_altitude_long(selected.alt_geom, selected.geom_rate, DisplayUnits)); + $('#selected_photo_link').html(getFlightAwarePhotoLink(selected.registration)); + + $('#selected_altitude_geom').text(format_altitude_long(selected.alt_geom, selected.geom_rate, DisplayUnits)); $('#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)); @@ -957,9 +1002,9 @@ function refreshSelected() { $('#selected_roll').text(selected.roll.toFixed(1)); } if (selected.track_rate == null) { - $('#selected_track_rate').text('n/a'); + $('#selected_trackrate').text('n/a'); } else { - $('#selected_track_rate').text(selected.track_rate.toFixed(2)); + $('#selected_trackrate').text(selected.track_rate.toFixed(2)); } $('#selected_geom_rate').text(format_vert_rate_long(selected.geom_rate, DisplayUnits)); if (selected.nav_qnh == null) { @@ -986,7 +1031,8 @@ function refreshSelected() { } else { $('#selected_version').text('v' + selected.version); } -} + + } function refreshHighlighted() { // this is following nearly identical logic, etc, as the refreshSelected function, but doing less junk for the highlighted pane @@ -1004,6 +1050,48 @@ function refreshHighlighted() { $('#highlighted_infoblock').show(); + // Get info box position and size + var infoBox = $('#highlighted_infoblock'); + var infoBoxPosition = infoBox.position(); + if (typeof infoBoxOriginalPosition.top === 'undefined') { + infoBoxOriginalPosition.top = infoBoxPosition.top; + infoBoxOriginalPosition.left = infoBoxPosition.left; + } else { + infoBox.css("left", infoBoxOriginalPosition.left); + infoBox.css("top", infoBoxOriginalPosition.top); + infoBoxPosition = infoBox.position(); + } + var infoBoxExtent = getExtent(infoBoxPosition.left, infoBoxPosition.top, infoBox.outerWidth(), infoBox.outerHeight()); + + // Get map size + var mapCanvas = $('#map_canvas'); + var mapExtent = getExtent(0, 0, mapCanvas.width(), mapCanvas.height()); + + var marker = highlighted.marker; + var markerCoordinates = highlighted.marker.getGeometry().getCoordinates(); + var markerPosition = OLMap.getPixelFromCoordinate(markerCoordinates); + + // Check for overlap + //FIXME TODO: figure out this/remove this check + if (isPointInsideExtent(markerPosition[0], markerPosition[1], infoBoxExtent) || true) { + // Array of possible new positions for info box + var candidatePositions = []; + candidatePositions.push( { x: 40, y: 80 } ); + candidatePositions.push( { x: markerPosition[0] + 20, y: markerPosition[1] + 60 } ); + + // Find new position + for (var i = 0; i < candidatePositions.length; i++) { + var candidatePosition = candidatePositions[i]; + var candidateExtent = getExtent(candidatePosition.x, candidatePosition.y, infoBox.outerWidth(), infoBox.outerHeight()); + + 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); + } + } + } + if (highlighted.flight !== null && highlighted.flight !== "") { $('#highlighted_callsign').text(highlighted.flight); } else { @@ -1223,6 +1311,8 @@ function selectPlaneByHex(hex,autofollow) { Planes[SelectedPlane].clearLines(); Planes[SelectedPlane].updateMarker(); $(Planes[SelectedPlane].tr).removeClass("selected"); + // scroll the infoblock back to the top for the next plane to be selected + $('.infoblock-container').scrollTop(0); } // If we are clicking the same plane, we are deselecting it. @@ -1424,9 +1514,11 @@ function setSelectedInfoBlockVisibility() { if (planeSelected && mapIsVisible) { $('#selected_infoblock').show(); + $('#sidebar_canvas').css('margin-bottom', $('#selected_infoblock').height() + 'px'); } else { $('#selected_infoblock').hide(); + $('#sidebar_canvas').css('margin-bottom', 0); } } @@ -1446,21 +1538,8 @@ function adjustSelectedInfoBlockPosition() { // Get marker position var marker = selectedPlane.marker; var markerCoordinates = selectedPlane.marker.getGeometry().getCoordinates(); - var markerPosition = OLMap.getPixelFromCoordinate(markerCoordinates); - - // Get info box position and size - var infoBox = $('#selected_infoblock'); - var infoBoxPosition = infoBox.position(); - if (typeof infoBoxOriginalPosition.top === 'undefined') { - infoBoxOriginalPosition.top = infoBoxPosition.top; - infoBoxOriginalPosition.left = infoBoxPosition.left; - } else { - infoBox.css("left", infoBoxOriginalPosition.left); - infoBox.css("top", infoBoxOriginalPosition.top); - infoBoxPosition = infoBox.position(); - } - var infoBoxExtent = getExtent(infoBoxPosition.left, infoBoxPosition.top, infoBox.outerWidth(), infoBox.outerHeight()); - + var markerPosition = OLMap.getPixelFromCoordinate(markerCoordinates); + // Get map size var mapCanvas = $('#map_canvas'); var mapExtent = getExtent(0, 0, mapCanvas.width(), mapCanvas.height()); diff --git a/public_html/style.css b/public_html/style.css index e1af4db..e8777fc 100644 --- a/public_html/style.css +++ b/public_html/style.css @@ -1,4 +1,5 @@ html, body { + -ms-overflow-style: -ms-autohiding-scrollbar; margin: 0; padding: 0; background-color: #ffffff; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 10pt; overflow: auto; height: 100%; } @@ -9,15 +10,28 @@ html, body { } #selected_infoblock { - position: absolute; - left: 40px; - top: 60px; - min-width: 394px; - padding: 10px; + position: absolute; + bottom: 0; + margin: 0; + border-top: 1px solid #ccc; background: #ffffff; - box-shadow: 4px 4px 10px #444444; - cursor: pointer; - z-index: 9999; + width: 100%; + height: 400px; +} +.infoblock-container { + overflow: scroll; + height: 100%; +} +#sidebar_canvas { + padding: 10px; + overflow: scroll; +} +#sidebar_container { + display: flex; + flex-direction: column; + width: 500px; + left: 0 !important; + height: 100%; } #map_container { @@ -85,15 +99,9 @@ html, body { background-size: cover; } -#sidebar_container { - display: flex; - width: 500px; - left: 0 !important; -} - #splitter { - cursor: col-resize; + cursor: ew-resize; display: block; position: absolute; top: 125px; @@ -106,7 +114,26 @@ html, body { background-position: 0px; background-color: transparent; border: none; - background-image: url("images/column-adjust.png"); + background-image: url("images/toggle-width@2x.png"); + background-size: cover; +} + +#splitter-infoblock { + cursor: ns-resize; + display: inline-block; + position: absolute ; + top: 0px; + right: 0; + /* float: right; */ + margin-left: auto; + width: 24px; + height: 25px; + background-size: 24px 25px; + background-repeat: no-repeat; + background-position: 0px; + background-color: transparent; + border: none; + background-image: url("images/toggle-height@2x.png"); background-size: cover; } @@ -134,11 +161,7 @@ html, body { left: 10px !important; } -#sidebar_canvas { - flex: 1 1 auto; - padding: 10px; - overflow: scroll; -} + div#SpecialSquawkWarning { position: absolute; bottom: 25px; right: 430px; border: 2px solid red; background-color: #FFFFA3; opacity: 0.75; filter:alpha(opacity=75); padding: 5px; @@ -257,22 +280,33 @@ select.error, textarea.error, input.error { padding-right: 20px; } -.infoHeading -{ +.infoHeading { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 18px; + font-size: 12px; + font-weight: bold; + line-height: 16px; color: #002F5D; - color: rgb(0, 47, 93); } -.infoData -{ +.infoData { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 18px; + font-size: 12px; + line-height: 16px; color: #000000; - color: rgb(0, 0, 0); +} + +.sectionTitle { + width: 100%; + text-transform: uppercase; + color: #fff; + background: #002F5D; + font-size: 14px; + /* padding: 5px 20px; */ + /* margin-left: -10px; */ +} + +.section-title-content { + padding: 5px 20px; } .legend @@ -301,8 +335,7 @@ select.error, textarea.error, input.error { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px; - text-indent: 16px - color: #000000; + text-indent: 16px; color: rgb(0, 0, 0); } @@ -316,24 +349,6 @@ select.error, textarea.error, input.error { text-decoration: underline; } -.infoHeading -{ - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - line-height: 16px; - color: #666666; - color: rgb(102, 102, 102); -} - -.infoData -{ - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - line-height: 16px; - color: #000000; - color: rgb(0, 0, 0); -} - #header { width: 100%; height: 60px; @@ -471,12 +486,12 @@ select.error, textarea.error, input.error { .infoRowTitle { display: inline-block; - width: 50%; + /* width: 50%; */ } .infoRowContent { display: inline-block; - width: 40%; + /* width: 40%; */ } .infoRowFluid { @@ -487,6 +502,13 @@ select.error, textarea.error, input.error { padding-top: 10px; } +.infoRowLine { + width: 49%; + display: inline-block; + padding-top: 2px; + padding-bottom: 2px; +} + .removePadding { padding: 0; } @@ -517,7 +539,7 @@ select.error, textarea.error, input.error { .lightGreyBackground { background-color: #efefef; } - +/* .fourColumnSection1 { width: 20%; } @@ -532,7 +554,7 @@ select.error, textarea.error, input.error { .fourColumnSection4 { width: 20%; -} +} */ #dump1090_infoblock { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -655,6 +677,32 @@ select.error, textarea.error, input.error { outline: none; } +.bottom-container { + width: 100%; + margin-top: 8px; + padding: 40px 0px; + text-align: center; + background-color: #eee; +} +#selected_flightaware_link a { + background-color: #00a0e2; + color: white; + text-decoration: none; + padding: 10px; + border-radius: 4px; +} +.bottom-info-container { + padding-top: 10px; + padding-bottom: 10px; + text-align: center; + color: #002F5D; + line-height: 18px; +} + +.infoblock-container-small .infoRowFluid { + display: block; +} + /* Retina 2x images */ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .settingsCloseBox { @@ -672,9 +720,6 @@ select.error, textarea.error, input.error { .ol-zoom-in { background-image: url("images/zoom-in@2x.png"); } - #splitter { - background-image: url("images/column-adjust@2x.png"); - } #toggle_sidebar_button.show_sidebar { background-image: url("images/table-icon@2x.png"); } @@ -703,9 +748,6 @@ select.error, textarea.error, input.error { .ol-zoom-in { background-image: url("images/zoom-in@3x.png"); } - #splitter { - background-image: url("images/column-adjust@3x.png"); - } #toggle_sidebar_button.show_sidebar { background-image: url("images/table-icon@3x.png"); }