@@ -1509,6 +1509,11 @@ function showHysplit(callsign) {
15091509 for ( var prediction in vehicle [ "prediction_hysplit" ] ) {
15101510 map . addLayer ( vehicle [ "prediction_hysplit" ] [ prediction ] ) ;
15111511 }
1512+ for ( var prediction in vehicle [ "markers_hysplit" ] ) {
1513+ for ( var pred_hour in vehicle [ "markers_hysplit" ] [ prediction ] ) {
1514+ map . addLayer ( vehicle [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
1515+ }
1516+ }
15121517}
15131518
15141519function hideHysplit ( callsign ) {
@@ -1517,33 +1522,51 @@ function hideHysplit(callsign) {
15171522 for ( var prediction in vehicle [ "prediction_hysplit" ] ) {
15181523 map . removeLayer ( vehicle [ "prediction_hysplit" ] [ prediction ] ) ;
15191524 }
1525+ for ( var prediction in vehicle [ "markers_hysplit" ] ) {
1526+ for ( var pred_hour in vehicle [ "markers_hysplit" ] [ prediction ] ) {
1527+ map . removeLayer ( vehicle [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
1528+ }
1529+ }
15201530}
15211531
15221532function generateHysplit ( callsign ) {
15231533 hideHysplit ( callsign )
15241534 var vehicle = vehicles [ callsign ] ;
15251535 vehicle . prediction_hysplit_visible = true ;
1526- for ( var alt = - 1000 ; alt <= 1000 ; alt += 100 ) {
1527- createHysplit ( callsign , alt ) ;
1536+ alt_max = 1000 ;
1537+ alt_step = 100 ;
1538+ alt_min = alt_max * - 1 ;
1539+ for ( var alt = alt_min ; alt <= alt_max ; alt += alt_step ) {
1540+ alt_norm = ( alt + alt_max ) / ( alt_max * 2.0 ) ;
1541+ alt_color = ConvertRGBtoHex ( evaluate_cmap ( alt_norm , 'turbo' ) ) ;
1542+ createHysplit ( callsign , alt , alt_color ) ;
15281543 }
15291544}
15301545
1531- function createHysplit ( callsign , adjustment ) {
1546+ function createHysplit ( callsign , adjustment , alt_color ) {
1547+
15321548 var vehicle = vehicles [ callsign ] ;
15331549
15341550 var altitude = Math . round ( vehicle . curr_position . gps_alt ) + adjustment ;
15351551
1536- var startTime = new Date ( Date . parse ( vehicle . curr_position . gps_time . replace ( "Z" , "" ) ) ) ;
1537- //max is 8h back so need to catch is older
1552+ // Handle any instances where we ended up with a weird time format from the APRS gateway.
1553+ // This should not be an issue with any other
1554+ var vehicleStartTime = vehicle . curr_position . gps_time . replace ( "+00:00Z" , "Z" ) ;
1555+
1556+ var startTime = new Date ( Date . parse ( vehicleStartTime ) ) ;
1557+ //max is 6h back so need to catch if older
15381558 var nowTime = new Date ( ) ;
15391559 var timeDifference = nowTime - startTime ;
1540- if ( timeDifference > 28800000 ) {
1541- nowTime . setHours ( nowTime . getHours ( ) - 8 ) ;
1560+ // If last vehicle position is greater than 6 hours old,
1561+ // Set start time to now - 6 hours.
1562+ if ( timeDifference > 21600000 ) {
1563+ nowTime . setHours ( nowTime . getHours ( ) - 6 ) ;
15421564 startTime = nowTime ;
15431565 }
15441566 startTime = startTime . toISOString ( ) ;
15451567
1546- var endTime = new Date ( Date . parse ( vehicle . curr_position . gps_time . replace ( "Z" , "" ) ) ) ;
1568+ // Predict up to 84 hours ahead.
1569+ var endTime = new Date ( Date . parse ( vehicleStartTime ) ) ;
15471570 endTime . setHours ( endTime . getHours ( ) + 84 ) ;
15481571 endTime = endTime . toISOString ( ) ;
15491572
@@ -1565,7 +1588,13 @@ function createHysplit(callsign, adjustment) {
15651588 success : function ( data ) {
15661589 var start = new L . LatLng ( vehicle . curr_position . gps_lat , vehicle . curr_position . gps_lon ) ;
15671590 var path = [ start ] ;
1591+
1592+ start_hours = 0 ;
1593+ startDateTime = - 1 ;
1594+ startDateStr = "" ;
1595+
15681596 for ( let point in data . prediction [ 1 ] . trajectory ) {
1597+ // Create path for current prediction.
15691598 if ( data . prediction [ 1 ] . trajectory [ point ] . latitude > 180.0 ) {
15701599 var lat = data . prediction [ 1 ] . trajectory [ point ] . latitude - 360.0 ;
15711600 } else {
@@ -1578,8 +1607,46 @@ function createHysplit(callsign, adjustment) {
15781607 }
15791608 var position = new L . LatLng ( lat , lon ) ;
15801609 path . push ( position ) ;
1610+
1611+ // Now create a circle marker if we are at a unit of 4 hours after the start time.
1612+ if ( startDateTime === - 1 ) {
1613+ startDateTime = new Date ( Date . parse ( data . prediction [ 1 ] . trajectory [ point ] . datetime ) ) ;
1614+ startDateStr = data . prediction [ 1 ] . trajectory [ point ] . datetime ;
1615+ }
1616+
1617+ current_time = new Date ( Date . parse ( data . prediction [ 1 ] . trajectory [ point ] . datetime ) ) ;
1618+ current_hours = Math . round ( ( current_time - startDateTime ) / 3600000 ) ;
1619+ if ( current_hours >= ( start_hours + 4 ) ) {
1620+ // We are at a unit of 4 hours, make a circle marker with information about the current prediction time.
1621+ if ( vehicle . markers_hysplit . hasOwnProperty ( adjustment ) == false ) {
1622+ vehicle . markers_hysplit [ adjustment ] = { } ;
1623+ }
1624+
1625+ vehicle . markers_hysplit [ adjustment ] [ current_hours ] = new L . CircleMarker ( position ,
1626+ {
1627+ radius : 6 ,
1628+ fillOpacity : 1 ,
1629+ color : alt_color ,
1630+ }
1631+ ) . bindPopup (
1632+ "<B>Prediction Start Time:</B> " + startDateStr + "<BR><B>Prediction Start Altitude: </B>" + altitude + "<BR><B>Prediction Current time:</B> " + data . prediction [ 1 ] . trajectory [ point ] . datetime + " (+" + current_hours + " hrs)"
1633+ ) ;
1634+
1635+ if ( vehicle . prediction_hysplit_visible ) {
1636+ vehicle . markers_hysplit [ adjustment ] [ current_hours ] . addTo ( map ) ;
1637+ }
1638+
1639+ start_hours = current_hours ;
1640+ }
1641+
1642+
15811643 }
1582- vehicle . prediction_hysplit [ adjustment ] = new L . Wrapped . Polyline ( path ) ;
1644+ // Add the polyline to the map.
1645+ vehicle . prediction_hysplit [ adjustment ] = new L . Wrapped . Polyline ( path ,
1646+ {
1647+ 'color' :alt_color ,
1648+ }
1649+ ) ;
15831650 vehicle . prediction_hysplit_age = vehicle . curr_position . gps_time ;
15841651 if ( vehicle . prediction_hysplit_visible ) {
15851652 vehicle . prediction_hysplit [ adjustment ] . addTo ( map ) ;
@@ -2473,6 +2540,7 @@ function addPosition(position) {
24732540 prediction_hysplit : { } ,
24742541 prediction_hysplit_visible : false ,
24752542 prediction_hysplit_age : 0 ,
2543+ markers_hysplit : { } ,
24762544 ascent_rate : 0.0 ,
24772545 horizontal_rate : 0.0 ,
24782546 max_alt : parseFloat ( position . gps_alt ) ,
@@ -2543,6 +2611,11 @@ function addPosition(position) {
25432611 for ( var prediction in vehicle_info [ "prediction_hysplit" ] ) {
25442612 map . removeLayer ( vehicle_info [ "prediction_hysplit" ] [ prediction ] ) ;
25452613 }
2614+ for ( var prediction in vehicle_info [ "markers_hysplit" ] ) {
2615+ for ( var pred_hour in vehicle_info [ "markers_hysplit" ] [ prediction ] ) {
2616+ map . removeLayer ( vehicle_info [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
2617+ }
2618+ }
25462619 try {
25472620 for ( var p in vehicle_info . polyline ) {
25482621 map . removeLayer ( vehicle_info . polyline [ p ] ) ;
0 commit comments