#include "mappix.h" #include #include #include #include #include #include #include #include "nmeap.h" #include "geo-tools.h" #define GPS_DEVICE "/dev/rfcomm0" struct iochandata { track_head *track; GtkWidget *dialog; GtkWidget *lat_label; GtkWidget *long_label; GtkWidget *nrpnt_label; gboolean end_record; gint nrpoints; nmeap_context_t nmeap; nmeap_gga_t gga; }; static gboolean gps_ch_inev (GIOChannel *source, GIOCondition condition, gpointer data) { struct iochandata *iodata = (struct iochandata *)data; GError *merr; static gchar buf[256], label[128]; gsize rread; gint offset, remain, status; trackdata *trackpoint; if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { /* something bad happened on the channel, close it */ g_message("error on gps_ch"); return FALSE; } merr = NULL; if (g_io_channel_read_chars (source, buf, 255, &rread, &merr) != G_IO_STATUS_NORMAL) return FALSE; // buf[255] = 0; if (rread == 0) return TRUE; // g_message("chan read %d", rread); /* FIXME: use nmeap.sf.net instead */ remain = rread; offset = 0; while (remain > 0) { status = nmeap_parseBuffer(&iodata->nmeap, &buf[offset], &remain); offset += (rread - remain); switch(status) { case NMEAP_GPGGA: g_message("found GPGGA message %.6f %.6f %.0f %lu %d %d %f %f\n", iodata->gga.latitude , iodata->gga.longitude, iodata->gga.altitude, iodata->gga.time, iodata->gga.satellites, iodata->gga.quality, iodata->gga.hdop, iodata->gga.geoid); if (iodata->gga.quality > 0) { if (iodata->gga.latitude > 360 || iodata->gga.longitude > 360) return TRUE; iodata->nrpoints++; //g_message("lat=%f long=%f %s, fixtype %d", iodata->nms->latitude, iodata->nms->longitude, iodata->nms->satsvalid ? "valid" : "not valid", iodata->nms->fixtype); #if 0 for (i=0; i<12; i++) { g_message("sat #%02d", i); g_message("\tin use:\t%s", iodata->nms->satellites[i].used ? "yes" : "no"); g_message("\tno#:\t%d", iodata->nms->satellites[i].number); g_message("\tele:\t%d", iodata->nms->satellites[i].elevation); g_message("\tazim:\t%d", iodata->nms->satellites[i].azimuth); g_message("\ts/n ratio:\t%d", iodata->nms->satellites[i].snratio); } #endif g_sprintf(label, "%d", iodata->nrpoints); gtk_label_set_text(GTK_LABEL(iodata->nrpnt_label), label); g_sprintf(label, "%f", iodata->gga.latitude); gtk_label_set_text(GTK_LABEL(iodata->lat_label), label); g_sprintf(label, "%f", iodata->gga.longitude); gtk_label_set_text(GTK_LABEL(iodata->long_label), label); trackpoint = (trackdata *)g_malloc(sizeof(trackdata)); latlon2unit(iodata->gga.latitude, iodata->gga.longitude, trackpoint->unitx, trackpoint->unity); trackpoint->elevation = iodata->gga.altitude; trackpoint->selected = FALSE; iodata->track->track = g_list_prepend(iodata->track->track, trackpoint); } break; case NMEAP_GPRMC: break; default: break; } } if (merr != NULL) g_error_free(merr); if (iodata->end_record) return FALSE; else return TRUE; } void do_record_track (mapwin *Mapper) { gint fd; GIOChannel *gps_ch; GtkWidget *dialog; GtkWidget *table, *w; GtkWidget *long_label; GtkWidget *lat_label; GtkWidget *nrpnt_label; gint evsrcid, res; struct iochandata iodata; #ifdef HILDON gtk_infoprintf(GTK_WINDOW(gtk_widget_get_toplevel(Mapper->mainwin)), "Connecting to GPS..."); while (gtk_events_pending()) gtk_main_iteration(); #endif fd = g_open(GPS_DEVICE, O_RDONLY | O_NONBLOCK); if (fd < 0) { return; } gps_ch = g_io_channel_unix_new(fd); dialog = gtk_dialog_new_with_buttons("Recording Track", GTK_WINDOW(gtk_widget_get_toplevel(Mapper->mainwin)), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_ADD, 1 /* response add */, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); table = gtk_table_new (2, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4); gtk_table_set_homogeneous(GTK_TABLE (table), TRUE); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, FALSE, FALSE, 0); w = gtk_label_new("Latitude"); gtk_label_set_use_markup(GTK_LABEL(w), TRUE); lat_label = gtk_label_new("-.-X"); gtk_table_attach_defaults (GTK_TABLE (table), w, 0, 1, 0, 1); gtk_table_attach_defaults (GTK_TABLE (table), lat_label, 1, 2, 0, 1); w = gtk_label_new("Longitude"); gtk_label_set_use_markup(GTK_LABEL(w), TRUE); long_label = gtk_label_new("-.-X"); gtk_table_attach_defaults (GTK_TABLE (table), w, 0, 1, 1, 2); gtk_table_attach_defaults (GTK_TABLE (table), long_label, 1, 2, 1, 2); w = gtk_label_new("points #"); gtk_label_set_use_markup(GTK_LABEL(w), TRUE); nrpnt_label = gtk_label_new("0"); gtk_table_attach_defaults (GTK_TABLE (table), w, 0, 1, 2, 3); gtk_table_attach_defaults (GTK_TABLE (table), nrpnt_label, 1, 2, 2, 3); gtk_widget_show_all(dialog); iodata.end_record = FALSE; iodata.nrpoints = 0; iodata.dialog = dialog; iodata.lat_label = lat_label; iodata.long_label = long_label; iodata.nrpnt_label = nrpnt_label; iodata.track = (track_head *)g_malloc(sizeof(track_head)); iodata.track->name = g_strdup("RecTrack"); iodata.track->show = TRUE; //nmea_parse_line("", &nms); if (nmeap_init(&iodata.nmeap, NULL) != 0) return; if (nmeap_addParser(&iodata.nmeap, "GPGGA", nmeap_gpgga, NULL, &iodata.gga) != 0) return; evsrcid = g_io_add_watch(gps_ch, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, gps_ch_inev, &iodata); do { res = gtk_dialog_run(GTK_DIALOG(dialog)); if (res == 1) { g_message("would add waypoint"); } } while (res == 1); /* anything than 1 will leave */ iodata.end_record = TRUE; g_io_channel_shutdown(gps_ch, FALSE, NULL); close(fd); track_add_new_to_main(Mapper, iodata.track); if (iodata.dialog != NULL) { gtk_widget_hide(iodata.dialog); gtk_widget_destroy(iodata.dialog); } } void on_record_track (GtkButton *widget, gpointer user_data) { mapwin *Mapper = (mapwin *)user_data; do_record_track(Mapper); }