211 lines
6 KiB
C
211 lines
6 KiB
C
![]() |
#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);
|
||
|
}
|