I have written a JavaScript code (I just got started) which queries the Opensky REST API every 10 seconds. After I collect the data, I plot it through Leaflet.js. For each item I add a popup text box which opens when I click on the tooltip. So far the code works great!
Here is the code so you can play around:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=\, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="id=edge">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin="">
</script>
<style>
#openskyMap {
height: 800px;
width:1200px;
}
</style>
<title>
"FETCH JSON from API and map lat lon"
</title>
</head>
<body>
<h1>Where are the flights</h1>
<p>Last Update (UNIX time): <span id="ts"></span></p>
<div id="openskyMap"></div>
/* JAVASCRIPT CODE BEGINS HERE */
<script>
/* DEFINE OPENSKY API URL */
var opensky_url = "https://opensky-network.org/api/states/all?time=TIME";
/* INITIATE LEAFLET MAP */
const mymap = L.map('openskyMap').setView([45, 0], 3);
const attribution = '© <a href="https://www.openstreetmap.org/copyright">OpenStreatMap</a> contributors'
const tileUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const tiles = L.tileLayer(tileUrl, {attribution});
var layerGroup = L.layerGroup().addTo(mymap);
tiles.addTo(mymap);
/* CHANGE ICON SIZE BASED ON ZOOM */
mymap.on('zoomend', function(e) {
var currentZoom = mymap.getZoom();
console.log("Current Zoom" + " " + currentZoom);
if (currentZoom >= 10) {
damsRadius = 100;
} else {
damsRadius = 20000;
}
});
/* FUNCTION TO GET THE ICAO24 CODE. I CANNOT GET IT OUT OF HERE THOUGH! */
function getIcao24(e) {
var popup = e.target.getPopup();
var content = popup.getContent();
console.log(content)
return content
}
/* INITIATE QUERY FUNCTION */
async function getOpensky() {
/* CALCULATE UNIX TIME TO BE PASSED TO THE URL */
var ts = Math.round((new Date()).getTime() / 1000);
ts = ts.toString();
/* MAKE QUERY TO OPENSKY URL */
const response = await fetch(opensky_url.replace('TIME',ts));
const data = await response.json();
/* PLOT ITEMS TO MAP USING LEAFLET:js */
layerGroup.clearLayers();
for (var key in data.states) {
/* GET SINGLE ITEM FROM JSON */
const item = data.states[key];
try{
/* GET GEOGRAPHICAL COORDINATES*/
const lon = item[5];
const lat = item[6];
/* DEFINE POPUP TEXT TO BE DISPLAYED*/
const popupText = "<p>"+item[0] + " - " + item[1] + "<br/>Lat: " + lat.toFixed(2)+" / Lon: "+lon.toFixed(2)+"<br/>Epoch: "+ts+"</p>";
/* ADD ITEM TO THE MAP. CALL getICAO24 FUNCTION BUT I DON'T KNOW HOW TO SAVE THE OUTPUT*/
L.circle(L.latLng(
parseFloat(item[6]), // lon
parseFloat(item[5]) // lat
), damsRadius).addTo(layerGroup).bindPopup(popupText).on('click', getIcao24);
document.getElementById('ts').textContent = ts;
}
catch (e) {}
}
}
/* CALL FUNCTION FIRST TIME*/
getOpensky();
/* UPDATE FUNCTION EVERY 10 SECONDS */
setInterval(getOpensky, 10000);
</script>
</body>
</html>
Every time I click on an aircraft (item
), the popup window opens as expected. However, I would like to keep the selected popup text open even after the refresh has occurred (setInterval
every 10 seconds). This is not happening due to the fact that when I click on the tooltip, the output is only displayed on the console but not store anywhere to be somehow recognized during the next query.
I though that one possible solution is to add a function called getIcao24
which should return the popup text and get the unique icao24
code (item[0]
) from the string and then check when it appears in the next iteration and set the popup box as open. However I have no clue how to get such information out of the function.
Would you be able to suggest a smart and elegant way to achieve my goal, i.e. maintain the popup box of a clicked item open even after a refresh has occurred?