@@ -1554,6 +1554,11 @@ function showHysplit(callsign) {
15541554 for ( var prediction in vehicle [ "prediction_hysplit" ] ) {
15551555 map . addLayer ( vehicle [ "prediction_hysplit" ] [ prediction ] ) ;
15561556 }
1557+ for ( var prediction in vehicle [ "markers_hysplit" ] ) {
1558+ for ( var pred_hour in vehicle [ "markers_hysplit" ] [ prediction ] ) {
1559+ map . addLayer ( vehicle [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
1560+ }
1561+ }
15571562}
15581563
15591564function hideHysplit ( callsign ) {
@@ -1562,33 +1567,51 @@ function hideHysplit(callsign) {
15621567 for ( var prediction in vehicle [ "prediction_hysplit" ] ) {
15631568 map . removeLayer ( vehicle [ "prediction_hysplit" ] [ prediction ] ) ;
15641569 }
1570+ for ( var prediction in vehicle [ "markers_hysplit" ] ) {
1571+ for ( var pred_hour in vehicle [ "markers_hysplit" ] [ prediction ] ) {
1572+ map . removeLayer ( vehicle [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
1573+ }
1574+ }
15651575}
15661576
15671577function generateHysplit ( callsign ) {
15681578 hideHysplit ( callsign )
15691579 var vehicle = vehicles [ callsign ] ;
15701580 vehicle . prediction_hysplit_visible = true ;
1571- for ( var alt = - 1000 ; alt <= 1000 ; alt += 100 ) {
1572- createHysplit ( callsign , alt ) ;
1581+ alt_max = 1000 ;
1582+ alt_step = 100 ;
1583+ alt_min = alt_max * - 1 ;
1584+ for ( var alt = alt_min ; alt <= alt_max ; alt += alt_step ) {
1585+ alt_norm = ( alt + alt_max ) / ( alt_max * 2.0 ) ;
1586+ alt_color = ConvertRGBtoHex ( evaluate_cmap ( alt_norm , 'turbo' ) ) ;
1587+ createHysplit ( callsign , alt , alt_color ) ;
15731588 }
15741589}
15751590
1576- function createHysplit ( callsign , adjustment ) {
1591+ function createHysplit ( callsign , adjustment , alt_color ) {
1592+
15771593 var vehicle = vehicles [ callsign ] ;
15781594
15791595 var altitude = Math . round ( vehicle . curr_position . gps_alt ) + adjustment ;
15801596
1581- var startTime = new Date ( Date . parse ( vehicle . curr_position . gps_time . replace ( "Z" , "" ) ) ) ;
1582- //max is 8h back so need to catch is older
1597+ // Handle any instances where we ended up with a weird time format from the APRS gateway.
1598+ // This should not be an issue with any other
1599+ var vehicleStartTime = vehicle . curr_position . gps_time . replace ( "+00:00Z" , "Z" ) ;
1600+
1601+ var startTime = new Date ( Date . parse ( vehicleStartTime ) ) ;
1602+ //max is 6h back so need to catch if older
15831603 var nowTime = new Date ( ) ;
15841604 var timeDifference = nowTime - startTime ;
1585- if ( timeDifference > 28800000 ) {
1586- nowTime . setHours ( nowTime . getHours ( ) - 8 ) ;
1605+ // If last vehicle position is greater than 6 hours old,
1606+ // Set start time to now - 6 hours.
1607+ if ( timeDifference > 21600000 ) {
1608+ nowTime . setHours ( nowTime . getHours ( ) - 6 ) ;
15871609 startTime = nowTime ;
15881610 }
15891611 startTime = startTime . toISOString ( ) ;
15901612
1591- var endTime = new Date ( Date . parse ( vehicle . curr_position . gps_time . replace ( "Z" , "" ) ) ) ;
1613+ // Predict up to 84 hours ahead.
1614+ var endTime = new Date ( Date . parse ( vehicleStartTime ) ) ;
15921615 endTime . setHours ( endTime . getHours ( ) + 84 ) ;
15931616 endTime = endTime . toISOString ( ) ;
15941617
@@ -1610,7 +1633,13 @@ function createHysplit(callsign, adjustment) {
16101633 success : function ( data ) {
16111634 var start = new L . LatLng ( vehicle . curr_position . gps_lat , vehicle . curr_position . gps_lon ) ;
16121635 var path = [ start ] ;
1636+
1637+ start_hours = 0 ;
1638+ startDateTime = - 1 ;
1639+ startDateStr = "" ;
1640+
16131641 for ( let point in data . prediction [ 1 ] . trajectory ) {
1642+ // Create path for current prediction.
16141643 if ( data . prediction [ 1 ] . trajectory [ point ] . latitude > 180.0 ) {
16151644 var lat = data . prediction [ 1 ] . trajectory [ point ] . latitude - 360.0 ;
16161645 } else {
@@ -1623,8 +1652,46 @@ function createHysplit(callsign, adjustment) {
16231652 }
16241653 var position = new L . LatLng ( lat , lon ) ;
16251654 path . push ( position ) ;
1655+
1656+ // Now create a circle marker if we are at a unit of 4 hours after the start time.
1657+ if ( startDateTime === - 1 ) {
1658+ startDateTime = new Date ( Date . parse ( data . prediction [ 1 ] . trajectory [ point ] . datetime ) ) ;
1659+ startDateStr = data . prediction [ 1 ] . trajectory [ point ] . datetime ;
1660+ }
1661+
1662+ current_time = new Date ( Date . parse ( data . prediction [ 1 ] . trajectory [ point ] . datetime ) ) ;
1663+ current_hours = Math . round ( ( current_time - startDateTime ) / 3600000 ) ;
1664+ if ( current_hours >= ( start_hours + 4 ) ) {
1665+ // We are at a unit of 4 hours, make a circle marker with information about the current prediction time.
1666+ if ( vehicle . markers_hysplit . hasOwnProperty ( adjustment ) == false ) {
1667+ vehicle . markers_hysplit [ adjustment ] = { } ;
1668+ }
1669+
1670+ vehicle . markers_hysplit [ adjustment ] [ current_hours ] = new L . CircleMarker ( position ,
1671+ {
1672+ radius : 6 ,
1673+ fillOpacity : 1 ,
1674+ color : alt_color ,
1675+ }
1676+ ) . bindPopup (
1677+ "<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)"
1678+ ) ;
1679+
1680+ if ( vehicle . prediction_hysplit_visible ) {
1681+ vehicle . markers_hysplit [ adjustment ] [ current_hours ] . addTo ( map ) ;
1682+ }
1683+
1684+ start_hours = current_hours ;
1685+ }
1686+
1687+
16261688 }
1627- vehicle . prediction_hysplit [ adjustment ] = new L . Wrapped . Polyline ( path ) ;
1689+ // Add the polyline to the map.
1690+ vehicle . prediction_hysplit [ adjustment ] = new L . Wrapped . Polyline ( path ,
1691+ {
1692+ 'color' :alt_color ,
1693+ }
1694+ ) ;
16281695 vehicle . prediction_hysplit_age = vehicle . curr_position . gps_time ;
16291696 if ( vehicle . prediction_hysplit_visible ) {
16301697 vehicle . prediction_hysplit [ adjustment ] . addTo ( map ) ;
@@ -2518,6 +2585,7 @@ function addPosition(position) {
25182585 prediction_hysplit : { } ,
25192586 prediction_hysplit_visible : false ,
25202587 prediction_hysplit_age : 0 ,
2588+ markers_hysplit : { } ,
25212589 ascent_rate : 0.0 ,
25222590 horizontal_rate : 0.0 ,
25232591 max_alt : parseFloat ( position . gps_alt ) ,
@@ -2589,6 +2657,11 @@ function addPosition(position) {
25892657 for ( var prediction in vehicle_info [ "prediction_hysplit" ] ) {
25902658 map . removeLayer ( vehicle_info [ "prediction_hysplit" ] [ prediction ] ) ;
25912659 }
2660+ for ( var prediction in vehicle_info [ "markers_hysplit" ] ) {
2661+ for ( var pred_hour in vehicle_info [ "markers_hysplit" ] [ prediction ] ) {
2662+ map . removeLayer ( vehicle_info [ "markers_hysplit" ] [ prediction ] [ pred_hour ] ) ;
2663+ }
2664+ }
25922665 try {
25932666 for ( var p in vehicle_info . polyline ) {
25942667 map . removeLayer ( vehicle_info . polyline [ p ] ) ;
0 commit comments