// DEPENDENCIES: moment.js, papaparse (for csv), lz-string (for compression) var LSkey_airports = "ol_airports" var LSkey_airports_lastupdate = "ol_airports-lastupdate" var Airports = new Map(); function loadAirports(){ if(!needUpdatingAirports()){ var airports_lsitem = localStorage.getItem(LSkey_airports) if(airports_lsitem){ Airports = new Map(JSON.parse( LZString.decompress(airports_lsitem))); if(Airports.size > 0) {return;} // map seemlingly has restored correctly, our work is done } } var airports_csv_url = "data/airports.csv"; Papa.parse(airports_csv_url, { download: true, header: true, skipEmptyLines: true, step: function(row) { row.data.forEach(function(tuple){ if(tuple.type == "closed" || tuple.name.toLowerCase().includes("marked as spam")) return; // ignore closed or spam airports tuple.name = tuple.name.replace(/\s*Airport/ig, '').trim(); // remove obvious occurrence of airport in airport names var airportMeta = { name: tuple.name, iso_country: tuple.iso_country, municipality: tuple.municipality }; if(tuple.iata_code){ Airports.set(tuple.iata_code, tuple.ident); // save space in Localstorage: only save metainfo once, if IATA code given, need to re-loopup using the icao code given in the value of the kv pair } if(tuple.ident){ Airports.set(tuple.ident, airportMeta); // ident=ICAO id of airport } }); }, complete: function(){ // persist map to LS localStorage.setItem(LSkey_airports, LZString.compress(JSON.stringify(Array.from(Airports.entries())))); localStorage.setItem(LSkey_airports_lastupdate, moment().toISOString()); // update "last updated" } }); } function needUpdatingAirports(){ var one_week_ago=moment().subtract(1,'week').toISOString(); var lastupdate=localStorage.getItem(LSkey_airports_lastupdate); if(lastupdate){ if(moment(lastupdate).isBefore(one_week_ago)){ return true; // data is too old } else { return false; // data is fetched less than one week ago } } else { return true; // no date stored, fetch data to be sure } } function resolveAirportById(iata_or_icao){ // since we store the meta info only for icao keys, we need to do indirection for IATA keys var airport_meta = Airports.get(iata_or_icao); var airport_icao = iata_or_icao; // by default, assume the parameter is already the ICAO if(typeof airport_meta === 'string'){ // value corr. to key is the icao code for the given IATA code airport_icao = airport_meta; // the value is our icao ID, so re-set the variable airport_meta = Airports.get(airport_icao); // lookup actual meta info to icao } if(airport_meta){ var municipalityAddition = ""; // if airport name already includes city name, don't add it, otherwise do if(!airport_meta.name.includes(airport_meta.municipality)){ municipalityAddition = ", "+airport_meta.municipality; } return { text: airport_meta.name+municipalityAddition, label: ''+airport_meta.name+municipalityAddition+'', applyFlag: function(htmlElement){ // set flag when it finished loading if($(htmlElement).hasClass("country-"+airport_meta.iso_country)) { return; // if flag hasn't changed, don't re-request via HTTP } $.ajax({ url: "flags/4x3/"+airport_meta.iso_country.toLowerCase()+".svg", success: function(rawsvg){ var svgElement = $(rawsvg); if(!svgElement.get(0).classList) return; // some error occurred fetching svg svgElement.get(0).classList.add("flag-icon"); // add class to new element (not possible via jquery) $(htmlElement).html(svgElement); // remove previous country class $(htmlElement).removeClass(function(i,c) { if(c){ return c.match(/country-\w+/gi).join(' '); } }); // add new country css attribute $(htmlElement).addClass("country-"+airport_meta.iso_country); // save country info in class attribute }, dataType: 'text' }); } } } else { return { label: "", applyFlag: function(htmlElement){ // remove svg $(htmlElement).html(""); // remove country class $(htmlElement).removeClass(function(i,c) { if(c){ return c.match(/country-\w+/gi).join(' '); } }); } } } }