mappix/mappix-trackrecord.c

211 lines
6 KiB
C
Raw Permalink Normal View History

#include "mappix.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#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("<b>Latitude</b>");
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("<b>Longitude</b>");
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("<b>points #</b>");
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);
}