@@ -269,6 +269,76 @@ var offline = {
269269var DEG_TO_RAD = Math . PI / 180.0 ;
270270var EARTH_RADIUS = 6371000.0 ;
271271
272+
273+ //Function to check if a file exists in the marker file list
274+ //useful for checking for files following the format {prefix}-{name}.{ext}, e.g. balloon-DH2LM.png
275+ function checkFileInList ( prefix , name , extension )
276+ {
277+ let fileName = prefix + "-" + name + "." + extension ;
278+
279+ if ( ajax_marker_filelist != null )
280+ {
281+ if ( ajax_marker_filelist . includes ( fileName ) )
282+ {
283+ console . log ( "File list includes filename " + fileName ) ;
284+ return true ;
285+ }
286+ else
287+ {
288+ console . log ( "File list does not include filename " + fileName ) ;
289+ return false ;
290+ }
291+ }
292+ else return false ;
293+ }
294+
295+
296+ function getMarkerList ( url )
297+ {
298+ //Create an XMLHttpRequest to get directory listing from Apache2
299+ var xhr = new XMLHttpRequest ( ) ;
300+
301+ //Specify the URL
302+ xhr . open ( 'GET' , url , false ) ;
303+
304+ //Send out the request
305+ xhr . send ( ) ;
306+
307+ //Read the received data
308+ //console.log(xhr.responseText);
309+ let rawData = xhr . responseText ;
310+ // console.log(rawData);
311+
312+ //Parse file names and tokenize them
313+ let fileList = parseDirectoryListing ( rawData ) ;
314+
315+ //Check, only for debugging
316+ // console.log(fileList.includes("balloon-DH2LM.png"));
317+
318+ return fileList ;
319+ }
320+
321+ //Function for extracting file names out of Apache2 directory listings
322+ function parseDirectoryListing ( rawList )
323+ {
324+ //Extract all hyperlinks
325+ let rawFileList = rawList . match ( / h r e f = " ( [ \. \_ \- \w \d ] + ) / g) ;
326+ // .map((x) => x.replace('href="', '')); // pull out the hrefs and clean up
327+ let fileList = rawFileList ;
328+
329+ //Remove all hrefs
330+ for ( var i = 0 ; i < fileList . length ; i ++ ) {
331+ let val = fileList [ i ] ;
332+ val = val . replace ( 'href="' , '' ) ;
333+ fileList [ i ] = val ;
334+ // console.log(val);
335+ }
336+
337+ // console.log(fileList);
338+ return fileList ;
339+ }
340+
341+
272342// calculates look angles between two points
273343// format of a and b should be {lon: 0, lat: 0, alt: 0}
274344// returns {elevention: 0, azimut: 0, bearing: "", range: 0}
@@ -1294,6 +1364,9 @@ function updateVehicleInfo(vcallsign, newPosition) {
12941364 vehicle . marker . setMode ( "parachute" ) ;
12951365 }
12961366
1367+ //Override for testing
1368+ //vehicle.marker.setMode("parachute");
1369+
12971370 // Update landing marker if data is available
12981371 if ( newPosition . data . hasOwnProperty ( "pred_lat" ) && newPosition . data . hasOwnProperty ( "pred_lon" ) ) {
12991372 // Landing prediction data exists..
@@ -2529,7 +2602,7 @@ function addPosition(position) {
25292602 vehicle_type = "balloon" ;
25302603 color_index = balloon_index ++ % balloon_colors . length ;
25312604
2532- if ( vcallsign == "DL24ENTE" ) image_src = host_url + markers_url + "balloon-ente .png" ;
2605+ if ( checkFileInList ( "balloon" , vcallsign , "png" ) ) image_src = host_url + markers_url + "balloon-" + vcallsign + " .png";
25332606 else image_src = host_url + markers_url + "balloon-" +
25342607 ( ( vcallsign == "PIE" ) ? "rpi" : balloon_colors_name [ color_index ] ) + ".png" ;
25352608 image_src_size = [ 46 , 84 ] ;
@@ -2577,7 +2650,9 @@ function addPosition(position) {
25772650
25782651 marker . shadow = marker_shadow ;
25792652 marker . balloonColor = ( vcallsign == "PIE" ) ? "rpi" : balloon_colors_name [ color_index ] ;
2580- marker . balloonColor = ( vcallsign == "DL24ENTE" ) ? "ente" : balloon_colors_name [ color_index ] ;
2653+ // marker.balloonColor = (checkFileInList("balloon", vcallsign, "png")) ? vcallsign : balloon_colors_name[color_index];
2654+ marker . balloonColor = vcallsign ;
2655+ marker . balloonAltColor = balloon_colors_name [ color_index ] ;
25812656 marker . mode = 'balloon' ;
25822657 marker . setMode = function ( mode ) {
25832658 if ( this . mode == mode ) return ;
@@ -2591,12 +2666,18 @@ function addPosition(position) {
25912666 map . removeLayer ( vehicle . horizon_circle_title ) ;
25922667 map . removeLayer ( vehicle . subhorizon_circle_title ) ;
25932668
2594- if ( this . balloonColor == "ente" )
2669+ //Provide an alternative color if there is no payload image
2670+ //Here custom payload images are designed to be slightly larger than original ones,
2671+ //So a fallback mechanism is implemented if there is no payload image.
2672+ var payloadImgExists = checkFileInList ( "payload" , vcallsign , "png" ) ;
2673+ var payloadColor = payloadImgExists ? vcallsign : this . balloonAltColor ;
2674+
2675+ if ( this . balloonColor == vcallsign )
25952676 img = new L . icon ( {
2596- iconUrl : host_url + markers_url + "payload-" + this . balloonColor + ".png" ,
2597- iconSize : [ 48 , 70 ] ,
2598- iconAnchor : [ 24 , 70 ] ,
2599- tooltipAnchor : [ 0 , - 20 ] ,
2677+ iconUrl : host_url + markers_url + "payload-" + payloadColor + ".png" ,
2678+ iconSize : ( payloadImgExists ? [ 30 , 37 ] : [ 17 , 18 ] ) ,
2679+ iconAnchor : ( payloadImgExists ? [ 15 , 33 ] : [ 8 , 14 ] ) ,
2680+ tooltipAnchor : ( payloadImgExists ? [ 0 , 10 ] : [ 0 , - 20 ] ) ,
26002681 } ) ;
26012682 else img = new L . icon ( {
26022683 iconUrl : host_url + markers_url + "payload-" + this . balloonColor + ".png" ,
@@ -2614,18 +2695,28 @@ function addPosition(position) {
26142695 map . addLayer ( vehicle . subhorizon_circle_title ) ;
26152696 }
26162697
2617- // mode = "parachute";
2698+ // this.mode = 'parachute';
2699+
2700+ //Provide an alternative color if there is no parachute image
2701+ let parachuteImgExists = checkFileInList ( "parachute" , vcallsign , "png" ) ;
2702+ var parachuteColor = parachuteImgExists ? vcallsign : this . balloonAltColor ;
2703+ parachuteColor = ( this . balloonColor == vcallsign ) ? parachuteColor : this . balloonColor ;
2704+
2705+ //Also provide an alternative color if there is no balloon image for some reason :)
2706+ let balloonImgExists = checkFileInList ( "balloon" , vcallsign , "png" ) ;
2707+ var balloonColor = balloonImgExists ? vcallsign : this . balloonAltColor ;
2708+ balloonColor = ( this . balloonColor == vcallsign ) ? balloonColor : this . balloonColor ;
26182709
26192710 if ( mode == "parachute" ) {
2620- img = new L . icon ( {
2621- iconUrl : host_url + markers_url + "parachute-" + this . balloonColor + ".png" ,
2711+ img = new L . icon ( {
2712+ iconUrl : host_url + markers_url + "parachute-" + parachuteColor + ".png" ,
26222713 iconSize : [ 46 , 84 ] ,
26232714 tooltipAnchor : [ 0 , - 98 ] ,
26242715 iconAnchor : [ 23 , 90 ] ,
26252716 } ) ;
26262717 } else {
26272718 img = new L . icon ( {
2628- iconUrl : host_url + markers_url + "balloon-" + this . balloonColor + ".png" ,
2719+ iconUrl : host_url + markers_url + "balloon-" + balloonColor + ".png" ,
26292720 iconSize : [ 46 , 84 ] ,
26302721 tooltipAnchor : [ 0 , - 98 ] ,
26312722 iconAnchor : [ 23 , 90 ] ,
@@ -3345,6 +3436,7 @@ var ajax_inprogress = false;
33453436var ajax_inprogress_single = false ;
33463437var ajax_inprogress_single_new = false ;
33473438var ajax_positions_first_update_complete = false ;
3439+ var ajax_marker_filelist = null ;
33483440
33493441function refresh ( ) {
33503442 if ( ajax_inprogress ) {
@@ -3368,6 +3460,9 @@ function refresh() {
33683460 setLongTimePeriods ( false ) ;
33693461 }
33703462
3463+ //Get current file list for the markers
3464+ ajax_marker_filelist = getMarkerList ( host_url + markers_url ) ;
3465+
33713466 ajax_positions = $ . ajax ( {
33723467 type : "GET" ,
33733468 url : newdata_url ,
0 commit comments