@@ -73,6 +73,11 @@ void ground_track_create(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
7373 double t0 ; /* time when this_orbit starts */
7474 double t ;
7575 ssp_t * this_ssp ;
76+ double track_num ;
77+ double target_phase ;
78+ double prev_phase ;
79+ double total_phase ;
80+ gboolean wrap ;
7681
7782 sat_log_log (SAT_LOG_LEVEL_DEBUG ,
7883 _ ("%s: Creating ground track for %s" ),
@@ -83,76 +88,133 @@ void ground_track_create(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
8388
8489 /* get configuration parameters */
8590 this_orbit = sat -> orbit ;
86- max_orbit = sat -> orbit - 1 + mod_cfg_get_int (satmap -> cfgdata ,
87- MOD_CFG_MAP_SECTION ,
88- MOD_CFG_MAP_TRACK_NUM ,
89- SAT_CFG_INT_MAP_TRACK_NUM );
90-
91- sat_log_log (SAT_LOG_LEVEL_DEBUG ,
92- _ ("%s: Start orbit: %d" ), __func__ , this_orbit );
93- sat_log_log (SAT_LOG_LEVEL_DEBUG ,
94- _ ("%s: End orbit %d" ), __func__ , max_orbit );
95-
96- /* find the time when the current orbit started */
97-
98- /* Iterate backwards in time until we reach sat->orbit < this_orbit.
99- Use predict_calc from predict-tools.c as SGP/SDP driver.
100- As a built-in safety, we stop iteration if the orbit crossing is
101- more than 24 hours back in time.
102- */
103- t0 = satmap -> tstamp ; //get_current_daynum ();
104- /* use == instead of >= as it is more robust */
105- for (t = t0 ; (sat -> orbit == this_orbit ) && ((t + 1.0 ) > t0 ); t -= 0.0007 )
106- predict_calc (sat , qth , t );
107-
108- /* set it so that we are in the same orbit as this_orbit
109- and not a different one */
110- t += 2 * 0.0007 ;
111- t0 = t ;
112- predict_calc (sat , qth , t0 );
91+ track_num = mod_cfg_get_double (satmap -> cfgdata , MOD_CFG_MAP_SECTION ,
92+ MOD_CFG_MAP_TRACK_NUM ,
93+ SAT_CFG_DOUBLE_MAP_TRACK_NUM );
94+
95+ /* If number of orbits to draw is less than 2, we start the track 25% or an
96+ * orbit behind the satellites current position. Otherwise it starts at the
97+ * start of the orbit. */
98+ if (track_num < 2.0 )
99+ {
100+ /* Start a quarter of an orbit ago */
101+ if (sat -> phase <= 90.0 )
102+ {
103+ target_phase = sat -> phase + 360.0 - 90.0 ;
104+ wrap = TRUE;
105+ }
106+ else
107+ {
108+ target_phase = sat -> phase - 90.0 ;
109+ wrap = FALSE;
110+ }
111+ for (t = satmap -> tstamp ; (wrap && (sat -> phase <= 90.0 )) || (sat -> phase > target_phase ); t -= 0.0007 )
112+ predict_calc (sat , qth , t );
113+ t += 0.0007 ;
114+
115+ /* Move ahead user-defined number of orbits (or parts of) */
116+ prev_phase = sat -> phase ;
117+ total_phase = 0.0 ;
118+ while ((total_phase < 360.0 * track_num ) && (!decayed (sat )))
119+ {
120+ /* We use 30 sec time steps. If resolution is too fine, the
121+ line drawing routine will filter out unnecessary points
122+ */
123+ t += 0.00035 ;
124+ predict_calc (sat , qth , t );
125+ if (sat -> phase < prev_phase ) // have we wrapped?
126+ total_phase += sat -> phase + 360.0 - prev_phase ;
127+ else
128+ total_phase += sat -> phase - prev_phase ;
129+ prev_phase = sat -> phase ;
113130
114- sat_log_log (SAT_LOG_LEVEL_DEBUG ,
115- _ ("%s: T0: %f (%d)" ), __func__ , t0 , sat -> orbit );
131+ /* store this SSP */
132+ this_ssp = g_try_new (ssp_t , 1 );
133+ if (this_ssp == NULL )
134+ {
135+ sat_log_log (SAT_LOG_LEVEL_ERROR ,
136+ _ ("%s: MAYDAY: Insufficient memory for ground track!" ),
137+ __func__ );
138+ return ;
139+ }
116140
117- /* calculate (lat,lon) for the required orbits */
118- while ((sat -> orbit <= max_orbit ) &&
119- (sat -> orbit >= this_orbit ) && (!decayed (sat )))
141+ this_ssp -> lat = sat -> ssplat ;
142+ this_ssp -> lon = sat -> ssplon ;
143+ obj -> track_data .latlon =
144+ g_slist_prepend (obj -> track_data .latlon , this_ssp );
145+ }
146+ }
147+ else
120148 {
121- /* We use 30 sec time steps. If resolution is too fine, the
122- line drawing routine will filter out unnecessary points
123- */
124- t += 0.00035 ;
125- predict_calc (sat , qth , t );
149+ max_orbit = sat -> orbit - 1 + (long )track_num ;
150+
151+ sat_log_log (SAT_LOG_LEVEL_DEBUG ,
152+ _ ("%s: Start orbit: %d" ), __func__ , this_orbit );
153+ sat_log_log (SAT_LOG_LEVEL_DEBUG ,
154+ _ ("%s: End orbit %d" ), __func__ , max_orbit );
126155
127- /* store this SSP */
156+ /* find the time when the current orbit started */
128157
129- /* Note: g_slist_append() has to traverse the entire list to find the end, which
130- is inefficient when adding multiple elements. Therefore, we use g_slist_prepend()
131- and reverse the entire list when we are done.
158+ /* Iterate backwards in time until we reach sat->orbit < this_orbit.
159+ Use predict_calc from predict-tools.c as SGP/SDP driver.
160+ As a built-in safety, we stop iteration if the orbit crossing is
161+ more than 24 hours back in time.
132162 */
133- this_ssp = g_try_new (ssp_t , 1 );
163+ t0 = satmap -> tstamp ; //get_current_daynum ();
164+ /* use == instead of >= as it is more robust */
165+ for (t = t0 ; (sat -> orbit == this_orbit ) && ((t + 1.0 ) > t0 ); t -= 0.0007 )
166+ predict_calc (sat , qth , t );
167+
168+ /* set it so that we are in the same orbit as this_orbit
169+ and not a different one */
170+ t += 2 * 0.0007 ;
171+ t0 = t ;
172+ predict_calc (sat , qth , t0 );
173+
174+ sat_log_log (SAT_LOG_LEVEL_DEBUG ,
175+ _ ("%s: T0: %f (%d)" ), __func__ , t0 , sat -> orbit );
176+
177+ /* calculate (lat,lon) for the required orbits */
178+ while ((sat -> orbit <= max_orbit ) &&
179+ (sat -> orbit >= this_orbit ) && (!decayed (sat )))
180+ {
181+ /* We use 30 sec time steps. If resolution is too fine, the
182+ line drawing routine will filter out unnecessary points
183+ */
184+ t += 0.00035 ;
185+ predict_calc (sat , qth , t );
186+
187+ /* store this SSP */
188+
189+ /* Note: g_slist_append() has to traverse the entire list to find the end, which
190+ is inefficient when adding multiple elements. Therefore, we use g_slist_prepend()
191+ and reverse the entire list when we are done.
192+ */
193+ this_ssp = g_try_new (ssp_t , 1 );
194+
195+ if (this_ssp == NULL )
196+ {
197+ sat_log_log (SAT_LOG_LEVEL_ERROR ,
198+ _ ("%s: MAYDAY: Insufficient memory for ground track!" ),
199+ __func__ );
200+ return ;
201+ }
134202
135- if (this_ssp == NULL )
203+ this_ssp -> lat = sat -> ssplat ;
204+ this_ssp -> lon = sat -> ssplon ;
205+ obj -> track_data .latlon =
206+ g_slist_prepend (obj -> track_data .latlon , this_ssp );
207+
208+ }
209+
210+ /* log if there is a problem with the orbit calculation */
211+ if (sat -> orbit != (max_orbit + 1 ))
136212 {
137213 sat_log_log (SAT_LOG_LEVEL_ERROR ,
138- _ ("%s: MAYDAY: Insufficient memory for ground track! " ),
139- __func__ );
214+ _ ("%s: Problem computing ground track for %s " ),
215+ __func__ , sat -> nickname );
140216 return ;
141217 }
142-
143- this_ssp -> lat = sat -> ssplat ;
144- this_ssp -> lon = sat -> ssplon ;
145- obj -> track_data .latlon =
146- g_slist_prepend (obj -> track_data .latlon , this_ssp );
147-
148- }
149- /* log if there is a problem with the orbit calculation */
150- if (sat -> orbit != (max_orbit + 1 ))
151- {
152- sat_log_log (SAT_LOG_LEVEL_ERROR ,
153- _ ("%s: Problem computing ground track for %s" ),
154- __func__ , sat -> nickname );
155- return ;
156218 }
157219
158220 /* Reset satellite structure to eliminate glitches in single sat
@@ -313,6 +375,7 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
313375 guint start ;
314376 guint i , j , n , num_points ;
315377 guint32 col ;
378+ gboolean start_not_end ;
316379
317380 (void )sat ;
318381 (void )qth ;
@@ -327,6 +390,10 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
327390 MOD_CFG_MAP_SECTION ,
328391 MOD_CFG_MAP_TRACK_COL , SAT_CFG_INT_MAP_TRACK_COL );
329392
393+ /* Determine which end arrow heads should be drawn, depending on direction
394+ satellite is moving in, which is determined by its inclination. */
395+ start_not_end = sat -> tle .xincl > 90.0 ;
396+
330397 /* loop over each SSP */
331398 for (i = 0 ; i < n ; i ++ )
332399 {
@@ -375,6 +442,16 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
375442 CAIRO_LINE_CAP_SQUARE ,
376443 "line-join" ,
377444 CAIRO_LINE_JOIN_MITER ,
445+ "end-arrow" ,
446+ !start_not_end ,
447+ "start-arrow" ,
448+ start_not_end ,
449+ "arrow-length" ,
450+ 10.0 ,
451+ "arrow-tip-length" ,
452+ 8.0 ,
453+ "arrow-width" ,
454+ 8.0 ,
378455 NULL );
379456 goo_canvas_points_unref (gpoints );
380457 goo_canvas_item_model_lower (line , obj -> marker );
@@ -439,7 +516,13 @@ static void create_polylines(GtkSatMap * satmap, sat_t * sat, qth_t * qth,
439516 "stroke-color-rgba" , col ,
440517 "line-cap" , CAIRO_LINE_CAP_SQUARE ,
441518 "line-join" ,
442- CAIRO_LINE_JOIN_MITER , NULL );
519+ CAIRO_LINE_JOIN_MITER ,
520+ "end-arrow" , !start_not_end ,
521+ "start-arrow" , start_not_end ,
522+ "arrow-length" , 10.0 ,
523+ "arrow-tip-length" , 8.0 ,
524+ "arrow-width" , 8.0 ,
525+ NULL );
443526 goo_canvas_points_unref (gpoints );
444527 goo_canvas_item_model_lower (line , obj -> marker );
445528
0 commit comments