Skip to content

Commit 2903be6

Browse files
committed
Merge PR #194
1 parent 1482feb commit 2903be6

8 files changed

Lines changed: 465 additions & 81 deletions

src/config-keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
#define MOD_CFG_MAP_SHADOW_ALPHA "SHADOW_ALPHA"
115115
#define MOD_CFG_MAP_SHOWTRACKS "SHOWTRACKS"
116116
#define MOD_CFG_MAP_HIDECOVS "HIDECOVS"
117+
#define MOD_CFG_MAP_AUTO_GROUND_TRACK "AUTO_GROUND_TRACK"
117118

118119
/* polar view specific */
119120
#define MOD_CFG_POLAR_SECTION "POLAR"

src/gtk-sat-map-ground-track.c

Lines changed: 143 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/gtk-sat-map.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ static gboolean on_button_press(GooCanvasItem * item,
7777
static gboolean on_button_release(GooCanvasItem * item,
7878
GooCanvasItem * target,
7979
GdkEventButton * event, gpointer data);
80+
static void clear_auto_ground_tracks(gpointer key, gpointer val,
81+
gpointer data);
8082
static void clear_selection(gpointer key, gpointer val, gpointer data);
8183
static void load_map_file(GtkSatMap * satmap, float clon);
8284
static GooCanvasItemModel *create_canvas_model(GtkSatMap * satmap);
@@ -929,6 +931,8 @@ static gboolean on_button_release(GooCanvasItem * item,
929931
gint *catpoint = NULL;
930932
sat_map_obj_t *obj = NULL;
931933
guint32 col;
934+
sat_t *sat = NULL;
935+
gboolean auto_ground_track;
932936

933937
(void)target;
934938

@@ -949,6 +953,18 @@ static gboolean on_button_release(GooCanvasItem * item,
949953
}
950954
else
951955
{
956+
auto_ground_track = mod_cfg_get_bool(satmap->cfgdata,
957+
MOD_CFG_MAP_SECTION,
958+
MOD_CFG_MAP_AUTO_GROUND_TRACK,
959+
SAT_CFG_BOOL_MAP_AUTO_GROUND_TRACK);
960+
961+
if (auto_ground_track)
962+
{
963+
/* Clear auto-enabled ground trackss. */
964+
g_hash_table_foreach(satmap->obj, clear_auto_ground_tracks,
965+
satmap);
966+
}
967+
952968
obj->selected = !obj->selected;
953969

954970
if (obj->selected)
@@ -980,6 +996,23 @@ static gboolean on_button_release(GooCanvasItem * item,
980996
if (obj->oldrcnum == 2)
981997
g_object_set(obj->range2, "stroke-color-rgba", col, NULL);
982998

999+
if (auto_ground_track)
1000+
{
1001+
/* Create ground track for newly selected satellite. */
1002+
sat = SAT(g_hash_table_lookup(satmap->sats, catpoint));
1003+
if (sat != NULL)
1004+
{
1005+
if (!obj->showtrack)
1006+
{
1007+
obj->showtrack = TRUE;
1008+
/* create ground track */
1009+
ground_track_create(satmap, sat, satmap->qth, obj);
1010+
/* do not add to satmap->showtracks, that's just for
1011+
* sats where it has manually been enabled. */
1012+
}
1013+
}
1014+
}
1015+
9831016
/* clear other selections */
9841017
g_hash_table_foreach(satmap->obj, clear_selection, catpoint);
9851018
}
@@ -993,6 +1026,34 @@ static gboolean on_button_release(GooCanvasItem * item,
9931026
return TRUE;
9941027
}
9951028

1029+
/* Delete ground tracks that were automatically enabled for the selected
1030+
* satellite. */
1031+
1032+
static void clear_auto_ground_tracks(gpointer key, gpointer val, gpointer data)
1033+
{
1034+
GtkSatMap *satmap = GTK_SAT_MAP(data);
1035+
sat_map_obj_t *obj = SAT_MAP_OBJ(val);
1036+
sat_t *sat = NULL;
1037+
gint *catpoint = key;
1038+
1039+
if (obj->selected)
1040+
{
1041+
sat = SAT(g_hash_table_lookup(satmap->sats, catpoint));
1042+
if (sat != NULL)
1043+
{
1044+
/* If ground track was auto enabled, this sat will not be in
1045+
* showtracks hash table. Don't use value in hash table,
1046+
* just whether it exists */
1047+
if (!g_hash_table_lookup_extended(satmap->showtracks,
1048+
&(sat->tle.catnr), NULL, NULL))
1049+
{
1050+
obj->showtrack = FALSE;
1051+
ground_track_delete(satmap, sat, satmap->qth, obj, TRUE);
1052+
}
1053+
}
1054+
}
1055+
}
1056+
9961057
static void clear_selection(gpointer key, gpointer val, gpointer data)
9971058
{
9981059
gint *old = key;

src/mod-cfg-get-param.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,38 @@ gchar *mod_cfg_get_str(GKeyFile * f, const gchar * sec,
155155
return param;
156156
}
157157

158+
gdouble mod_cfg_get_double(GKeyFile * f, const gchar * sec, const gchar * key,
159+
sat_cfg_double_e p)
160+
{
161+
GError *error = NULL;
162+
gdouble param;
163+
164+
/* check whether parameter is present in GKeyFile */
165+
if (g_key_file_has_key(f, sec, key, NULL))
166+
{
167+
param = g_key_file_get_double(f, sec, key, &error);
168+
169+
if (error != NULL)
170+
{
171+
sat_log_log(SAT_LOG_LEVEL_WARN,
172+
_("%s: Failed to read double (%s)"),
173+
__func__, error->message);
174+
175+
g_clear_error(&error);
176+
177+
/* get a timeout from global config */
178+
param = sat_cfg_get_double(p);
179+
}
180+
}
181+
/* get value from sat-cfg */
182+
else
183+
{
184+
param = sat_cfg_get_double(p);
185+
}
186+
187+
return param;
188+
}
189+
158190
/**
159191
* \brief Load an integer list into a hash table that uses the
160192
* existinence of datain the hash as a boolean.

0 commit comments

Comments
 (0)