working on heatmaps
[kismet-logviewer.git] / logviewer / static / russ_map_panel.html
diff --git a/logviewer/static/russ_map_panel.html b/logviewer/static/russ_map_panel.html
new file mode 100644 (file)
index 0000000..c690883
--- /dev/null
@@ -0,0 +1,317 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>heat map</title>
+
+    <script src="js/jquery-3.1.0.min.js"></script>
+    <script src="js/chart.umd.js"></script>
+    <script src="js/js.storage.min.js"></script>
+    <script src="js/kismet.ui.theme.js"></script>
+
+    <link rel="stylesheet" type="text/css" href="css/font-awesome.min.css">
+    <link rel="stylesheet" href="css/leaflet.css" />
+    <link rel="stylesheet" type="text/css" href="css/jquery.jspanel.min.css" />
+    <link rel="stylesheet" type="text/css" href="css/Control.Loading.css" />
+
+    <script src="js/leaflet.js"></script>
+    <script src="js/Leaflet.MultiOptionsPolyline.min.js"></script>
+    <script src="js/Control.Loading.js"></script>
+    <script src="js/chroma.min.js"></script>
+
+    <script src="js/js.storage.min.js"></script>
+    <script src="js/kismet.utils.js"></script>
+    <script src="js/kismet.units.js"></script>
+
+    <script src="js/datatables.min.js"></script>
+    <script src="js/dataTables.scrollResize.js"></script>
+
+    <style>
+        :root {
+            --adsb-sidebar-background: white;
+            --adsb-sidebar-background-offset: #f9f9f9;
+        }
+
+        [data-theme="dark"] {
+            --adsb-sidebar-background: #222;
+            --adsb-sidebar-background-offset: #444;
+            --map-tiles-filter: brightness(0.6) invert(1) contrast(3) hue-rotate(200deg) saturate(0.3) brightness(0.7);
+        }
+
+        .map-tiles {
+            filter: var(--map-tiles-filter, none);
+        }
+
+        body {
+            padding: 0;
+            margin: 0;
+        }
+
+        html, body, #map {
+            height: 100%;
+            font: 10pt "Helvetica Neue", Arial, Helvetica, sans-serif;
+        }
+
+        .marker-center {
+            margin: 0;
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            -ms-transform: translate(-50%, -50%);
+            transform: translate(-50%, -50%);
+        }
+
+        .right-sidebar {
+            position: absolute;
+            top: 10px;
+            bottom: 10px;
+            right: 10px;
+            width: 20%;
+            border: 1px solid black;
+            background: var(--adsb-sidebar-background);
+            z-index: 999;
+            padding: 10px;
+        }
+
+        .warning {
+            position: absolute;
+            top: 10%;
+            bottom: 10%;
+            right: 25%;
+            left: 25%;
+            border: 1px solid black;
+            background: var(--adsb-sidebar-background);
+            z-index: 10000;
+            padding: 10px;
+        }
+
+        #alt_scale {
+            width: 50%;
+            position: absolute;
+            bottom: 10px;
+            left: 25%;
+            height: 15px;
+            z-index: 999;
+            border: 1px solid black;
+            padding-left: 10px;
+            padding-right: 10px;
+            background: linear-gradient(to right, 
+                hsl(50,100%,50%), 
+                hsl(100,100%,50%), 
+                hsl(150,100%,50%), 
+                hsl(200,100%,50%), 
+                hsl(250,100%,50%), 
+                hsl(300,100%,50%), 
+                hsl(360,100%,50%));
+            text-align: center;
+        }
+
+        #alt_min {
+            position: absolute;
+            left: 10px;
+        }
+
+        #alt_mini {
+            position: absolute;
+            left: 25%;
+        }
+
+        #alt_maxi {
+            position: absolute;
+            left: 75%;
+        }
+
+        #alt_max {
+            position: absolute;
+            right: 10px;
+        }
+
+        #alt_title {
+            display: inline-block;
+        }
+
+        .resize_wrapper {
+            position: relative;
+            box-sizing: border-box;
+            height: calc(100% - 125px);
+            padding: 0.5em 0.5em 1.5em 0.5em;
+            border-radius: 0.5em;
+            background: var(--adsb-sidebar-background-offset);
+            overflow: hidden;
+        }
+
+    </style>
+</head>
+<body>
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
+    <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
+    <script src="/js/leaflet-heat.js"></script>
+
+    <div id="warning" class="warning">
+        <p><b>Warning!</b>
+        <p>To display the Russ map, your browser will connect to the Leaflet and Open Street Map servers to fetch the map tiles.  This requires you have a functional Internet connection, and will reveal something about your location (the bounding region where planes have been seen.)
+        <p><input id="dontwarn" type="checkbox">Don't warn me again</input>
+        <p><button id="continue">Continue</button>
+    </div>
+    <div id="map"></div>
+
+    <script>
+        units = 'i';
+
+        if (kismet.getStorage('kismet.base.unit.distance') === 'metric' ||
+            kismet.getStorage('kismet.base.unit.distance') === '')
+            units = 'm';
+
+        if (units === 'm') {
+            $('#alt_min').html("0m");
+            $('#alt_mini').html("3000m");
+            $('#alt_maxi').html("9000m");
+            $('#alt_max').html("12000m");
+        } else {
+            $('#alt_min').html("0ft");
+            $('#alt_mini').html("10000ft");
+            $('#alt_maxi').html("30000ft");
+            $('#alt_max').html("40000ft");
+        }
+
+
+        var window_visible = true;
+/*
+        // Visibility detection from https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
+        // Set the name of the hidden property and the change event for visibility
+        var hidden, visibilityChange; 
+        if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
+            hidden = "hidden";
+            visibilityChange = "visibilitychange";
+        } else if (typeof document.msHidden !== "undefined") {
+            hidden = "msHidden";
+            visibilityChange = "msvisibilitychange";
+        } else if (typeof document.webkitHidden !== "undefined") {
+            hidden = "webkitHidden";
+            visibilityChange = "webkitvisibilitychange";
+        }
+
+        function handleVisibilityChange() {
+            if (document[hidden]) {
+                window_visible = false;
+            } else {
+                window_visible = true;
+            }
+        }
+
+        // Warn if the browser doesn't support addEventListener or the Page Visibility API
+        if (typeof document.addEventListener === "undefined" || hidden === undefined) {
+            ; // Do nothing
+        } else {
+            // Handle page visibility change   
+            document.addEventListener(visibilityChange, handleVisibilityChange, false);
+        }
+*/
+        var urlparam = new URL(window.location.href);
+        var param_url = urlparam.searchParams.get('parent_url') + "/";
+        var param_prefix = urlparam.searchParams.get('local_uri_prefix', "");
+        var KISMET_PROXY_PREFIX = urlparam.searchParams.get('KISMET_PROXY_PREFIX', "");
+
+        if (param_prefix == 0)
+            param_prefix=""
+
+        var local_uri_prefix = param_url + param_prefix;
+        if (typeof(KISMET_URI_PREFIX) !== 'undefined')
+            local_uri_prefix = KISMET_URI_PREFIX;
+
+        var map_configured = false;
+
+        var markers = {};
+
+        var tid = -1;
+
+        var map = null;
+
+        function map_cb(d) {
+            data = kismet.sanitizeObject(d);
+           
+            if (!map_configured) {
+                var lat1 = data['kismet.wireless.map.min_lat'];
+                var lon1 = data['kismet.wireless.map.min_lon'];
+                var lat2 = data['kismet.wireless.map.max_lat'];
+                var lon2 = data['kismet.wireless.map.max_lon'];
+
+                map = L.map('map', {
+                    loadingControl: true
+                });
+                map.fitBounds([[lat1, lon1], [lat2, lon2]])
+                L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+                    maxZoom: 19,
+                    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
+                    className: 'map-tiles',
+                }).addTo(map);
+
+                map_configured = true;
+            }
+
+            //var prev_pos = {
+            //    'top': $(dt.settings()[0].nScrollBody).scrollTop(),
+            //    'left': $(dt.settings()[0].nScrollBody).scrollLeft()
+            //};
+
+           //console.log(data['kismet.wireless.map.devices'].length);
+           //console.log(data['kismet.wireless.map.devices']);
+           /*var locationPoints = [];
+            //for (var d = 0; d < data['kismet.wireless.map.devices'].length; d++) {
+            //    try {
+       //          var tmp = data['kismet.wireless.map.devices'][d];
+       //          //console.log(tmp);
+       //          locationPoints = locationPoints.concat(tmp);
+         //           //dt.row.add([icao, id, kismet_units.renderHeightDistanceUnitless(altitude, 0), kismet_units.renderSpeedUnitless(speed, 0, true), heading.toFixed(0), packets]);
+//
+ //               } catch (error) {
+  //                  ;
+   //             }
+//           }
+           //console.log(locationPoints);
+           //locationPoints = locationPoints.map(function (p) { return [p[0], p[1]]; });
+               */
+           var addressPoints = data['kismet.wireless.map.devices'];
+           addressPoints = addressPoints.map(function (p) { return [p[1], p[0]]; });
+           var heat = L.heatLayer(addressPoints).addTo(map);
+           var window_visible = true;
+        }
+
+        var load_maps = kismet.getStorage('kismet.russ.maps_ok', false);
+
+        function poll_map() {
+            if (window_visible && !$('#map').is(':hidden') && load_maps) {
+                $.get(local_uri_prefix + KISMET_PROXY_PREFIX + "phy/RUSS/map_data.json")
+                    .done(function(d) {
+                        map_cb(d);
+                    });
+                    //.always(function(d) {
+                    //    tid = setTimeout(function() { poll_map(); }, 2000);
+                    //});
+            } else {
+                tid = setTimeout(function() { poll_map(); }, 2000);
+            }
+        }
+
+        // Set a global timeout
+        $.ajaxSetup({
+            timeout:5000,
+            xhrFields: {
+                withCredentials: true
+            }
+        });
+
+        if (load_maps)
+            $('#warning').hide();
+
+        $('#continue').on('click', function() {
+            if ($('#dontwarn').is(":checked"))
+                kismet.putStorage('kismet.russ.maps_ok', true);
+            $('#warning').hide();
+            load_maps = true;
+        });
+
+        poll_map();
+
+    </script>
+</body>
+</html>