@@ -28,6 +28,8 @@ var receivers = [];
2828var recovery_names = [ ] ;
2929var recoveries = [ ] ;
3030
31+ var launchPredictions = { } ;
32+
3133var launches = null ;
3234var receiverCanvas = null ;
3335
@@ -563,6 +565,34 @@ function load() {
563565 liveData ( ) ;
564566 } ;
565567
568+ L . NumberedDivIcon = L . Icon . extend ( {
569+ options : {
570+ iconUrl : host_url + markers_url + "marker_hole.png" ,
571+ number : '' ,
572+ shadowUrl : null ,
573+ iconSize : new L . Point ( 25 , 41 ) ,
574+ iconAnchor : new L . Point ( 13 , 41 ) ,
575+ popupAnchor : new L . Point ( 0 , - 33 ) ,
576+ className : 'leaflet-div-icon'
577+ } ,
578+
579+ createIcon : function ( ) {
580+ var div = document . createElement ( 'div' ) ;
581+ var img = this . _createImg ( this . options [ 'iconUrl' ] ) ;
582+ var numdiv = document . createElement ( 'div' ) ;
583+ numdiv . setAttribute ( "class" , "number" ) ;
584+ numdiv . innerHTML = this . options [ 'number' ] || '' ;
585+ div . appendChild ( img ) ;
586+ div . appendChild ( numdiv ) ;
587+ this . _setIconStyles ( div , 'icon' ) ;
588+ return div ;
589+ } ,
590+
591+ createShadow : function ( ) {
592+ return null ;
593+ }
594+ } ) ;
595+
566596 map . whenReady ( callBack ) ;
567597
568598 // animate-in the timebox,
@@ -609,6 +639,141 @@ function setTimeValue() {
609639 } , 100 ) ;
610640}
611641
642+ function launchSitePredictions ( times , station , marker ) {
643+ var popup = launches . getLayer ( marker ) . getPopup ( ) ;
644+ var popupContent = popup . getContent ( ) ;
645+ var popupContentSplit = popupContent . split ( "<button onclick='launchSitePredictions(" ) [ 0 ] ;
646+ popupContentSplit += "<img style='width:60px;height:20px' src='img/hab-spinner.gif' />" ;
647+ popup . setContent ( popupContentSplit ) ;
648+ if ( popupContent . includes ( "Delete</button>" ) ) {
649+ deletePredictions ( marker ) ;
650+ popupContent = popupContent . split ( "<button onclick='deletePredictions(" ) [ 0 ] ;
651+ }
652+ times = times . split ( "," ) ;
653+ position = station . split ( "," ) ;
654+ var now = new Date ( ) ;
655+ var count = 0 ;
656+ var day = 0 ;
657+ var dates = [ ] ;
658+ while ( count < 7 ) {
659+ for ( var i = 0 ; i < times . length ; i ++ ) {
660+ var date = new Date ( ) ;
661+ var time = times [ i ] . split ( ":" ) ;
662+ date . setUTCHours ( time [ 0 ] ) ;
663+ date . setUTCMinutes ( time [ 1 ] ) ;
664+ date . setSeconds ( 0 ) ;
665+ date . setMilliseconds ( 0 ) ;
666+ if ( date < now ) {
667+ date . setDate ( date . getDate ( ) + 1 ) ;
668+ }
669+ if ( day > 0 ) {
670+ date . setDate ( date . getDate ( ) + day ) ;
671+ }
672+ if ( count < 7 ) {
673+ dates . push ( date . toISOString ( ) . split ( '.' ) [ 0 ] + "Z" ) ;
674+ count += 1 ;
675+ }
676+ }
677+ day += 1 ;
678+ }
679+ var completed = 0 ;
680+ for ( var i = 0 ; i < dates . length ; i ++ ) {
681+ //var url = "http://predict.cusf.co.uk/api/v1/?launch_latitude=" + position[0] + "&launch_longitude=" + position[1] + "&launch_datetime=" + dates[i] + "&ascent_rate=5&burst_altitude=26000&descent_rate=6";
682+ var url = "https://api.v2.sondehub.org/tawhiri?launch_latitude=" + position [ 0 ] + "&launch_longitude=" + position [ 1 ] + "&launch_datetime=" + dates [ i ] + "&ascent_rate=5&burst_altitude=26000&descent_rate=6" ;
683+ showPrediction ( url ) . done ( handleData ) . fail ( handleError ) ;
684+ }
685+ function handleData ( data ) {
686+ completed += 1 ;
687+ plotPrediction ( data , dates , marker ) ;
688+ if ( completed == 7 ) {
689+ popupContent += "<button onclick='deletePredictions(" + marker + ")' style='margin-bottom:0;'>Delete</button>" ;
690+ popup . setContent ( popupContent ) ;
691+ }
692+ }
693+ function handleError ( error ) {
694+ completed += 1 ;
695+ console . log ( error ) ;
696+ if ( completed == 7 ) {
697+ popupContent += "<button onclick='deletePredictions(" + marker + ")' style='margin-bottom:0;'>Delete</button>" ;
698+ popup . setContent ( popupContent ) ;
699+ }
700+ }
701+ }
702+
703+ function plotPrediction ( data , dates , marker ) {
704+ if ( ! launchPredictions . hasOwnProperty ( marker ) ) {
705+ launchPredictions [ marker ] = { } ;
706+ }
707+ launchPredictions [ marker ] [ dates . indexOf ( data . request . launch_datetime ) + 1 ] = { } ;
708+ plot = launchPredictions [ marker ] [ dates . indexOf ( data . request . launch_datetime ) + 1 ] ;
709+
710+ ascent = data . prediction [ 0 ] . trajectory ;
711+ descent = data . prediction [ 1 ] . trajectory ;
712+ var predictionPath = [ ] ;
713+ for ( var i = 0 ; i < ascent . length ; i ++ ) {
714+ predictionPath . push ( [ ascent [ i ] . latitude , ascent [ i ] . longitude ] ) ;
715+ } ;
716+ for ( var x = 0 ; x < descent . length ; x ++ ) {
717+ predictionPath . push ( [ descent [ x ] . latitude , descent [ x ] . longitude ] ) ;
718+ } ;
719+ var burstPoint = ascent [ ascent . length - 1 ] ;
720+ var landingPoint = descent [ descent . length - 1 ] ;
721+
722+ plot . predictionPath = new L . polyline ( predictionPath , { color : 'red' } ) . addTo ( map ) ;
723+
724+ burstIconImage = host_url + markers_url + "balloon-pop.png" ;
725+
726+ burstIcon = new L . icon ( {
727+ iconUrl : burstIconImage ,
728+ iconSize : [ 20 , 20 ] ,
729+ iconAnchor : [ 10 , 10 ] ,
730+ } ) ;
731+
732+ plot . burstMarker = new L . marker ( [ burstPoint . latitude , burstPoint . longitude ] , {
733+ icon : burstIcon
734+ } ) . addTo ( map ) ;
735+
736+ var burstTime = new Date ( burstPoint . datetime ) ;
737+ var burstTooltip = "<b>Time: </b>" + burstTime . toLocaleString ( ) + "<br><b>Altitude: </b>" + Math . round ( burstPoint . altitude ) + "m" ;
738+ plot . burstMarker . bindTooltip ( burstTooltip , { offset : [ 5 , 0 ] } ) ;
739+
740+ plot . landingMarker = new L . marker ( [ landingPoint . latitude , landingPoint . longitude ] , {
741+ icon : new L . NumberedDivIcon ( { number : dates . indexOf ( data . request . launch_datetime ) + 1 } )
742+ } ) . addTo ( map ) ;
743+
744+ var landingTime = new Date ( landingPoint . datetime ) ;
745+ var landingTooltip = "<b>Time: </b>" + landingTime . toLocaleString ( ) ;
746+ plot . landingMarker . bindTooltip ( landingTooltip , { offset : [ 13 , - 28 ] } ) ;
747+ }
748+
749+ function showPrediction ( url ) {
750+ return $ . ajax ( {
751+ type : "GET" ,
752+ url : url ,
753+ dataType : "json" ,
754+ } ) ;
755+ }
756+
757+ function deletePredictions ( marker ) {
758+ if ( launchPredictions . hasOwnProperty ( marker ) ) {
759+ for ( var prediction in launchPredictions [ marker ] ) {
760+ if ( launchPredictions [ marker ] . hasOwnProperty ( prediction ) ) {
761+ for ( var object in launchPredictions [ marker ] [ prediction ] ) {
762+ if ( launchPredictions [ marker ] [ prediction ] . hasOwnProperty ( object ) ) {
763+ map . removeLayer ( launchPredictions [ marker ] [ prediction ] [ object ] ) ;
764+ }
765+ }
766+ }
767+ }
768+ }
769+ var popup = launches . getLayer ( marker ) . getPopup ( ) ;
770+ var popupContent = popup . getContent ( ) ;
771+ if ( popupContent . includes ( "Delete</button>" ) ) {
772+ popupContent = popupContent . split ( "<button onclick='deletePredictions(" ) [ 0 ] ;
773+ popup . setContent ( popupContent ) ;
774+ }
775+ }
776+
612777function showLaunchSites ( ) {
613778 if ( ! launches ) {
614779 launches = new L . LayerGroup ( ) ;
@@ -639,8 +804,12 @@ function showLaunchSites() {
639804 sondes = sondes . replace ( new RegExp ( "\\b82\\b" ) , "LMS6-1680 (possible to track)" ) ;
640805 sondes = sondes . replace ( new RegExp ( "\\b84\\b" ) , "iMet-54 (possible to track)" ) ;
641806 var marker = new L . circleMarker ( latlon , { color : '#696969' , fillColor : "white" , radius : 8 } ) ;
807+ var popup = new L . popup ( { autoClose : false , closeOnClick : false } ) ;
808+ marker . bindPopup ( popup ) ;
809+ launches . addLayer ( marker ) ;
642810 if ( json [ key ] . hasOwnProperty ( 'times' ) ) {
643811 var tempDate = null ;
812+ var popupContent = null ;
644813 for ( var i = 0 ; i < json [ key ] [ 'times' ] . length ; i ++ ) {
645814 var date = new Date ( ) ;
646815 var now = new Date ( ) ;
@@ -654,20 +823,18 @@ function showLaunchSites() {
654823 if ( tempDate ) {
655824 if ( date < tempDate ) {
656825 tempDate = date ;
657- var popup = new L . popup ( { autoClose : false , closeOnClick : false } ) . setContent ( "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes +
658- "<br><b>Next launch:</b> " + date . toString ( ) ) ;
826+ popupContent = "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes + "<br><b>Next launch:</b> " + date . toString ( ) ;
659827 }
660828 } else {
661829 tempDate = date ;
662- var popup = new L . popup ( { autoClose : false , closeOnClick : false } ) . setContent ( "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes +
663- "<br><b>Next launch:</b> " + date . toString ( ) ) ;
830+ popupContent = "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes + "<br><b>Next launch:</b> " + date . toString ( ) ;
664831 }
665832 }
833+ popupContent += "<br><button onclick='launchSitePredictions(\"" + json [ key ] [ 'times' ] . toString ( ) + "\", \"" + latlon . toString ( ) + "\", \"" + launches . getLayerId ( marker ) + "\")' style='margin-bottom:0;'>Generate Predictions</button>" ;
666834 } else {
667- var popup = new L . popup ( { autoClose : false , closeOnClick : false } ) . setContent ( "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes ) ;
835+ popupContent = "<font style='font-size: 13px'>" + json [ key ] . station_name + "</font><br><br><b>Sondes launched:</b> " + sondes ;
668836 }
669- marker . bindPopup ( popup ) ;
670- launches . addLayer ( marker ) ;
837+ popup . setContent ( popupContent ) ;
671838 }
672839 }
673840 } ) ;
0 commit comments