8
#include <glib/gprintf.h>
17
#include <sys/types.h>
18
#include <sys/socket.h>
19
#include <netinet/in.h>
20
#include <arpa/inet.h>
22
#include "gps_functions.h"
25
#include "tile_management.h"
26
#include "converter.h"
28
char * distance2scale(float distance, float *factor);
31
static GIOChannel *gpsd_io_channel =NULL;
33
static guint sid1, sid3;
41
printf("*** %s(): \n",__PRETTY_FUNCTION__);
43
global_reconnect_gpsd = TRUE;
44
g_source_remove(watchdog);
46
g_source_remove(sid1);
47
g_source_remove(sid3);
54
osd_speed(gboolean force_redraw)
56
PangoContext *context = NULL;
57
PangoLayout *layout = NULL;
58
PangoFontDescription *desc = NULL;
64
static int x = 10, y = 10;
65
static int width = 0, height = 0;
67
static double speed_tmp = 0;
73
if(gpsdata && mouse_dx == 0 && mouse_dy == 0)
75
switch (global_speed_unit)
81
unit_conv = 1.0/1.609344;
84
unit_conv = 1.0 / 1.852;
90
buffer = g_strdup_printf("%.0f", gpsdata->fix.speed*3.6*unit_conv);
93
context = gtk_widget_get_pango_context (map_drawable);
94
layout = pango_layout_new (context);
95
desc = pango_font_description_new();
97
pango_font_description_set_size (desc, 50 * PANGO_SCALE);
98
pango_layout_set_font_description (layout, desc);
99
pango_layout_set_text (layout, buffer, strlen(buffer));
102
gc = gdk_gc_new (map_drawable->window);
104
color.red = (gpsdata->fix.speed*3.6*unit_conv > 50) ? 0xffff : 0;
108
gdk_gc_set_rgb_fg_color (gc, &color);
115
if(speed_tmp != floor(gpsdata->fix.speed*3.6*unit_conv) || force_redraw)
119
map_drawable->window,
120
map_drawable->style->fg_gc[GTK_WIDGET_STATE (map_drawable)],
127
if(gpsdata->fix.speed>0.01 && gpsdata->valid)
128
gdk_draw_layout(map_drawable->window,
134
pango_layout_get_pixel_size(layout, &width, &height);
137
speed_tmp = floor(gpsdata->fix.speed*3.6*unit_conv);
140
pango_font_description_free (desc);
141
g_object_unref (layout);
148
static GtkLabel *label=NULL;
149
static gchar buffer[256];
150
int num_dl_threads = 0;
153
label = GTK_LABEL(lookup_widget(window1, "label4"));
155
num_dl_threads = update_thread_number(0);
156
if(num_dl_threads && !global_tiles_in_dl_queue)
159
"<b>no GPS found</b> - <span foreground='#0000ff'><b>D%d</b></span>",
162
else if (num_dl_threads && global_tiles_in_dl_queue)
164
"<b>no GPSD found</b> - <span foreground='#0000ff'><b>D%d</b></span> - <b>[%d]</b>",
165
num_dl_threads, global_tiles_in_dl_queue);
167
g_sprintf(buffer,"<b>no GPS found</b>");
170
gtk_label_set_label(label, buffer);
176
static GtkLabel *label=NULL, *label31, *label38, *label39;
177
static GtkLabel *label41, *label42, *label43, *label45;
178
static GtkLabel *label66, *label68, *label70;
179
static gchar buffer[256];
180
static gchar numdl_buf[64], dl_buf[64], ff_buf[64], tr_buf[64];
181
static gchar speedunit[5], distunit[3], altunit[3];
182
int trip_hours, trip_minutes, trip_seconds;
183
int num_dl_threads = 0;
186
double unit_conv = 1, unit_conv_alt = 1;
190
if(global_speed_unit==1)
192
unit_conv = 1.0/1.609344;
193
g_sprintf(speedunit, "%s","mph");
194
g_sprintf(distunit, "%s", "m");
196
else if(global_speed_unit==2)
198
unit_conv = 1.0/1.852;
199
g_sprintf(speedunit, "%s","kn");
200
g_sprintf(distunit, "%s", "NM");
204
g_sprintf(speedunit, "%s","km/h");
205
g_sprintf(distunit, "%s", "km");
209
if(global_alt_unit==1)
211
unit_conv_alt = 1.0/0.3048;
212
g_sprintf(altunit, "%s", "ft");
215
g_sprintf(altunit, "%s", "m");
217
if(global_auto_download)
218
g_sprintf(dl_buf, "%s", "");
220
g_sprintf(dl_buf, "%s", "<span foreground='#ff0000'><b>!</b></span>");
222
if (global_fftimer_running)
223
g_sprintf(ff_buf, "%s", "<span foreground='#00e000'><b>f</b></span>");
225
g_sprintf(ff_buf, "%s", "");
228
g_sprintf(tr_buf, "%s", "<span foreground='#00e000'><b>t</b></span>");
230
g_sprintf(tr_buf, "%s", "");
234
label = GTK_LABEL(lookup_widget(window1, "label4"));
235
label45 = GTK_LABEL(lookup_widget(window1, "label45"));
236
label41 = GTK_LABEL(lookup_widget(window1, "label41"));
237
label31 = GTK_LABEL(lookup_widget(window1, "label31"));
238
label38 = GTK_LABEL(lookup_widget(window1, "label38"));
239
label39 = GTK_LABEL(lookup_widget(window1, "label39"));
240
label42 = GTK_LABEL(lookup_widget(window1, "label42"));
241
label43 = GTK_LABEL(lookup_widget(window1, "label43"));
242
label66 = GTK_LABEL(lookup_widget(window1, "label66"));
243
label68 = GTK_LABEL(lookup_widget(window1, "label68"));
244
label70 = GTK_LABEL(lookup_widget(window1, "label70"));
251
num_dl_threads = update_thread_number(0);
253
if(num_dl_threads && !global_tiles_in_dl_queue)
254
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span> ",
256
else if (num_dl_threads && global_tiles_in_dl_queue)
257
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span>-%d ",
258
num_dl_threads, global_tiles_in_dl_queue);
260
g_sprintf(numdl_buf, "%s", "");
264
"%s%s%s%s<b>%4.1f</b> %s %.0f° a:%.0f%s t:%.3f%s %d/%d/%.1f",
269
gpsdata->fix.speed * 3.6 * unit_conv, speedunit,
270
gpsdata->fix.track * unit_conv,
271
gpsdata->fix.altitude * unit_conv_alt, altunit,
272
trip_distance * unit_conv, distunit,
273
gpsdata->satellites_inview,
274
gpsdata->satellites_used,
278
gtk_label_set_label(label, buffer);
285
time_sec = (time_t)gpsdata->fix.time;
286
ts = localtime(&time_sec);
289
strftime(buffer, sizeof(buffer), "%a %Y-%m-%d %H:%M:%S ", ts);
290
gtk_label_set_label(label41,buffer);
293
switch (global_latlon_unit)
296
g_sprintf(buffer, "%f - %f", gpsdata->fix.latitude, gpsdata->fix.longitude);
299
g_sprintf(buffer, "%s %s",
300
latdeg2latmin(gpsdata->fix.latitude),
301
londeg2lonmin(gpsdata->fix.longitude));
304
g_sprintf(buffer, "%s %s",
305
latdeg2latsec(gpsdata->fix.latitude),
306
londeg2lonsec(gpsdata->fix.longitude));
308
gtk_label_set_label(label31,buffer);
312
"<b><span foreground='#0000ff'><span font_desc='40'>%.1f</span></span></b> %s",
313
gpsdata->fix.speed*3.6*unit_conv, speedunit);
314
gtk_label_set_label(label38,buffer);
317
g_sprintf(buffer, "%.1f %s", gpsdata->fix.altitude * unit_conv_alt, altunit);
318
gtk_label_set_label(label39,buffer);
321
g_sprintf(buffer, "%.1f° ", gpsdata->fix.track);
322
gtk_label_set_label(label42,buffer);
325
g_sprintf(buffer, "%d/%d HDOP: %.1f ",
326
gpsdata->satellites_inview, gpsdata->satellites_used, gpsdata->hdop);
327
gtk_label_set_label(label43,buffer);
334
g_sprintf(buffer, "%.3f %s", trip_distance*unit_conv,distunit);
335
gtk_label_set_label(label45,buffer);
339
trip_hours = trip_time / 3600;
340
trip_minutes = ((int)trip_time%3600)/60;
341
trip_seconds = (int)trip_time % 60;
343
if (trip_seconds < 10 && trip_minutes < 10)
345
g_sprintf(buffer, " %d:0%d:0%d",trip_hours,trip_minutes,trip_seconds);
347
else if (trip_seconds < 10)
348
g_sprintf(buffer, " %d:%d:0%d",trip_hours,trip_minutes,trip_seconds);
349
else if (trip_minutes < 10)
350
g_sprintf(buffer, " %d:0%d:%d",trip_hours,trip_minutes,trip_seconds);
352
g_sprintf(buffer, " %d:%d:%d",trip_hours,trip_minutes,trip_seconds);
354
gtk_label_set_label(label66,buffer);
357
g_sprintf(buffer, " %.1f %s", trip_distance*3600*unit_conv/(trip_time+2.0), speedunit);
358
gtk_label_set_label(label68,buffer);
361
g_sprintf(buffer, " %.1f %s", trip_maxspeed*3.6*unit_conv, speedunit);
362
gtk_label_set_label(label70,buffer);
372
parse_nmea_rmc(char *nmea)
375
gchar lat_dec[3], lon_dec[4];
376
double lat_min, lat=0, lon_min,lon=0;
377
gchar hour[3],min[3],sec[3],year[3],month[3],day[3];
380
typedef struct tm tm_t;
382
static tm_t *tm = NULL;
384
if(!tm) tm = g_new0(tm_t,1);
386
array = g_strsplit(nmea,",",0);
388
while (array[i]) i++;
390
g_source_remove(watchdog);
391
watchdog = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE,10000,reset_gpsd_io,NULL,NULL);
398
if (strlen(array[1]) >= 6)
400
strncpy(hour, array[1],2);
402
strncpy(min, array[1]+2,2);
404
strncpy(sec, array[1]+4,2);
409
if (strlen(array[9]) == 6)
411
strncpy(day, array[9],2);
413
strncpy(month, array[9]+2,2);
415
strncpy(year, array[9]+4,2);
418
tm->tm_sec = atoi(sec);
419
tm->tm_min = atoi(min);
420
tm->tm_hour= atoi(hour);
421
tm->tm_mday= atoi(day);
422
tm->tm_mon = atoi(month)-1;
423
tm->tm_year= atoi(year)+100;
426
gpsdata->fix.time = (double) mktime(tm);
433
if (strlen(array[3]) >= 3)
435
strncpy(lat_dec, array[3], 2);
437
lat_min = atof(array[3]+2);
438
lat = atof(lat_dec) + (lat_min/60);
439
if (strcmp(array[4],"S")==0)
446
if (strlen(array[5]) >= 4)
448
strncpy(lon_dec, array[5], 3);
450
lon_min = atof(array[5]+3);
451
lon = atof(lon_dec) + (lon_min/60);
452
if (strcmp(array[6],"W")==0)
459
gpsdata->valid = (strcmp(array[2],"A")==0) ? TRUE : FALSE;
463
gpsdata->seen_vaild = TRUE;
464
gpsdata->fix.latitude = lat;
465
gpsdata->fix.longitude = lon;
466
gpsdata->fix.speed = atof(array[7])*0.514444;
467
gpsdata->fix.track = atof(array[8]);
471
printf("%s(): YIKES. not enough fields. GPS receiver broken?\n",__PRETTY_FUNCTION__);
480
parse_nmea_gga(char *nmea)
486
array = g_strsplit(nmea,",",0);
498
gpsdata->satellites_used = atoi(array[7]);
502
gpsdata->hdop = atof(array[8]);
503
gpsdata->fix.altitude = atof(array[9]);
511
parse_nmea_gsv(char *nmea)
518
array = g_strsplit(nmea,",",0);
520
while (array[i]) i++;
526
gpsdata->satellites_inview = atoi(array[3]);
534
cb_gpsd_io_error(GIOChannel *src, GIOCondition condition, gpointer data)
536
printf("*** %s(): \n",__PRETTY_FUNCTION__);
539
g_source_remove(sid1);
540
g_source_remove(sid3);
549
cb_gpsd_data(GIOChannel *src, GIOCondition condition, gpointer data)
553
GError *error = NULL;
559
status = g_io_channel_read_line(
566
if(status == G_IO_STATUS_NORMAL)
569
if (strncmp(str_return,"$GPGSV",6)==0)
571
parse_nmea_gsv(str_return);
573
else if(strncmp(str_return,"$GPGGA",6)==0)
575
parse_nmea_gga(str_return);
577
else if (strncmp(str_return,"$GPRMC",6)==0)
579
parse_nmea_rmc(str_return);
588
printf("%s \n", error->message);
607
struct sockaddr_in server;
608
char buffer_send[] = "r";
611
if(!gpsdata || global_reconnect_gpsd)
613
printf("reconnecting to gpsd\n");
615
if (sock) sock = close(sock);
618
server.sin_family = AF_INET;
619
server.sin_addr.s_addr = inet_addr(global_server);
620
server.sin_port = htons (atoi(global_port));
621
memset(&(server.sin_zero), '\0', 8);
624
sock = socket(AF_INET, SOCK_STREAM, 0);
625
conn = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr));
628
fprintf(stderr, "connection to gpsd FAILED \n");
632
fprintf(stderr, "connection to gpsd SUCCEEDED \n");
634
global_reconnect_gpsd = FALSE;
638
gpsdata = g_new0(gps_data_t,1);
641
len = write(sock, buffer_send, strlen(buffer_send));
643
perror("ERROR writing to socket");
646
len = recv(sock, buffer, 500, 0);
650
fprintf(stderr, "Rcvd: %s",buffer);
655
watchdog = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE,10000,reset_gpsd_io,NULL,NULL);
658
gpsd_io_channel = g_io_channel_unix_new(sock);
659
g_io_channel_set_flags(gpsd_io_channel, G_IO_FLAG_NONBLOCK, NULL);
662
sid1 = g_io_add_watch_full(gpsd_io_channel, G_PRIORITY_HIGH_IDLE+200, G_IO_ERR | G_IO_HUP, cb_gpsd_io_error, NULL, NULL);
665
sid3 = g_io_add_watch_full(gpsd_io_channel, G_PRIORITY_HIGH_IDLE+200, G_IO_IN | G_IO_PRI, cb_gpsd_data, NULL, NULL);
681
printf("POLL ERROR \n");
687
else printf("NOGPS");
694
map_scale_indicator()
696
printf("%s():\n",__PRETTY_FUNCTION__);
703
int y, width, height, bar_length=200;
704
float distance, factor, lat, lon1, lon2;
707
static GdkGC *gc=NULL, *gc1=NULL;
709
PangoContext *context = NULL;
710
PangoLayout *layout = NULL;
711
PangoFontDescription *desc = NULL;
713
y = map_drawable->allocation.height - 8;
717
gc = gdk_gc_new(pixmap);
718
gc1 = gdk_gc_new(pixmap);
724
gdk_gc_set_rgb_fg_color(gc, &color);
725
gdk_gc_set_line_attributes(gc,
726
5, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
732
gdk_gc_set_rgb_fg_color(gc1, &color);
733
gdk_gc_set_line_attributes(gc1,
734
3, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
738
lat = pixel2lat(global_zoom, global_y+y);
739
lon1 = pixel2lon(global_zoom, 0);
740
lon2 = pixel2lon(global_zoom, 200);
742
distance = get_distance(lat, lon1, lat, lon2);
744
buffer = distance2scale(distance, &factor);
745
bar_length *= factor;
747
gdk_draw_line(map_drawable->window, gc, 4, y, bar_length+6, y);
748
gdk_draw_line(map_drawable->window, gc1,5, y, bar_length+5, y);
751
context = gtk_widget_get_pango_context (map_drawable);
752
layout = pango_layout_new (context);
753
desc = pango_font_description_new();
755
pango_font_description_set_size (desc, 9 * PANGO_SCALE);
756
pango_layout_set_font_description (layout, desc);
757
pango_layout_set_text (layout, buffer, strlen(buffer));
761
pango_layout_get_pixel_size(layout, &width, &height);
765
gdk_gc_set_line_attributes(gc,
766
height+2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
768
gdk_gc_set_line_attributes(gc1,
769
height, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
771
gdk_draw_line(map_drawable->window, gc1, 22, y-height/2+6, 20+width+6, y-height/2+6);
775
gdk_draw_layout(map_drawable->window,
783
pango_font_description_free (desc);
784
g_object_unref (layout);
791
distance2scale(float distance, float *factor)
797
switch (global_speed_unit)
801
strncpy(unit, "km", 3);
804
unit_conv = 1.0/1.609344;
805
strncpy(unit, "m", 2);
808
unit_conv = 1.0 / 1.852;
809
strncpy(unit, "NM", 3);
813
distance *= unit_conv;
814
if (distance >= 5000) {
815
buf = g_strconcat("5000", unit, NULL);
816
*factor = 5000/distance;
818
else if (distance < 5000 && distance >= 2000) {
819
buf = g_strconcat("2000", unit, NULL);
820
*factor = 2000/distance;
822
else if (distance < 2000 && distance >= 1000) {
823
buf = g_strconcat("1000", unit, NULL);
824
*factor = 1000/distance;
826
else if (distance < 1000 && distance >= 500) {
827
buf = g_strconcat("500", unit, NULL);
828
*factor = 500/distance;
830
else if (distance < 500 && distance >= 200) {
831
buf = g_strconcat("200", unit, NULL);
832
*factor = 200/distance;
834
else if (distance < 200 && distance >= 100) {
835
buf = g_strconcat("100", unit, NULL);
836
*factor = 100/distance;
838
else if (distance < 100 && distance >= 50) {
839
buf = g_strconcat("50", unit, NULL);
840
*factor = 50/distance;
842
else if (distance < 50 && distance >= 20) {
843
buf = g_strconcat("20", unit, NULL);
844
*factor = 20/distance;
846
else if (distance < 20 && distance >= 10) {
847
buf = g_strconcat("10", unit, NULL);
848
*factor = 10/distance;
850
else if (distance < 10 && distance >= 5) {
851
buf = g_strconcat("5", unit, NULL);
852
*factor = 5/distance;
854
else if (distance < 5 && distance >= 2) {
855
buf = g_strconcat("2", unit, NULL);
856
*factor = 2/distance;
858
else if (distance < 2 && distance >= 1) {
859
buf = g_strconcat("1", unit, NULL);
860
*factor = 1/distance;
862
else if(global_speed_unit == METRICAL)
864
if (distance < 1 && distance >= 0.5) {
865
buf = g_strdup("500m");
866
*factor = 0.5/distance;
868
else if (distance < 0.5 && distance >= 0.2) {
869
buf = g_strdup("200m");
870
*factor = 0.2/distance;
872
else if (distance < 0.2 && distance >= 0.1) {
873
buf = g_strdup("100m");
874
*factor = 0.1/distance;
876
else if (distance < 0.1 && distance >= 0.05) {
877
buf = g_strdup("50m");
878
*factor = 0.05/distance;
880
else if (distance < 0.05 && distance >= 0.02) {
881
buf = g_strdup("20m");
882
*factor = 0.02/distance;
885
buf = g_strdup("10m");
886
*factor = 0.01/distance;
889
else if(global_speed_unit == IMPERIAL)
892
if (distance >= 5000) {
893
buf = g_strdup("5000ft");
894
*factor = 5000/distance;
896
else if (distance < 5000 && distance >= 2000) {
897
buf = g_strdup("2000ft");
898
*factor = 2000/distance;
900
else if (distance < 2000 && distance >= 1000) {
901
buf = g_strdup("1000ft");
902
*factor = 1000/distance;
904
else if (distance < 1000 && distance >= 500) {
905
buf = g_strdup("500ft");
906
*factor = 500/distance;
908
else if (distance < 500 && distance >= 200) {
909
buf = g_strdup("200ft");
910
*factor = 200/distance;
913
buf = g_strdup("100ft");
914
*factor = 100/distance;
917
else if(global_speed_unit == NAUTICAL)
919
if (distance < 1 && distance >= 0.5) {
920
buf = g_strdup("0.5NM");
921
*factor = 0.5/distance;
923
else if (distance < 0.5 && distance >= 0.2) {
924
buf = g_strdup("0.2NM");
925
*factor = 0.2/distance;
927
else if (distance < 0.2 && distance >= 0.1) {
928
buf = g_strdup("0.1NM");
929
*factor = 0.1/distance;
931
else if (distance < 0.1 && distance >= 0.05) {
932
buf = g_strdup("0.05NM");
933
*factor = 0.05/distance;
935
else if (distance < 0.05 && distance >= 0.02) {
936
buf = g_strdup("0.02NM");
937
*factor = 0.02/distance;
940
buf = g_strdup("0.01NM");
941
*factor = 0.01/distance;
946
buf=g_strdup("bingo");