1let map = null; 2let counter = 0; 3 4 5if (document.getElementById('mapping')) { 6 var mapready = false; 7 8 map = new maplibregl.Map({ 9 container: 'mapping', 10 style: 11 'https://api.maptiler.com/maps/d3f8e681-0e41-41a6-8f76-cdedfd815c80/style.json?key=NHMDD0pKnaddnVUEIwn5', 12 center: [35, 0], 13 // zoom: 1, 14 minZoom: 1, 15 maxZoom: 8 16 }) 17 .addControl(new maplibregl.NavigationControl(), "top-right") 18 .addControl(new maplibregl.ScaleControl()); 19 20 // We create 6 total layers (3 for AC, 3 for NetVar). This is the structure of the dots and how they have opacity and zoom values assigned to enable map zooming. Note that the layers also have data sources assigned as strings. Be aware that stringified item source may make debugging difficult. 21 // When the map is ready but there is no data (currently line 115) we do two main things: 22 // Add data sources to the map (currently lines 118 and 122) assigned to the JSON objects stored in memory. 23 // Add the previously created layer objects to the map in the correct order. 24 // From there, we just hit the database again every 35 seconds and reset the data sources for the two sets of layers. 25 let ac_layers = [ 26 { 27 'id': 'ac-layer-a', 28 'type': 'circle', 29 'source': 'item-source', 30 'maxzoom': 3, 31 'tooltipText': ['get', 'id'], 32 'paint': { 33 'circle-radius': 5, 34 'circle-color': ['get', 'fill-color'], 35 'circle-opacity': 0.5, 36 } 37 }, 38 { 39 'id': 'ac-layer-b', 40 'type': 'circle', 41 'source': 'item-source', 42 'minzoom': 3, 43 'maxzoom': 6, 44 'tooltipText': ['get', 'id'], 45 'paint': { 46 'circle-radius': 10, 47 'circle-color': ['get', 'fill-color'], 48 'circle-opacity': 0.5 49 } 50 }, 51 { 52 'id': 'ac-layer-c', 53 'type': 'circle', 54 'source': 'item-source', 55 'minzoom': 6, 56 'maxzoom': 15, 57 'tooltipText': ['get', 'id'], 58 'paint': { 59 'circle-radius': 15, 60 'circle-color': ['get', 'fill-color'], 61 'circle-opacity': 0.5 62 } 63 } 64 ]; 65 66 let group_layers = [ 67 { 68 id: 'group-circle-a', 69 type: 'circle', 70 source: 'group-source', 71 maxzoom: 4, 72 paint: { 73 'circle-radius': 20, 74 'circle-stroke-width': 1, 75 'circle-stroke-color': ['get', 'fill-color'], 76 'circle-color': ['get', 'fill-color'], 77 'circle-opacity': 0.3 78 } 79 }, 80 { 81 id: 'group-circle-b', 82 type: 'circle', 83 source: 'group-source', 84 minzoom: 4, 85 maxzoom: 8, 86 paint: { 87 'circle-radius': 75, 88 'circle-stroke-width': 2, 89 'circle-stroke-color': ['get', 'fill-color'], 90 'circle-color': ['get', 'fill-color'], 91 'circle-opacity': 0.2 92 } 93 }, 94 { 95 id: 'group-circle-c', 96 type: 'circle', 97 source: 'group-source', 98 minzoom: 8, 99 maxzoom: 14, 100 paint: { 101 'circle-radius': 150, 102 'circle-stroke-width': 2, 103 'circle-stroke-color': ['get', 'fill-color'], 104 'circle-color': ['get', 'fill-color'], 105 'circle-opacity': 0.1 106 } 107 } 108 ]; 109 110 map.on('load', () => { 111 mapready = true; 112 }); 113 114 var maptimer = setInterval(() => { 115 // Checking that the map is ready and both geoGrpData and geoACData data has been populated 116 if (mapready && geoGrpData.features.length != 0 && geoACData.features.length != 0) { 117 // This should execute once when the system is ready and then not run again 118 clearInterval(maptimer); 119 map.addSource('group-source', { 120 'type': 'geojson', 121 'data': geoGrpData 122 }); 123 map.addSource('item-source', { 124 'type': 'geojson', 125 'data': geoACData 126 }); 127 map.addLayer(group_layers[0]);
128 map.addLayer(group_layers[1]); 129 map.addLayer(group_layers[2]); 130 map.addLayer(ac_layers[0]); 131 map.addLayer(ac_layers[1]); 132 map.addLayer(ac_layers[2]); 133 134 const popup = new maplibregl.Popup({ 135 closeButton: false, 136 closeOnClick: false 137 }); 138 139 map.on('mouseenter', 'ac-layer-c', (e) => { 140 // Change the cursor style as a UI indicator. 141 map.getCanvas().style.cursor = 'pointer'; 142 143 const coordinates = e.features[0].geometry.coordinates.slice(); 144 const description = e.features[0].properties.description; 145 146 // Ensure that if the map is zoomed out such that multiple 147 // copies of the feature are visible, the popup appears 148 // over the copy being pointed to. 149 while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) { 150 coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360; 151 } 152 153 // Populate the popup and set its coordinates 154 // based on the feature found. 155 popup.setLngLat(coordinates).setHTML(description).addTo(map); 156 }); 157 158 map.on('mouseleave', 'ac-layer-c', () => { 159 map.getCanvas().style.cursor = ''; 160 popup.remove(); 161 }); 162 163 } 164 }, 500); 165} 166 167var geoACData = { 168 'type': 'FeatureCollection', 169 'features': [] 170}; 171 172var geoGrpData = { 173 'type': 'FeatureCollection', 174 'features': [] 175}; 176 177function setACData() { 178 $.ajax({ 179 url: '/api/getgeogroupac', 180 type: 'GET', 181 headers: { 182 Authorization: bearer 183 }, 184 success: (serverdata) => { 185 geoACData = serverdata; 186 if (map) { 187 // console.log('map1: ', map); 188 document.getElementById('mapDevices').innerHTML = geoACData.features.length + ' Devices'; 189 if (map.getSource('item-source')) { 190 // console.log('updating ac') 191 map.getSource('item-source').setData(geoACData); 192 map.redraw(); 193 } 194 } 195 // console.log(serverdata); 196 } 197 }); 198}; 199 200function setGroupData() { 201 $.ajax({ 202 url: '/api/getgeogroupnetvar', 203 type: 'GET', 204 headers: { 205 Authorization: bearer 206 }, 207 success: (serverdata) => { 208 // Test the color refresh by cycling through R/G/B group dots 209 // let clr1 = 'rgba(255,0,0,255)'; 210 // let clr2 = 'rgba(0,255,0,255)'; 211 // let clr3 = 'rgba(0,0,255,255)'; 212 // let clr = null; 213 // switch (counter) { 214 // case 0: 215 // clr = clr1; 216 // counter++; 217 // break; 218 // case 1: 219 // clr = clr2; 220 // counter++; 221 // break; 222 // case 2: 223 // clr = clr3; 224 // counter = 0; 225 // break; 226 // } 227 // serverdata.features.forEach(el => { 228 // el.properties['fill-color'] = clr; 229 // }); 230 geoGrpData = serverdata; 231 if (map) { 232 document.getElementById('mapClusters').innerHTML = geoGrpData.features.length + ' Clusters'; 233 // console.log('map2: ', map); 234 if (map.getSource('group-source')) { 235 map.getSource('group-source').setData(geoGrpData); 236 map.redraw(); 237 } 238 } 239 } 240 }); 241}; 242 243setInterval(() => { 244 setACData(); 245 setGroupData(); 246}, 35000); 247 248setACData(); 249setGroupData(); 250 251
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.