backup commit, formerly hosted on now inaccessible CVS
70
Makefile
Normal file
|
@ -0,0 +1,70 @@
|
|||
#
|
||||
# Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
# prefix for installation and search path (like icons)
|
||||
PREFIX = /usr/local/
|
||||
|
||||
# for normal desktop GTK+
|
||||
CCFLAGS = -Wall -O2 -g
|
||||
GTKCFLAGS = `pkg-config --cflags gtk+-2.0`
|
||||
|
||||
SQLITECFLAGS = `pkg-config --cflags sqlite3`
|
||||
|
||||
CFLAGS = $(CCFLAGS) $(GTKCFLAGS) $(SQLITECFLAGS)
|
||||
|
||||
#CLDFLAGS =
|
||||
GTKLDFLAGS = `pkg-config --libs gtk+-2.0`
|
||||
|
||||
SQLITELDFLAGS = `pkg-config --libs sqlite3`
|
||||
|
||||
## for Maemo/Hildon
|
||||
#CCFLAGS = -Wall -Os -g -DHILDON
|
||||
#GTKCFLAGS = `pkg-config --cflags gtk+-2.0` `pkg-config --cflags dbus-1`
|
||||
|
||||
#CFLAGS = $(CCFLAGS) $(GTKCFLAGS)
|
||||
|
||||
##CLDFLAGS =
|
||||
#GTKLDFLAGS = `pkg-config --libs gtk+-2.0` -lhildonlgpl -losso
|
||||
|
||||
|
||||
|
||||
# no need to change anything below this line
|
||||
# ------------------------------------------
|
||||
|
||||
.SUFFIXES: .d .c
|
||||
|
||||
CFLAGS += -MD -DPREFIX=\"$(PREFIX)\"
|
||||
LDFLAGS = $(CLDFLAGS) $(GTKLDFLAGS) $(SQLITELDFLAGS)
|
||||
|
||||
MAPPIX_MEMBERS = mappix mappix-ui mappix-trackdraw mappix-gpxreader geo-dist \
|
||||
mappix-trackedit mappix-trackrecord nmeap01 mappix-fileio \
|
||||
mappix-waypoints
|
||||
SOURCES = $(patsubst %,%.c,$(MAPPIX_MEMBERS))
|
||||
OBJS = $(patsubst %,%.o,$(MAPPIX_MEMBERS))
|
||||
DEPS = $(patsubst %,%.d,$(MAPPIX_MEMBERS))
|
||||
|
||||
all: mappix
|
||||
|
||||
mappix: $(OBJS)
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d mappix
|
||||
|
||||
-include $(DEPS)
|
74
NOTES
Normal file
|
@ -0,0 +1,74 @@
|
|||
|
||||
|
||||
GIOChannel* g_io_channel_unix_new (int fd);
|
||||
g_io_channel_set_encoding() function with NULL
|
||||
GIOStatus g_io_channel_set_encoding (GIOChannel *channel,
|
||||
const gchar *encoding,
|
||||
GError **error);
|
||||
guint g_io_add_watch (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
GIOFunc func,
|
||||
gpointer user_data);
|
||||
gboolean (*GIOFunc) (GIOChannel *source,
|
||||
GIOCondition condition,
|
||||
gpointer data);
|
||||
FALSE for end watch
|
||||
|
||||
|
||||
Distance Point To Line:
|
||||
(for Peuker)
|
||||
|
||||
d = |v^^.r| = (|(x_2-x_1)(y_1-y_0)-(x_1-x_0)(y_2-y_1)|)
|
||||
/
|
||||
(sqrt((x_2-x_1)^2+(y_2-y_1)^2))
|
||||
|
||||
- Ausgleichskurve
|
||||
Ausgleichsrechnung
|
||||
Interpolation
|
||||
|
||||
* Peuker line simplification
|
||||
* auto-split tracks
|
||||
if track has "gaps" then split track into two tracks.
|
||||
A gap is when in a group of four points A, B, C, D the distance
|
||||
from A to B and C to D is about the same but B to C is "a lot" more.
|
||||
* spike filter
|
||||
calculate mean deviation of all points of one track, then
|
||||
delete all points that have deviation > delta,
|
||||
recalculate mean deviation and redo
|
||||
* mean of two tracks A, B
|
||||
for each point of track A calculate distance to
|
||||
track B and create a new point on a new track in the middle of the
|
||||
distance. Next do the same process for all point of track B.
|
||||
The new track lies in the middle between A and B.
|
||||
Requires component-wise distance function with direction, i.e. e.g.
|
||||
distance of point is x=-5 and y=3 to track.
|
||||
* merge of two tracks
|
||||
for each point of track A find nearest corresponding point on
|
||||
track B, then calculate the average between both points and record
|
||||
this as new track point
|
||||
Repeat this for each point of track B.
|
||||
Limit the averaging to a maximum distance.
|
||||
|
||||
|
||||
SQLite tables
|
||||
-------------
|
||||
tracks track headers (streets, boundaries, rivers, ...)
|
||||
idx pkey index
|
||||
tid track id, id common to all data points of one track
|
||||
name track-/streetname
|
||||
ttype track-/streettype
|
||||
latmin bbox latitude min
|
||||
lonmin
|
||||
latmax
|
||||
lonmax
|
||||
trackpts the actual track (all tracks combined in one table?)
|
||||
lat
|
||||
lon
|
||||
ele
|
||||
dtim
|
||||
nrsat
|
||||
hdop
|
||||
vdop
|
||||
pdop
|
||||
points POIs
|
||||
cities name, center location, "size"
|
39
README
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
Mappix
|
||||
========
|
||||
|
||||
Boilerplate:
|
||||
|
||||
Copyright (C) 2006,2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
|
||||
0. Introduction
|
||||
---------------
|
||||
|
||||
Mappix is a to-become street map editor.
|
||||
The idea is to record GPS data and edit and annotate the recorded tracks and
|
||||
waypoints later. The longterm goal is to create a community of contributors.
|
||||
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
GPX Specification
|
||||
http://www.topografix.com/GPX/1/1/
|
BIN
cities.db
Normal file
212
geo-dist.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* geo-dist
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Calculate distances on Earth surface given geogrphic locations
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "geo-dist.h"
|
||||
|
||||
// #define DEBUG
|
||||
|
||||
|
||||
/*
|
||||
* Earth models
|
||||
* Remember, Earth is not a simple ball ;)
|
||||
*/
|
||||
struct ellipse_s {
|
||||
char *name;
|
||||
double a;
|
||||
double invf;
|
||||
};
|
||||
|
||||
static struct ellipse_s ellipse[] = {
|
||||
{
|
||||
"WGS84",
|
||||
6378.137 / 1.852,
|
||||
298.257223563
|
||||
}, {
|
||||
"NAD27",
|
||||
6378.2064 / 1.852,
|
||||
294.9786982138
|
||||
}, {
|
||||
"International",
|
||||
6378.388 / 1.852,
|
||||
297.0
|
||||
}, {
|
||||
"Krasovsky",
|
||||
6378.245 / 1.852,
|
||||
298.3
|
||||
}, {
|
||||
"Bessel",
|
||||
6377.397155 / 1.852,
|
||||
299.1528
|
||||
}, {
|
||||
"WGS72",
|
||||
6378.135 / 1.852,
|
||||
298.26
|
||||
}, {
|
||||
"WGS66",
|
||||
6378.145 / 1.852,
|
||||
298.25
|
||||
}, {
|
||||
"FAI sphere",
|
||||
6371.0 / 1.852,
|
||||
1000000000.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* math helper
|
||||
*/
|
||||
#if 0
|
||||
double atan2(double y, double x)
|
||||
{
|
||||
double out=0.;
|
||||
|
||||
if (x < 0) {
|
||||
out = atan(y/x) + M_PI;
|
||||
} else
|
||||
if ((x > 0) && (y >= 0)) {
|
||||
out = atan(y/x);
|
||||
} else
|
||||
if ((x > 0) && (y < 0)) {
|
||||
out = atan(y/x) + 2. * M_PI;
|
||||
} else
|
||||
if ((x == 0) && (y > 0)) {
|
||||
out = M_PI / 2.;
|
||||
} else
|
||||
if ((x == 0) && (y < 0)) {
|
||||
out = 3. * M_PI / 2.;
|
||||
} else
|
||||
if ((x == 0) && (y == 0)) {
|
||||
out= 0.;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* glat1, glat2: geodetic latitude in radians, N positive
|
||||
* glon1, glon2: geodetic longitude in radians E positive
|
||||
* Coordinates in radians means
|
||||
* 50°50.32N ^= 50 degree, 50 minutes and 32 seconds
|
||||
* ^= 50 + (50 / 60) + (32 / 3600)
|
||||
* ^= 50.84222
|
||||
*
|
||||
* returns: distance in nm (nautical miles), factor of 1.852 gives km
|
||||
*/
|
||||
double dist_ell(double glat1, double glon1, double glat2, double glon2, EllipsoidType e_model)
|
||||
{
|
||||
double a = ellipse[e_model].a; // 6378.137/1.852
|
||||
double invf = ellipse[e_model].invf; // 298.257223563
|
||||
double f = 1. / invf;
|
||||
double r, tu1, tu2, cu1, su1, cu2, s1, b1, f1;
|
||||
double x, sx, cx, sy=0, cy=0, y=0, sa, c2a=0, cz=0, e=0, c, d;
|
||||
double EPS = 0.00000000005;
|
||||
double s;
|
||||
double l_iter=1;
|
||||
double MAXITER=100;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(" calc dist from %.04lf %.04lf to %.04lf %.04lf\n", glat1, glon1, glat2, glon2);
|
||||
#endif
|
||||
glat1 = (M_PI / 180.) * glat1;
|
||||
glon1 = (M_PI / 180.) * -1. * glon1;
|
||||
glat2 = (M_PI / 180.) * glat2;
|
||||
glon2 = (M_PI / 180.) * -1. * glon2;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Using ellipse model %s (%.04lf %.04lf)\n", ellipse[e_model].name, a, invf);
|
||||
printf(" calc dist from %.04lf %.04lf to %.04lf %.04lf\n", glat1, glon1, glat2, glon2);
|
||||
#endif
|
||||
|
||||
if ((glat1+glat2==0.) && (fabs(glon1-glon2)==M_PI)) {
|
||||
#ifdef DEBUG
|
||||
printf("Warning: Course and distance between antipodal points is undefined\n");
|
||||
#endif
|
||||
glat1=glat1+0.00001; // allow algorithm to complete
|
||||
}
|
||||
|
||||
if (glat1==glat2 && (glon1==glon2 || fabs(fabs(glon1-glon2)-2*M_PI) < EPS)) {
|
||||
#ifdef DEBUG
|
||||
printf("Points 1 and 2 are identical- course undefined\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = 1. - f;
|
||||
tu1 = r * tan (glat1);
|
||||
tu2 = r * tan (glat2);
|
||||
cu1 = 1. / sqrt (1. + tu1 * tu1);
|
||||
su1 = cu1 * tu1;
|
||||
cu2 = 1. / sqrt (1. + tu2 * tu2);
|
||||
s1 = cu1 * cu2;
|
||||
b1 = s1 * tu2;
|
||||
f1 = b1 * tu1;
|
||||
x = glon2 - glon1;
|
||||
d = x + 1.; // force one pass
|
||||
|
||||
while ((fabs(d - x) > EPS) && (l_iter < MAXITER)) {
|
||||
l_iter = l_iter + 1;
|
||||
sx = sin (x);
|
||||
cx = cos (x);
|
||||
tu1 = cu2 * sx;
|
||||
tu2 = b1 - su1 * cu2 * cx;
|
||||
sy = sqrt (tu1 * tu1 + tu2 * tu2);
|
||||
cy = s1 * cx + f1;
|
||||
y = atan2 (sy, cy);
|
||||
sa = s1 * sx / sy;
|
||||
c2a = 1. - sa * sa;
|
||||
cz = f1 + f1;
|
||||
if (c2a > 0.)
|
||||
cz = cy - cz / c2a;
|
||||
e = cz * cz * 2. - 1.;
|
||||
c = ((-3. * c2a + 4.) * f + 4.) * c2a * f / 16.;
|
||||
d = x;
|
||||
x = ((e * cy * c + cz) * sy * c + y) * sa;
|
||||
x = (1. - c) * x * f + glon2 - glon1;
|
||||
}
|
||||
|
||||
x = sqrt ((1. / (r * r) - 1) * c2a + 1.);
|
||||
x += 1.;
|
||||
x = (x - 2.) / x;
|
||||
c = 1. - x;
|
||||
c = (x * x / 4. + 1.) / c;
|
||||
d = (0.375 * x * x - 1.) * x;
|
||||
x = e * cy;
|
||||
s = ((((sy*sy*4.-3.)*(1.-e-e)*cz*d/6.-x)*d/4.+cz)*sy*d+y)*c*a*r;
|
||||
#ifdef DEBUG
|
||||
if (fabs (l_iter - MAXITER) < EPS) {
|
||||
printf ("Algorithm did not converge\n");
|
||||
} else
|
||||
fprintf(stderr,"%s = %.4f\n", __FUNCTION__, s);
|
||||
#endif
|
||||
|
||||
return s;
|
||||
}
|
66
geo-dist.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
*
|
||||
* geo-dist
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GEO_DIST_H
|
||||
#define _GEO_DIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate distances on Earth surface given geographic locations
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
WGS84,
|
||||
NAD27,
|
||||
International,
|
||||
Krasovsky,
|
||||
Bessel,
|
||||
WGS72,
|
||||
WGS66,
|
||||
FAIsphere
|
||||
} EllipsoidType;
|
||||
|
||||
/* nautical in kilometer */
|
||||
#define NAUTICAL_MILE 1.852
|
||||
|
||||
/*
|
||||
* glat1, glat2: geodetic latitude in radians, N positive
|
||||
* glon1, glon2: geodetic longitude in radians E positive
|
||||
* Coordinates in radians means
|
||||
* 50°50.32N ^= 50 degree, 50 minutes and 32 seconds
|
||||
* ^= 50 + (50 / 60) + (32 / 3600)
|
||||
* ^= 50.84222
|
||||
*
|
||||
* returns: distance in nm (nautical miles), factor of 1.852 gives km
|
||||
*/
|
||||
double dist_ell(double, double, double, double, EllipsoidType);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GEO_DIST_H */
|
133
geo-tools.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* geo-tools.h
|
||||
*
|
||||
* Copyright (C) 2006,2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
* parts taken from Maemo-Mapper (GPL)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GEO_TOOLS_H
|
||||
#define _GEO_TOOLS_H
|
||||
|
||||
/* from GNU glibc math.h - since we do not need __USE_GNU else
|
||||
* we copy it here
|
||||
*/
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the following unit-latlpon conversions are
|
||||
* shamelessly stolen^Wborrowed from Maemo-Mapper ;)
|
||||
* ...and will be returned in time
|
||||
* Some minor modifications have been done...
|
||||
*/
|
||||
|
||||
#define pixel2unit(pixel) ((pixel) << _zoom)
|
||||
#define unit2pixel(pixel) ((pixel) >> _zoom)
|
||||
|
||||
|
||||
/* use 31 bits for best accuracy */
|
||||
#define WORLD_SIZE_UNITS (1 << 30 /*26*/)
|
||||
#define MERCATOR_SPAN (-6.28318377773622f)
|
||||
#define MERCATOR_TOP (3.14159188886811f)
|
||||
#define latlon2unit(lat, lon, unitx, unity) { \
|
||||
gdouble tmp; \
|
||||
unitx = (lon + 180.f) * (WORLD_SIZE_UNITS / 360.f) + 0.5f; \
|
||||
tmp = sin(lat * (M_PIl / 180.f)); \
|
||||
unity = 0.5f + (WORLD_SIZE_UNITS / MERCATOR_SPAN) \
|
||||
* (log((1.f + tmp) / (1.f - tmp)) * 0.5f - MERCATOR_TOP); \
|
||||
}
|
||||
|
||||
#define unit2latlon(unitx, unity, lat, lon) { \
|
||||
(lon) = ((unitx) * (360.f / WORLD_SIZE_UNITS)) - 180.f; \
|
||||
(lat) = (360.f * (atan(exp(((unity) \
|
||||
* (MERCATOR_SPAN / WORLD_SIZE_UNITS)) \
|
||||
+ MERCATOR_TOP)))) * (1.f / M_PIl) - 90.f; \
|
||||
}
|
||||
|
||||
#define MACRO_RECALC_OFFSET() { \
|
||||
_offsetx = grid2pixel( \
|
||||
unit2grid(_center.unitx) \
|
||||
- _screen_grids_halfwidth \
|
||||
- tile2grid(_base_tilex)); \
|
||||
_offsety = grid2pixel( \
|
||||
unit2grid(_center.unity) \
|
||||
- _screen_grids_halfheight \
|
||||
- tile2grid(_base_tiley)); \
|
||||
}
|
||||
|
||||
#define MACRO_RECALC_FOCUS_BASE() { \
|
||||
_focus.unitx = x2unit(_screen_width_pixels * _center_ratio / 20); \
|
||||
_focus.unity = y2unit(_screen_height_pixels * _center_ratio / 20); \
|
||||
}
|
||||
|
||||
#define MACRO_RECALC_FOCUS_SIZE() { \
|
||||
_focus_unitwidth = pixel2unit( \
|
||||
(10 - _center_ratio) * _screen_width_pixels / 10); \
|
||||
_focus_unitheight = pixel2unit( \
|
||||
(10 - _center_ratio) * _screen_height_pixels / 10); \
|
||||
}
|
||||
|
||||
#define MACRO_RECALC_CENTER_BOUNDS() { \
|
||||
_min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); \
|
||||
_min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); \
|
||||
_max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1; \
|
||||
_max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)- 1; \
|
||||
}
|
||||
|
||||
#define MACRO_INIT_TRACK(track) { \
|
||||
(track).head = (track).tail = g_new(TrackPoint, ARRAY_CHUNK_SIZE); \
|
||||
(track).tail->unitx = (track).tail->unity = 0; \
|
||||
(track).cap = (track).head + ARRAY_CHUNK_SIZE; \
|
||||
(track).whead = g_new(WayPoint, ARRAY_CHUNK_SIZE); \
|
||||
(track).wtail = (track).whead - 1; \
|
||||
(track).wcap = (track).whead + ARRAY_CHUNK_SIZE; \
|
||||
}
|
||||
|
||||
#define MACRO_CLEAR_TRACK(track) if((track).head) { \
|
||||
WayPoint *curr; \
|
||||
g_free((track).head); \
|
||||
(track).head = (track).tail = (track).cap = NULL; \
|
||||
for(curr = (track).whead - 1; curr++ != (track).wtail; ) \
|
||||
g_free(curr->desc); \
|
||||
g_free((track).whead); \
|
||||
(track).whead = (track).wtail = (track).wcap = NULL; \
|
||||
}
|
||||
|
||||
#define DISTANCE_ROUGH(point) \
|
||||
(abs((gint)((point).unitx) - _pos.unitx) \
|
||||
+ abs((gint)((point).unity) - _pos.unity))
|
||||
|
||||
#define MACRO_QUEUE_DRAW_AREA() \
|
||||
gtk_widget_queue_draw_area( \
|
||||
_map_widget, \
|
||||
0, 0, \
|
||||
_screen_width_pixels, \
|
||||
_screen_height_pixels)
|
||||
|
||||
#define KEEP_DISPLAY_ON() { \
|
||||
/* Note that the flag means keep on ONLY when fullscreen. */ \
|
||||
if(_always_keep_on || _fullscreen) \
|
||||
{ \
|
||||
osso_display_state_on(_osso); \
|
||||
osso_display_blanking_pause(_osso); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
134
mappix-fileio.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
*
|
||||
* mappix-fileio
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "mappix.h"
|
||||
#include "geo-tools.h"
|
||||
|
||||
|
||||
static void
|
||||
write_trackpoint(gpointer data, gpointer user_data)
|
||||
{
|
||||
trackdata *tdata = (trackdata *)data;
|
||||
FILE *mfile = (FILE *)user_data;
|
||||
gfloat llat, llong;
|
||||
gchar dstr[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if (tdata != NULL) {
|
||||
g_fprintf(mfile, "<trkpt ");
|
||||
unit2latlon(tdata->unitx, tdata->unity, llat, llong);
|
||||
g_ascii_dtostr(dstr, G_ASCII_DTOSTR_BUF_SIZE, llat);
|
||||
g_fprintf(mfile, "lat=\"%s\" ", dstr);
|
||||
g_ascii_dtostr(dstr, G_ASCII_DTOSTR_BUF_SIZE, llong);
|
||||
g_fprintf(mfile, "long=\"%s\">\n", dstr);
|
||||
g_fprintf(mfile, "<ele>%.6f</ele>\n", tdata->elevation);
|
||||
#if 0
|
||||
// if (tdata->datetime != NULL)
|
||||
// g_fprintf(mfile, "<time>%s</time>\n", tdata->datetime);
|
||||
g_fprintf(mfile, "<sat>%d</sat>\n", tdata->nrsat);
|
||||
g_fprintf(mfile, "<hdop>%f</hdop>\n", tdata->hdop);
|
||||
g_fprintf(mfile, "<vdop>%f</vdop>\n", tdata->vdop);
|
||||
g_fprintf(mfile, "<pdop>%f</pdop>\n", tdata->pdop);
|
||||
#endif
|
||||
g_fprintf(mfile, "</trkpt>\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_track(gpointer data, gpointer user_data)
|
||||
{
|
||||
track_head *thead = (track_head *)data;
|
||||
FILE *mfile = (FILE *)user_data;
|
||||
gfloat minlat, minlon, maxlat, maxlon;
|
||||
|
||||
if (thead != NULL) {
|
||||
g_fprintf(mfile, "<trk>\n");
|
||||
g_fprintf(mfile, "<name>%s</name>\n", thead->name);
|
||||
g_fprintf(mfile, "<type>%d</type>\n", thead->type); /* NOT GPX CONFORMANT */
|
||||
g_fprintf(mfile, "<show>%s</show>\n", thead->show ? "true" : "false"); /* NOT GPX CONFORMANT */
|
||||
unit2latlon(thead->xmin, thead->ymin, minlat, minlon);
|
||||
unit2latlon(thead->xmax, thead->ymax, maxlat, maxlon);
|
||||
g_fprintf(mfile, "<bounds minlat=\"%f\" minlon=\"%f\" maxlat=\"%f\" maxlon=\"%f\"/>\n", minlat, minlon, maxlat, maxlon);
|
||||
g_fprintf(mfile, "<trkseg>\n");
|
||||
if (thead->track != NULL)
|
||||
g_list_foreach(thead->track, write_trackpoint, mfile);
|
||||
g_fprintf(mfile, "</trkseg>\n");
|
||||
g_fprintf(mfile, "</trk>\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_waypoint(gpointer data, gpointer user_data)
|
||||
{
|
||||
waypoint *tdata = (waypoint *)data;
|
||||
FILE *mfile = (FILE *)user_data;
|
||||
gfloat llat, llong;
|
||||
gchar dstr[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if (tdata != NULL) {
|
||||
g_fprintf(mfile, "<wpt ");
|
||||
unit2latlon(tdata->unitx, tdata->unity, llat, llong);
|
||||
g_ascii_dtostr(dstr, G_ASCII_DTOSTR_BUF_SIZE, llat);
|
||||
g_fprintf(mfile, "lat=\"%s\" ", dstr);
|
||||
g_ascii_dtostr(dstr, G_ASCII_DTOSTR_BUF_SIZE, llong);
|
||||
g_fprintf(mfile, "long=\"%s\">\n", dstr);
|
||||
g_fprintf(mfile, "<name>%s</name>\n", tdata->name);
|
||||
g_fprintf(mfile, "<ele>%.6f</ele>\n", tdata->elevation);
|
||||
#if 0 // not yet used
|
||||
if (tdata->datetime != NULL)
|
||||
g_fprintf(mfile, "<time>%s</time>\n", tdata->datetime);
|
||||
g_fprintf(mfile, "<sat>%d</sat>\n", tdata->nrsat);
|
||||
g_fprintf(mfile, "<hdop>%f</hdop>\n", tdata->hdop);
|
||||
g_fprintf(mfile, "<vdop>%f</vdop>\n", tdata->vdop);
|
||||
g_fprintf(mfile, "<pdop>%f</pdop>\n", tdata->pdop);
|
||||
#endif
|
||||
g_fprintf(mfile, "</wpt>\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gint
|
||||
save_project_to_file(gchar *filename, mapwin *Mapper)
|
||||
{
|
||||
FILE *mfile;
|
||||
|
||||
mfile = g_fopen(filename, "w");
|
||||
|
||||
g_fprintf(mfile, "<?xml version=\"1.0\"?>\n<gpx version=\"1.0\" creator=\"Mappix\"\nxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\nxmlns=\"http://www.topografix.com/GPX/1/0\"\nxsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
|
||||
if (Mapper->tracklist)
|
||||
g_list_foreach(Mapper->tracklist, write_track, mfile);
|
||||
if (Mapper->waypoints)
|
||||
g_list_foreach(Mapper->waypoints, write_waypoint, mfile);
|
||||
g_fprintf(mfile, "</gpx>\n");
|
||||
|
||||
fclose(mfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
24
mappix-fileio.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
*
|
||||
* mappix-fileio
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
gint save_project_to_file(gchar *, mapwin *);
|
344
mappix-gpxreader.c
Normal file
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* gpxreader
|
||||
* read GPX files
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <expat.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mappix.h"
|
||||
|
||||
#include "geo-tools.h"
|
||||
|
||||
#define BUFFSIZE 8192
|
||||
|
||||
|
||||
/* oh well ... we have to remember in which tag we are... */
|
||||
#define CurrentIsTrackMask (guint)0x000000ff
|
||||
#define CurrentIsTrack (guint)1 << 0
|
||||
#define CurrentIsTrackName (guint)1 << 1
|
||||
#define CurrentIsTrackType (guint)1 << 2
|
||||
#define CurrentIsTrackShow (guint)1 << 3
|
||||
#define CurrentIsTrackpointMask (guint)0x0000ff00
|
||||
#define CurrentIsTrackpoint (guint)1 << 8
|
||||
#define CurrentIsTrackpointEle (guint)1 << 9
|
||||
#define CurrentIsTrackpointNRSAT (guint)1 << 10
|
||||
#define CurrentIsTrackpointHDOP (guint)1 << 11
|
||||
#define CurrentIsTrackpointPDOP (guint)1 << 12
|
||||
#define CurrentIsWaypointMask (guint)0x00ff0000
|
||||
#define CurrentIsWaypoint (guint)1 << 16
|
||||
#define CurrentIsWaypointEle (guint)1 << 17
|
||||
#define CurrentIsWaypointName (guint)1 << 18
|
||||
|
||||
/* for passing data around the callbacks */
|
||||
typedef struct {
|
||||
mapwin *Mapper;
|
||||
guint current;
|
||||
GList *track;
|
||||
GList *waypoints;
|
||||
trackdata *tdata;
|
||||
waypoint *wpt;
|
||||
gchar *fname;
|
||||
gchar *tname;
|
||||
gboolean show;
|
||||
tracktype type;
|
||||
} udt;
|
||||
|
||||
|
||||
void finish_track(udt *ltdata)
|
||||
{
|
||||
track_head *new_track;
|
||||
|
||||
if (ltdata->track != NULL) {
|
||||
/* done reading the track */
|
||||
new_track = (track_head *)malloc(sizeof(track_head));
|
||||
new_track->xmax = -1;
|
||||
new_track->ymax = -1;
|
||||
new_track->xmin = WORLD_SIZE_UNITS;
|
||||
new_track->ymin = WORLD_SIZE_UNITS;
|
||||
new_track->track = g_list_reverse(ltdata->track);
|
||||
new_track->show = ltdata->show;
|
||||
new_track->type = ltdata->type;
|
||||
if (ltdata->tname != NULL)
|
||||
new_track->name = g_strdup(ltdata->tname);
|
||||
else
|
||||
new_track->name = g_path_get_basename(ltdata->fname);
|
||||
// fprintf(stderr,"track '%s' has bbox latmin=%lf longmin=%lf latmax=%lf longmax=%lf\n", new_track->name, new_track->latmin, new_track->longmin, new_track->latmax, new_track->longmax);
|
||||
track_add_new_to_main(ltdata->Mapper, new_track);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
startElement(void *userData, const char *name, const char **atts)
|
||||
{
|
||||
udt *ud = (udt *)userData;
|
||||
gdouble rlat, rlong;
|
||||
|
||||
if (strncmp(name, "trkpt", 5) == 0) {
|
||||
ud->tdata = (trackdata *)malloc(sizeof(trackdata));
|
||||
memset(ud->tdata, 0, sizeof(trackdata));
|
||||
if (ud->tdata != NULL) {
|
||||
ud->current |= CurrentIsTrackpoint;
|
||||
rlat = g_ascii_strtod (atts[1], NULL);
|
||||
rlong = g_ascii_strtod (atts[3], NULL);
|
||||
latlon2unit(rlat, rlong, ud->tdata->unitx, ud->tdata->unity);
|
||||
ud->tdata->selected = FALSE;
|
||||
}
|
||||
//fprintf(stderr,"lat=%lf long=%lf\n", tdata->latitude, tdata->longitude);
|
||||
} else if (strncmp(name, "trkseg", 6) == 0) {
|
||||
/* not yet supported */
|
||||
} else if (strncmp(name, "trk", 3) == 0) {
|
||||
// g_message("new track");
|
||||
ud->current |= CurrentIsTrack;
|
||||
if (ud->tname != NULL) {
|
||||
g_free(ud->tname);
|
||||
ud->tname = NULL;
|
||||
};
|
||||
ud->type = UNKNOWN;
|
||||
ud->show = FALSE;
|
||||
} else if (strncmp(name, "wpt", 3) == 0) {
|
||||
ud->wpt = (waypoint *)malloc(sizeof(waypoint));
|
||||
memset(ud->wpt, 0, sizeof(waypoint));
|
||||
if (ud->wpt != NULL) {
|
||||
ud->current |= CurrentIsWaypoint;
|
||||
rlat = g_ascii_strtod (atts[1], NULL);
|
||||
rlong = g_ascii_strtod (atts[3], NULL);
|
||||
latlon2unit(rlat, rlong, ud->wpt->unitx, ud->wpt->unity);
|
||||
ud->wpt->name = NULL;
|
||||
}
|
||||
} else {
|
||||
// fprintf(stderr,"xml unkn: '%s'\n", name);
|
||||
if (ud->current & CurrentIsTrackpoint) {
|
||||
//fprintf(stderr, "is trackpoint\n");
|
||||
if (strncmp(name, "ele", 3) == 0)
|
||||
ud->current |= CurrentIsTrackpointEle;
|
||||
if (strncmp(name, "sat", 3) == 0)
|
||||
ud->current |= CurrentIsTrackpointNRSAT;
|
||||
if (strncmp(name, "hdop", 4) == 0)
|
||||
ud->current |= CurrentIsTrackpointHDOP;
|
||||
if (strncmp(name, "pdop", 4) == 0)
|
||||
ud->current |= CurrentIsTrackpointPDOP;
|
||||
} else if (ud->current & CurrentIsWaypoint) {
|
||||
//fprintf(stderr, "is waypoint\n");
|
||||
if (strncmp(name, "name", 4) == 0)
|
||||
ud->current |= CurrentIsWaypointName;
|
||||
if (strncmp(name, "ele", 3) == 0)
|
||||
ud->current |= CurrentIsWaypointEle;
|
||||
} else if (ud->current & CurrentIsTrack) {
|
||||
//fprintf(stderr, "is track\n");
|
||||
if (strncmp(name, "name", 4) == 0) {
|
||||
ud->current |= CurrentIsTrackName;
|
||||
//fprintf(stderr,"name start\n");
|
||||
}
|
||||
if (strncmp(name, "type", 4) == 0) {
|
||||
ud->current |= CurrentIsTrackType;
|
||||
//fprintf(stderr,"type start\n");
|
||||
}
|
||||
if (strncmp(name, "show", 4) == 0) {
|
||||
ud->current |= CurrentIsTrackShow;
|
||||
//fprintf(stderr,"show start\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
endElement(void *userData, const char *name)
|
||||
{
|
||||
udt *ud = (udt *)userData;
|
||||
//mapwin *Mapper = (mapwin *)userData;
|
||||
|
||||
//fprintf(stderr,"xml endelem: '%s'\n", name);
|
||||
|
||||
/* trackpoints */
|
||||
if (strncmp(name, "trkpt", 5) == 0) {
|
||||
ud->current &= ~CurrentIsTrackpointMask;
|
||||
ud->track = g_list_prepend(ud->track, ud->tdata);
|
||||
} else if (strncmp(name, "trkseg", 6) == 0) {
|
||||
} else if (strncmp(name, "trk", 3) == 0) {
|
||||
finish_track(ud);
|
||||
ud->current = 0;
|
||||
ud->track = NULL;
|
||||
ud->current &= ~CurrentIsTrackMask;
|
||||
}
|
||||
|
||||
if (ud->current & CurrentIsTrackName) {
|
||||
if (strncmp(name, "name", 4) == 0) {
|
||||
//fprintf(stderr, "bnamee 0x%04x ", ud->current);
|
||||
ud->current ^= CurrentIsTrackName;
|
||||
//fprintf(stderr, "anamee 0x%04x\n", ud->current);
|
||||
}
|
||||
}
|
||||
|
||||
if (ud->current & CurrentIsTrackpoint) {
|
||||
if (strncmp(name, "ele", 3) == 0)
|
||||
ud->current ^= CurrentIsTrackpointEle;
|
||||
}
|
||||
|
||||
/* waypoints */
|
||||
if (strncmp(name, "wpt", 3) == 0) {
|
||||
ud->current &= ~CurrentIsWaypointMask;
|
||||
//ud->Mapper->waypoints = g_list_prepend(ud->Mapper->waypoints, ud->wpt);
|
||||
ud->waypoints = g_list_prepend(ud->waypoints, ud->wpt);
|
||||
}
|
||||
if (ud->current & CurrentIsWaypoint) {
|
||||
if (strncmp(name, "name", 4) == 0)
|
||||
ud->current ^= CurrentIsWaypointName;
|
||||
}
|
||||
|
||||
if (ud->current & CurrentIsTrack) {
|
||||
if (CurrentIsTrackType && strncmp(name, "type", 4) == 0)
|
||||
ud->current ^= CurrentIsTrackType;
|
||||
if (CurrentIsTrackShow && strncmp(name, "show", 4) == 0)
|
||||
ud->current ^= CurrentIsTrackShow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
CharData (void *userData, const XML_Char *s, int len)
|
||||
{
|
||||
udt *ud = (udt *)userData;
|
||||
gchar *tmp;
|
||||
|
||||
/* string is not null terminated */
|
||||
tmp = (gchar *)malloc(2+len*sizeof(gchar));
|
||||
memcpy(tmp,s,len);
|
||||
tmp[len] = 0;
|
||||
// fprintf(stderr,"char-data: '%s'\n", tmp);
|
||||
|
||||
/* track head */
|
||||
if (ud->current & CurrentIsTrackName) {
|
||||
if (ud->tname == NULL)
|
||||
ud->tname = g_strdup(tmp);
|
||||
else
|
||||
ud->tname = g_strconcat(ud->tname, tmp, NULL);
|
||||
}
|
||||
if (ud->current & CurrentIsTrackType) {
|
||||
//fprintf(stderr, "type = '%s'\n", tmp);
|
||||
gint val;
|
||||
sscanf(tmp, "%d", &val);
|
||||
ud->type = val;
|
||||
}
|
||||
if (ud->current & CurrentIsTrackShow) {
|
||||
//fprintf(stderr, "show = '%s'\n", tmp);
|
||||
if (len > 0 && g_ascii_strncasecmp("true", tmp, 4)==0 )
|
||||
ud->show = TRUE;
|
||||
else
|
||||
ud->show = FALSE;
|
||||
}
|
||||
|
||||
/* trackpoints */
|
||||
if (ud->current & CurrentIsTrackpointEle) {
|
||||
sscanf(tmp, "%f", &ud->tdata->elevation);
|
||||
}
|
||||
if (ud->current & CurrentIsTrackpointNRSAT) {
|
||||
gint val;
|
||||
sscanf(tmp, "%d", &val);
|
||||
ud->tdata->nrsat = val;
|
||||
}
|
||||
if (ud->current & CurrentIsTrackpointHDOP) {
|
||||
sscanf(tmp, "%f", &ud->tdata->hdop);
|
||||
}
|
||||
if (ud->current & CurrentIsTrackpointPDOP) {
|
||||
sscanf(tmp, "%f", &ud->tdata->pdop);
|
||||
}
|
||||
|
||||
/* waypoints */
|
||||
if (ud->current & CurrentIsWaypointName) {
|
||||
if (ud->wpt->name == NULL)
|
||||
ud->wpt->name = g_strdup(tmp);
|
||||
else
|
||||
ud->wpt->name = g_strconcat(ud->wpt->name, tmp, NULL);
|
||||
}
|
||||
if (ud->current & CurrentIsWaypointEle) {
|
||||
sscanf(tmp, "%f", &ud->wpt->elevation);
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WP
|
||||
void print_waypoints(gpointer data, gpointer user_data)
|
||||
{
|
||||
waypoint *wpnt = (waypoint *)data;
|
||||
|
||||
if (data != NULL) {
|
||||
fprintf(stderr,"wpt: lat=%lf long=%lf name='%s'\n", wpnt->unitx, wpnt->unity, wpnt->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
gint gpxread(gchar *fname, mapwin *Mapper)
|
||||
{
|
||||
char buf[BUFFSIZE];
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
int done;
|
||||
FILE *inpfile;
|
||||
udt ldata;
|
||||
// track_head *new_track;
|
||||
|
||||
inpfile=fopen(fname, "r");
|
||||
if (inpfile == NULL)
|
||||
return -1;
|
||||
|
||||
ldata.fname = fname;
|
||||
ldata.current = 0;
|
||||
ldata.Mapper = Mapper;
|
||||
ldata.track = NULL;
|
||||
ldata.tname = NULL;
|
||||
ldata.waypoints = NULL;
|
||||
XML_SetUserData(parser, &ldata);
|
||||
XML_SetElementHandler(parser, startElement, endElement);
|
||||
XML_SetCharacterDataHandler(parser, CharData);
|
||||
|
||||
do {
|
||||
size_t len = fread(buf, 1, sizeof(buf), inpfile);
|
||||
done = len < sizeof(buf);
|
||||
if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
|
||||
fprintf(stderr, "%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
return -1;
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
XML_ParserFree (parser);
|
||||
fclose (inpfile);
|
||||
|
||||
if (ldata.waypoints) {
|
||||
ldata.waypoints = g_list_reverse(ldata.waypoints);
|
||||
Mapper->waypoints = g_list_concat(Mapper->waypoints, ldata.waypoints);
|
||||
}
|
||||
#ifdef DEBUG_WP
|
||||
if (Mapper->waypoints != NULL) {
|
||||
g_list_foreach(Mapper->waypoints, print_waypoints, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
37
mappix-gpxreader.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* mappix-gpxreader.h
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_GPXREADER_H
|
||||
#define _MAPPIX_GPXREADER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
gint gpxread(gchar *, mapwin *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAPPIX_GPXREADER_H */
|
744
mappix-trackdraw.c
Normal file
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
* trackdraw
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "mappix.h"
|
||||
#include "geo-tools.h"
|
||||
#include "geo-dist.h"
|
||||
|
||||
|
||||
|
||||
void
|
||||
draw_waypoint_label (mapwin *Mapper, gint x, gint y, gchar *text_label)
|
||||
{
|
||||
PangoLayout *playout;
|
||||
GdkColor fgc, bgc;
|
||||
|
||||
playout = gtk_widget_create_pango_layout (Mapper->drawarea, text_label);
|
||||
gdk_color_parse("black", &fgc);
|
||||
gdk_color_parse("yellow", &bgc);
|
||||
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, x+10, y-20, playout, &fgc, &bgc);
|
||||
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x+10, y-10, x, y);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw_city_name(mapwin *Mapper, gchar *city_name, guint x, guint y)
|
||||
{
|
||||
PangoLayout *playout;
|
||||
GdkColor fgc;
|
||||
|
||||
// fprintf(stderr, "city %s\n", city_name);
|
||||
playout = gtk_widget_create_pango_layout (Mapper->drawarea, city_name);
|
||||
gdk_color_parse("black", &fgc);
|
||||
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, x, y, playout, &fgc, NULL);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
city_db_callback(void *user_data, int argc, char **argv, char **azColName)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
double lat, lon;
|
||||
guint unitx, unity;
|
||||
|
||||
// str argv[0]
|
||||
lat = g_ascii_strtod(argv[1] , NULL);
|
||||
lon = g_ascii_strtod(argv[2] , NULL);
|
||||
latlon2unit(lat, lon, unitx, unity);
|
||||
unitx = (unitx - Mapper->xoffset) * Mapper->scale;
|
||||
unity = (unity - Mapper->yoffset) * Mapper->scale;
|
||||
draw_city_name(Mapper, argv[0], unitx, unity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_city_names(mapwin *Mapper)
|
||||
{
|
||||
sqlite3 *db;
|
||||
|
||||
/* re-scan for cities */
|
||||
if (Mapper->show_cities && !sqlite3_open("cities.db", &db)) {
|
||||
char *zErrMsg = 0;
|
||||
gchar sql[256];
|
||||
double lat_min, lon_min;
|
||||
double lat_max, lon_max;
|
||||
gchar lamax[32], lamin[32], lomax[32], lomin[32];
|
||||
|
||||
unit2latlon(Mapper->xmin, Mapper->ymin, lat_min, lon_min);
|
||||
unit2latlon(Mapper->xmax, Mapper->ymax, lat_max, lon_max);
|
||||
g_ascii_dtostr(lamax, 32, lat_max);
|
||||
g_ascii_dtostr(lamin, 32, lat_min);
|
||||
g_ascii_dtostr(lomax, 32, lon_max);
|
||||
g_ascii_dtostr(lomin, 32, lon_min);
|
||||
g_sprintf(sql, "SELECT city, lat, long FROM staedte WHERE lat > %s AND lat < %s AND long > %s AND long < %s;",
|
||||
lamax, lamin, lomin, lomax);
|
||||
sqlite3_exec(db, sql, city_db_callback, Mapper, &zErrMsg);
|
||||
// fprintf(stderr, "sql: '%s'\n", sql);
|
||||
sqlite3_close(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_scale(mapwin *Mapper)
|
||||
{
|
||||
PangoLayout *playout;
|
||||
GdkColor fgc;
|
||||
guint x1,x2,y;
|
||||
double lat1, lat2, lon1, lon2, dist;
|
||||
gchar scale_text[64];
|
||||
|
||||
// assuming we have 50px in the lower right corner
|
||||
// fprintf(stderr, "city %s\n", city_name);
|
||||
x1 = Mapper->xoffset;
|
||||
x2 = Mapper->xoffset + (100. / Mapper->scale);
|
||||
y = Mapper->yoffset;
|
||||
unit2latlon(x1, y, lat1, lon1);
|
||||
unit2latlon(x2, y, lat2, lon2);
|
||||
//fprintf(stderr, "x=%d x2=%d y=%d lat1=%lf lat2=%lf lon1=%lf lon2=%lf\n", x1,x2,y,lat1,lat2,lon1,lon2);
|
||||
|
||||
dist = dist_ell(lat1, lon1, lat2, lon2, WGS84) * NAUTICAL_MILE;
|
||||
if (dist > 1.0)
|
||||
g_snprintf(scale_text, 64, "%.02lfkm", dist);
|
||||
else {
|
||||
g_snprintf(scale_text, 64, "%.00lfm", dist*100.);
|
||||
}
|
||||
|
||||
playout = gtk_widget_create_pango_layout (Mapper->drawarea, scale_text);
|
||||
gdk_color_parse("black", &fgc);
|
||||
gdk_draw_layout_with_colors(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x - 80, Mapper->canvas_y - 20, playout, &fgc, NULL);
|
||||
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-110, Mapper->canvas_y - 20, Mapper->canvas_x-10, Mapper->canvas_y - 20);
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-110, Mapper->canvas_y - 25, Mapper->canvas_x-110, Mapper->canvas_y - 15);
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, Mapper->canvas_x-10, Mapper->canvas_y - 25, Mapper->canvas_x-10, Mapper->canvas_y - 15);
|
||||
|
||||
for (x1 = (Mapper->canvas_x-100); x1 < (Mapper->canvas_x-10); x1+=10)
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x1, Mapper->canvas_y - 25, x1, Mapper->canvas_y - 20);
|
||||
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
do_redraw(mapwin *Mapper)
|
||||
{
|
||||
draw_tracks(Mapper);
|
||||
if (Mapper->show_cities)
|
||||
draw_city_names(Mapper);
|
||||
if (Mapper->show_waypoints)
|
||||
draw_waypoints(Mapper);
|
||||
if (Mapper->show_scale)
|
||||
draw_scale(Mapper);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
change_scale(mapwin *Mapper, double new_scale)
|
||||
{
|
||||
Mapper->scale = new_scale;
|
||||
|
||||
do_redraw(Mapper);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zoom_in_cb (GtkSpinButton *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
gdouble scale_inc;
|
||||
guint x,y;
|
||||
|
||||
scale_inc = Mapper->scale / 10.;
|
||||
x = (Mapper->canvas_x / 2) / Mapper->scale;
|
||||
y = (Mapper->canvas_y / 2) / Mapper->scale;
|
||||
Mapper->scale += scale_inc;
|
||||
Mapper->xoffset += x - ((Mapper->canvas_x / 2) / Mapper->scale);
|
||||
Mapper->yoffset += y - ((Mapper->canvas_y / 2) / Mapper->scale);
|
||||
Mapper->xmin = Mapper->xoffset;
|
||||
Mapper->ymin = Mapper->yoffset;
|
||||
Mapper->xmax = Mapper->xmin + (Mapper->canvas_x / Mapper->scale);
|
||||
Mapper->ymax = Mapper->ymin + (Mapper->canvas_y / Mapper->scale);
|
||||
change_scale(Mapper, Mapper->scale);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zoom_out_cb (GtkSpinButton *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
gdouble scale_inc;
|
||||
guint x,y;
|
||||
|
||||
scale_inc = Mapper->scale / 10.;
|
||||
if (scale_inc < 0)
|
||||
scale_inc = 0;
|
||||
x = (Mapper->canvas_x / 2) / Mapper->scale;
|
||||
y = (Mapper->canvas_y / 2) / Mapper->scale;
|
||||
Mapper->scale -= scale_inc;
|
||||
Mapper->xoffset += x - ((Mapper->canvas_x / 2) / Mapper->scale);
|
||||
Mapper->yoffset += y - ((Mapper->canvas_y / 2) / Mapper->scale);
|
||||
Mapper->xmin = Mapper->xoffset;
|
||||
Mapper->ymin = Mapper->yoffset;
|
||||
Mapper->xmax = Mapper->xmin + (Mapper->canvas_x / Mapper->scale);
|
||||
Mapper->ymax = Mapper->ymin + (Mapper->canvas_y / Mapper->scale);
|
||||
change_scale(Mapper, Mapper->scale);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zoom_area_cb (GtkRadioToolButton *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
|
||||
Mapper->toolmode = MAPPIX_TOOL_ZOOM_REGION;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
move_cb (GtkRadioToolButton *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
|
||||
Mapper->toolmode = MAPPIX_TOOL_MOVE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
auto_scale (GtkButton *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
|
||||
change_scale(Mapper, calc_scale(Mapper));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_line(gint x1, gint y1, gint x2, gint y2, gint linewidth, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
|
||||
gdk_gc_set_line_attributes(Mapper->drawarea->style->black_gc, linewidth, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_MITER);
|
||||
gdk_draw_line(Mapper->mappix, Mapper->drawarea->style->black_gc, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_marker(gint x1, gint y1, gint psize, gint marker_type, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
GdkGC *marker_gc;
|
||||
|
||||
if (!Mapper->show_marker)
|
||||
return;
|
||||
if (marker_type & MARKER_SELECTED) {
|
||||
marker_gc = Mapper->blue_gc;
|
||||
marker_type &= ~MARKER_SELECTED;
|
||||
} else
|
||||
marker_gc = Mapper->red_gc;
|
||||
if (marker_type != MARKER_TYPE_NONE) {
|
||||
if (marker_type == MARKER_TYPE_FILLED_SQUARE) {
|
||||
gdk_draw_rectangle(Mapper->mappix, marker_gc, TRUE, x1 - (psize/2), y1 - (psize/2), psize, psize);
|
||||
} else if (marker_type == MARKER_TYPE_SQUARE) {
|
||||
gdk_draw_rectangle(Mapper->mappix, marker_gc, FALSE, x1 - (psize/2), y1 - (psize/2), psize, psize);
|
||||
} else if (marker_type == MARKER_TYPE_CROSS) {
|
||||
psize = psize / 2;
|
||||
gdk_gc_set_line_attributes(marker_gc, 0 /*linewidth*/, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
|
||||
gdk_draw_line(Mapper->mappix, marker_gc, x1-psize, y1-psize, x1+psize, y1+psize);
|
||||
gdk_draw_line(Mapper->mappix, marker_gc, x1+psize, y1-psize, x1-psize, y1+psize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_markers(track_head *trackh, double bbxmin, double bbxmax, double bbymin, double bbymax, mapwin *Mapper, cairo_t *cr)
|
||||
{
|
||||
GList *track = trackh->track;
|
||||
trackdata *tdata;
|
||||
GList *lp;
|
||||
gboolean start_newline = TRUE;
|
||||
|
||||
if (Mapper->show_marker && Mapper->scale > 0.0009) {
|
||||
double ox, oy;
|
||||
double angle;
|
||||
|
||||
ox = 0.; oy = 0.;
|
||||
cairo_set_line_width(cr, 1.5 / Mapper->scale);
|
||||
for (lp = track; lp; lp=g_list_next(lp)) {
|
||||
tdata = (trackdata *)lp->data;
|
||||
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
|
||||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
|
||||
start_newline = TRUE;
|
||||
} else {
|
||||
if (start_newline) {
|
||||
ox = (double)tdata->unitx;
|
||||
oy = (double)tdata->unity;
|
||||
} else {
|
||||
angle = -1. * atan2((double)tdata->unitx - ox,
|
||||
(double)tdata->unity - oy);
|
||||
cairo_move_to(cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
/* draw marker arrow */
|
||||
cairo_save (cr);
|
||||
if (tdata->selected)
|
||||
cairo_set_source_rgb (cr, .0,.0,.9);
|
||||
else
|
||||
cairo_set_source_rgb (cr, .0,.0,.0);
|
||||
// cairo_set_line_width(cr, 1.5 / Mapper->scale);
|
||||
cairo_rotate(cr, angle);
|
||||
cairo_rel_move_to (cr, -5./ Mapper->scale, -5./ Mapper->scale);
|
||||
cairo_rel_line_to (cr, 5./ Mapper->scale,5. / Mapper->scale);
|
||||
cairo_rel_line_to (cr, 5./ Mapper->scale,-5. / Mapper->scale);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
ox = (double)tdata->unitx;
|
||||
oy = (double)tdata->unity;
|
||||
}
|
||||
start_newline = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_line_with_marker(gint x1, gint y1, gint x2, gint y2, gint psize, gint linewidth, gint marker_type, gpointer user_data)
|
||||
{
|
||||
draw_marker(x1, y1, psize, marker_type, user_data);
|
||||
draw_marker(x2, y2, psize, marker_type, user_data);
|
||||
draw_line(x1, y1, x2, y2, linewidth, user_data);
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
do_calc_scale(mapwin *Mapper)
|
||||
{
|
||||
double xscale, yscale;
|
||||
double scale;
|
||||
|
||||
/* we calculate both scales and choose the smaller scale factor so that all data will fit */
|
||||
xscale = Mapper->canvas_x / (gdouble)(Mapper->xmax - Mapper->xmin);
|
||||
yscale = Mapper->canvas_y / (gdouble)(Mapper->ymax - Mapper->ymin);
|
||||
|
||||
if (xscale < yscale)
|
||||
scale = xscale;
|
||||
else
|
||||
scale = yscale;
|
||||
|
||||
/* this should bring the tracks to the lower left corner */
|
||||
Mapper->xoffset = Mapper->xmin;
|
||||
Mapper->yoffset = Mapper->ymin;
|
||||
|
||||
// g_message("xmax=%d ymax=%d xmin=%d ymax=%d xscale=%f yscale=%f scale=%f", Mapper->xmax, Mapper->ymax, Mapper->xmin, Mapper->ymin, Mapper->xscale, Mapper->yscale, Mapper->scale);
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
calc_scale(mapwin *Mapper)
|
||||
{
|
||||
trackdata *tdata;
|
||||
track_head *thead;
|
||||
GList *trackh, *trackp;
|
||||
|
||||
// fprintf(stderr,"cs\n");
|
||||
Mapper->xmin=WORLD_SIZE_UNITS;
|
||||
Mapper->xmax=0;
|
||||
Mapper->ymin=WORLD_SIZE_UNITS;
|
||||
Mapper->ymax=0;
|
||||
for (trackh=Mapper->tracklist; trackh; trackh=g_list_next(trackh)) {
|
||||
// fprintf(stderr," +cs\n");
|
||||
thead = (track_head *)trackh->data;
|
||||
if (thead->show) {
|
||||
for (trackp=thead->track; trackp; trackp=g_list_next(trackp)) {
|
||||
tdata = (trackdata *)trackp->data;
|
||||
// fprintf(stderr,"latmin=%lf latmax=%lf longmin=%lf longmax=%lf\n", latmin, latmax, longmin, longmax);
|
||||
if (tdata->unitx < Mapper->xmin)
|
||||
Mapper->xmin = tdata->unitx;
|
||||
else if (tdata->unitx > Mapper->xmax)
|
||||
Mapper->xmax = tdata->unitx;
|
||||
if (tdata->unity < Mapper->ymin)
|
||||
Mapper->ymin = tdata->unity;
|
||||
else if (tdata->unity > Mapper->ymax)
|
||||
Mapper->ymax = tdata->unity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return do_calc_scale(Mapper);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_waypoints(mapwin *Mapper)
|
||||
{
|
||||
GList *lp;
|
||||
waypoint *wpdata;
|
||||
|
||||
if (!Mapper->show_waypoints)
|
||||
return;
|
||||
for (lp = Mapper->waypoints; lp; lp=g_list_next(lp)) {
|
||||
double x,y;
|
||||
wpdata = (waypoint *)lp->data;
|
||||
x = (wpdata->unitx - Mapper->xoffset) * Mapper->scale;
|
||||
y = (wpdata->unity - Mapper->yoffset) * Mapper->scale;
|
||||
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", tdata->longitude, tdata->latitude, Mapper->scale);
|
||||
if (x < 0 || y < 0)
|
||||
continue;
|
||||
if (x > Mapper->canvas_x)
|
||||
continue;
|
||||
if (y > Mapper->canvas_y)
|
||||
continue;
|
||||
draw_waypoint_label (Mapper, x, y, wpdata->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
print_matrix(cairo_t *cr)
|
||||
{
|
||||
cairo_matrix_t cmatrix;
|
||||
|
||||
cairo_get_matrix(cr, &cmatrix);
|
||||
fprintf(stderr, "xx=%lf xy=%lf x0=%lf\n", cmatrix.xx, cmatrix.xy, cmatrix.x0);
|
||||
fprintf(stderr, "yx=%lf yy=%lf y0=%lf\n", cmatrix.yx, cmatrix.yy, cmatrix.y0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
draw_track(track_head *trackh, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
GList *track = trackh->track;
|
||||
trackdata *tdata;
|
||||
gboolean start_newline = TRUE;
|
||||
GList *lp;
|
||||
cairo_t *cr;
|
||||
cairo_matrix_t cmatrix;
|
||||
double bbxmin, bbxmax;
|
||||
double bbymin, bbymax;
|
||||
// double TRACK_FACTOR = (1. / (2. * Mapper->scale)) + (100000. * Mapper->scale);
|
||||
double TRACK_FACTOR = (4000. * (Mapper->scale * Mapper->scale)) * (1. / Mapper->scale);
|
||||
|
||||
if (TRACK_FACTOR < (0.8 / Mapper->scale))
|
||||
TRACK_FACTOR = 0.8 / Mapper->scale;
|
||||
if (track == NULL)
|
||||
return;
|
||||
cr = gdk_cairo_create (GDK_DRAWABLE(Mapper->mappix));
|
||||
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
|
||||
/* first set drawing for the outline of track or for non-outlined */
|
||||
if (Mapper->show_marker) {
|
||||
cairo_set_source_rgb (cr, 0,0,0);
|
||||
cairo_set_line_width(cr, 1.0 / Mapper->scale);
|
||||
} else {
|
||||
switch (trackh->type) {
|
||||
case UNKNOWN:
|
||||
case OUTLINE: /* always visible in 1.0pt */
|
||||
cairo_set_source_rgb (cr, 0,0,0);
|
||||
cairo_set_line_width(cr, 1.0 / Mapper->scale);
|
||||
break;
|
||||
case FOOTPATH:
|
||||
cairo_set_source_rgb (cr, 0,0,0);
|
||||
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
|
||||
break;
|
||||
case RIVER:
|
||||
cairo_set_source_rgb (cr, 0,0,.9);
|
||||
cairo_set_line_width(cr, 1.3 * TRACK_FACTOR);
|
||||
break;
|
||||
case AGRI:
|
||||
cairo_set_source_rgb (cr, 0.4,0.4,0.4);
|
||||
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
|
||||
break;
|
||||
case CITY:
|
||||
cairo_set_source_rgb (cr, .5,.5,.5);
|
||||
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
|
||||
break;
|
||||
case URBAN:
|
||||
cairo_set_source_rgb (cr, .3,.3,.3);
|
||||
cairo_set_line_width(cr, 1.5 * TRACK_FACTOR);
|
||||
break;
|
||||
case MOTORWAY:
|
||||
cairo_set_source_rgb (cr, .3,.3,.3);
|
||||
cairo_set_line_width(cr, 3.5 * TRACK_FACTOR);
|
||||
break;
|
||||
case HIGHWAY:
|
||||
cairo_set_source_rgb (cr, .1,.1,.1);
|
||||
cairo_set_line_width(cr, 4.5 * TRACK_FACTOR);
|
||||
break;
|
||||
default:
|
||||
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fprintf(stderr, "scale is: %lf\n", Mapper->scale);
|
||||
|
||||
cairo_matrix_init_identity(&cmatrix);
|
||||
cairo_matrix_init_scale(&cmatrix, Mapper->scale, Mapper->scale);
|
||||
cairo_matrix_translate(&cmatrix, -((double)Mapper->xoffset),
|
||||
-((double)Mapper->yoffset));
|
||||
cairo_set_matrix(cr, &cmatrix);
|
||||
|
||||
bbxmin = Mapper->xoffset;
|
||||
bbxmax = bbxmin + ((double)Mapper->canvas_x / Mapper->scale);
|
||||
bbymin = Mapper->yoffset;
|
||||
bbymax = bbymin + ((double)Mapper->canvas_y / Mapper->scale);
|
||||
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
|
||||
|
||||
for (lp = track; lp; lp=g_list_next(lp)) {
|
||||
tdata = (trackdata *)lp->data;
|
||||
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
|
||||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
|
||||
/* first finish this line, even if the target is outside */
|
||||
if (!start_newline)
|
||||
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
start_newline = TRUE;
|
||||
} else {
|
||||
//draw_line_with_marker(x, y, x2, y2, Mapper->marker_size, Mapper->linewidth, Mapper->marker_type, Mapper);
|
||||
if (start_newline) {
|
||||
// fprintf(stderr, "mt\n");
|
||||
cairo_move_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
} else {
|
||||
// fprintf(stderr, "lt\n");
|
||||
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
}
|
||||
start_newline = FALSE;
|
||||
}
|
||||
}
|
||||
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
|
||||
// print_matrix(cr);
|
||||
cairo_stroke (cr);
|
||||
|
||||
if (!(Mapper->show_marker || trackh->type == UNKNOWN || trackh->type == OUTLINE
|
||||
|| trackh->type == RIVER || trackh->type == FOOTPATH
|
||||
|| trackh->type == AGRI)) {
|
||||
cairo_set_source_rgb (cr, 0.7,0.7,0.7);
|
||||
cairo_set_line_width(cr, (double)Mapper->linewidth / Mapper->scale);
|
||||
|
||||
/* second set drawing for the inner colored track */
|
||||
switch (trackh->type) {
|
||||
case CITY:
|
||||
cairo_set_source_rgb (cr, 1.,1.,1.);
|
||||
cairo_set_line_width(cr, .5 * TRACK_FACTOR);
|
||||
break;
|
||||
case URBAN:
|
||||
cairo_set_source_rgb (cr, 1.,1.,.7);
|
||||
cairo_set_line_width(cr, 1. * TRACK_FACTOR);
|
||||
break;
|
||||
case MOTORWAY:
|
||||
cairo_set_source_rgb (cr, 1.,1.,.5);
|
||||
cairo_set_line_width(cr, 2.5 * TRACK_FACTOR);
|
||||
break;
|
||||
case HIGHWAY:
|
||||
cairo_set_source_rgb (cr, 9.,0.,0.);
|
||||
cairo_set_line_width(cr, 3.5 * TRACK_FACTOR);
|
||||
break;
|
||||
default:
|
||||
cairo_set_line_width(cr, 1.0 * TRACK_FACTOR);
|
||||
break;
|
||||
}
|
||||
|
||||
for (lp = track; lp; lp=g_list_next(lp)) {
|
||||
tdata = (trackdata *)lp->data;
|
||||
// x = (tdata->unitx - Mapper->xoffset) * Mapper->scale;
|
||||
// y = (tdata->unity - Mapper->yoffset) * Mapper->scale;
|
||||
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", (double)tdata->unitx, (double)tdata->unity, Mapper->scale);
|
||||
// fprintf(stderr,"x=%lf y=%lf\n", x, y);
|
||||
if ((tdata->unitx < bbxmin || tdata->unitx > bbxmax) ||
|
||||
(tdata->unity < bbymin || tdata->unity > bbymax)) {
|
||||
// fprintf(stderr, "nl\n");
|
||||
/* first finish this line, even if the target is outside */
|
||||
if (!start_newline)
|
||||
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
start_newline = TRUE;
|
||||
} else {
|
||||
//draw_line_with_marker(x, y, x2, y2, Mapper->marker_size, Mapper->linewidth, Mapper->marker_type, Mapper);
|
||||
if (start_newline) {
|
||||
// fprintf(stderr, "mt\n");
|
||||
cairo_move_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
} else {
|
||||
// fprintf(stderr, "lt\n");
|
||||
cairo_line_to (cr, (double)tdata->unitx, (double)tdata->unity);
|
||||
}
|
||||
start_newline = FALSE;
|
||||
}
|
||||
}
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
if (Mapper->show_marker)
|
||||
draw_markers(trackh, bbxmin, bbxmax, bbymin, bbymax, Mapper, cr);
|
||||
|
||||
// fprintf(stderr, "xl=%lf xh=%lf yl=%lf yh=%lf\n", bbxmin, bbxmax, bbymin, bbymax);
|
||||
// print_matrix(cr);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
draw_idle(gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
static GList *track=NULL;
|
||||
static track_head *trackh=NULL;
|
||||
trackdata *tdata;
|
||||
double x,y;
|
||||
static double x2=-1,y2=-1;
|
||||
static GList *lp=NULL;
|
||||
|
||||
if (Mapper->tracklist == NULL) {
|
||||
// fprintf(stderr,"tracklist==NULL -> end\n");
|
||||
/* erase drawing area */
|
||||
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
Mapper->draw_idle_active = FALSE;
|
||||
track = NULL;
|
||||
lp = NULL;
|
||||
x2 = -1;
|
||||
y2 = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// start new drawing
|
||||
if (!Mapper->draw_idle_active) {
|
||||
// fprintf(stderr,"new drawing -> starting\n");
|
||||
Mapper->draw_idle_active = TRUE;
|
||||
track = Mapper->tracklist;
|
||||
/* erase drawing area */
|
||||
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
|
||||
lp = NULL;
|
||||
x2 = -1; y2 = -1;
|
||||
}
|
||||
|
||||
trackh=(track_head *)track->data;
|
||||
if (trackh->xmax < Mapper->xoffset ||
|
||||
trackh->ymax < Mapper->yoffset ||
|
||||
trackh->xmin > (Mapper->xoffset + (Mapper->canvas_x / Mapper->scale)) ||
|
||||
trackh->ymin > (Mapper->yoffset + (Mapper->canvas_y / Mapper->scale))) {
|
||||
/* fprintf(stderr, "not drawing track '%s'\n", trackh->name); */
|
||||
} else if (trackh->track != NULL && trackh->show) {
|
||||
if (lp == NULL)
|
||||
lp = trackh->track;
|
||||
tdata = (trackdata *)lp->data;
|
||||
x = (tdata->unitx - Mapper->xoffset) * Mapper->scale;
|
||||
y = (tdata->unity - Mapper->yoffset) * Mapper->scale;
|
||||
// fprintf(stderr,"x=%lf y=%lf sc=%lf\n", tdata->longitude, tdata->latitude, Mapper->scale);
|
||||
/* if the next point is the same as the previous we do not see a line so we do not paint it */
|
||||
if ((guint)x != (guint)x2 || (guint)y != (guint)y2) {
|
||||
if (x2 < 0 && y2 < 0) {
|
||||
x2 = x; y2 = y;
|
||||
draw_marker(x,y,Mapper->marker_size, Mapper->marker_type | (tdata->selected ? MARKER_SELECTED : 0), Mapper);
|
||||
} else {
|
||||
if ((x < 0 || x > Mapper->canvas_x) || (y < 0 || y > Mapper->canvas_y)) {
|
||||
x2 = -1; y2 = -1;
|
||||
} else {
|
||||
draw_marker(x,y,Mapper->marker_size, Mapper->marker_type | (tdata->selected ? MARKER_SELECTED : 0), Mapper);
|
||||
draw_line(x, y, x2, y2, Mapper->linewidth, Mapper);
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, done with this track
|
||||
lp = g_list_next(lp);
|
||||
if (lp == NULL) {
|
||||
// fprintf(stderr,"track end -> next track\n");
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
track = g_list_next(track);
|
||||
if (track != NULL) {
|
||||
trackh = (track_head *)track->data;
|
||||
lp = trackh->track;
|
||||
x2 = -1; y2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (track == NULL) {
|
||||
// fprintf(stderr,"end of tracks -> end\n");
|
||||
draw_waypoints(Mapper);
|
||||
Mapper->draw_idle_active = FALSE;
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_tracks(mapwin *Mapper)
|
||||
{
|
||||
if (Mapper->use_idledraw) {
|
||||
if (Mapper->draw_idle_active) {
|
||||
Mapper->draw_idle_active = FALSE;
|
||||
g_idle_remove_by_data(Mapper);
|
||||
}
|
||||
g_idle_add_full(G_PRIORITY_HIGH_IDLE + 20, draw_idle, Mapper, NULL);
|
||||
} else {
|
||||
GList *track;
|
||||
track_head *trackh;
|
||||
|
||||
/* erase drawing area */
|
||||
gdk_draw_rectangle(Mapper->mappix, Mapper->drawarea->style->white_gc, 1, 0, 0, Mapper->canvas_x, Mapper->canvas_y);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
if (Mapper->tracklist != NULL) {
|
||||
for (track=Mapper->tracklist; track; track=g_list_next(track)) {
|
||||
trackh = (track_head *)track->data;
|
||||
if (trackh->show) {
|
||||
if (trackh->xmax < Mapper->xoffset ||
|
||||
trackh->ymax < Mapper->yoffset ||
|
||||
trackh->xmin > (Mapper->xoffset + (Mapper->canvas_x / Mapper->scale)) ||
|
||||
trackh->ymin > (Mapper->yoffset + (Mapper->canvas_y / Mapper->scale))) {
|
||||
// fprintf(stderr, "not drawing track '%s'\n", trackh->name);
|
||||
} else
|
||||
draw_track(trackh, Mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_filename (gchar *fname, mapwin *Mapper)
|
||||
{
|
||||
if (gpxread(fname, Mapper) < 0)
|
||||
return;
|
||||
draw_tracks(Mapper);
|
||||
draw_city_names(Mapper);
|
||||
draw_waypoints(Mapper);
|
||||
gtk_widget_queue_draw(Mapper->drawarea);
|
||||
}
|
54
mappix-trackdraw.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* mappix-trackdraw.h
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_TRACKDRAW_H
|
||||
#define _MAPPIX_TRACKDRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void draw_waypoint_label (mapwin *, gint, gint, gchar *);
|
||||
void draw_pointed_line(gint, gint, gint, gint, gint, gint, gpointer);
|
||||
void draw_lines_cb (GtkButton *, gpointer);
|
||||
double do_calc_scale(mapwin *);
|
||||
double calc_scale(mapwin *);
|
||||
void do_redraw(mapwin *);
|
||||
void change_scale(mapwin *, double);
|
||||
void draw_marker(gint, gint, gint, gint, gpointer);
|
||||
void draw_track(track_head *, gpointer);
|
||||
void draw_tracks(mapwin *);
|
||||
void draw_filename (gchar *, mapwin *);
|
||||
void zoom_in_cb (GtkSpinButton *, gpointer);
|
||||
void zoom_out_cb (GtkSpinButton *, gpointer);
|
||||
void zoom_area_cb (GtkRadioToolButton *, gpointer);
|
||||
void move_cb (GtkRadioToolButton *, gpointer);
|
||||
void auto_scale (GtkButton *, gpointer);
|
||||
void draw_waypoints(mapwin *);
|
||||
void draw_city_names(mapwin *);
|
||||
void draw_scale(mapwin *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAPPIX_TRACKDRAW_H */
|
1124
mappix-trackedit.c
Normal file
51
mappix-trackedit.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* mappix-trackedit.h
|
||||
*
|
||||
* Copyright (C) 2006,2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_TRACKEDIT_H
|
||||
#define _MAPPIX_TRACKEDIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void on_auto_split (GtkButton *, gpointer);
|
||||
void on_auto_thin (GtkButton *, gpointer);
|
||||
void on_properties_track (GtkButton *, gpointer);
|
||||
void on_track_angle_simplify (GtkButton *, gpointer);
|
||||
void on_track_delete (GtkToolButton *, gpointer);
|
||||
void on_select_trackpoint_cb(GtkToolButton *, gpointer);
|
||||
void on_select_region_cb(GtkToolButton *, gpointer);
|
||||
void do_trackpoint_region_select(gint, gint, guint, guint, gpointer);
|
||||
void on_move_trackpoint_cb(GtkToolButton *, gpointer);
|
||||
void do_select_trackpoint(gint, gint, gpointer);
|
||||
void do_move_trackpoint(gint, gint, gint, gint, gpointer);
|
||||
void track_find_minmax(gpointer, gpointer);
|
||||
void track_add_new_to_main(mapwin *, track_head *);
|
||||
void on_delete_nodes_cb(GtkToolButton *, gpointer);
|
||||
void on_split_track(GtkToolButton *, gpointer);
|
||||
void on_track_length(GtkWidget *, gpointer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAPPIX_TRACKEDIT_H */
|
210
mappix-trackrecord.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
#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);
|
||||
}
|
6
mappix-trackrecord.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _MAPPIX_TRACKRECORD_H
|
||||
#define _MAPPIX_TRACKRECORD_H
|
||||
|
||||
void on_record_track (GtkButton *widget, gpointer user_data);
|
||||
|
||||
#endif /* _MAPPIX_TRACKRECORD_H */
|
1074
mappix-ui.c
Normal file
41
mappix-ui.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/***************************************************************************
|
||||
* mappix-ui.h
|
||||
*
|
||||
* Sun Jun 4 19:06:50 2006
|
||||
* Copyright 2006 User
|
||||
* Email
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_UI_H
|
||||
#define _MAPPIX_UI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int create_main_window(mapwin *);
|
||||
gint close_application( GtkWidget *, GdkEvent *, gpointer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAPPIX_UI_H */
|
365
mappix-waypoints.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* mappix-waypoints
|
||||
*
|
||||
* Copyright (C) 2006,2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mappix.h"
|
||||
#include "geo-tools.h"
|
||||
|
||||
|
||||
static void
|
||||
fill_liststore(GtkListStore *store, GList *waypoints)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GList *lp;
|
||||
waypoint *wpdata;
|
||||
gdouble lat, lon;
|
||||
|
||||
if (waypoints == NULL)
|
||||
return;
|
||||
if (waypoints->data == NULL)
|
||||
return;
|
||||
|
||||
lp = waypoints;
|
||||
do {
|
||||
wpdata = (waypoint *)lp->data;
|
||||
unit2latlon(wpdata->unitx, wpdata->unity, lat, lon);
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, wpdata->name, 1, lat, 2, lon, 3, lp, -1);
|
||||
} while ((lp = g_list_next(lp)));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wp_tv_add_columns (GtkTreeView *treeview, mapwin *Mapper)
|
||||
{
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
// GtkTreeModel *model;
|
||||
|
||||
// model = gtk_tree_view_get_model(Mapper->track_treeview);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Name", renderer, "text", 0, NULL);
|
||||
//gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
|
||||
//gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50);
|
||||
gtk_tree_view_append_column (treeview, column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Latitude", renderer, "text", 1, NULL);
|
||||
// gtk_tree_view_column_set_sort_column_id (column, 1);
|
||||
gtk_tree_view_append_column (treeview, column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Longitude", renderer, "text", 2, NULL);
|
||||
// gtk_tree_view_column_set_sort_column_id (column, 1);
|
||||
gtk_tree_view_append_column (treeview, column);
|
||||
|
||||
gtk_tree_view_set_search_column (treeview, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
delete_waypoint (GtkTreeView *treeview, GtkListStore *store, GtkWidget *parent, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
waypoint *wpdata;
|
||||
GtkTreeSelection *tree_selection;
|
||||
GtkTreeIter iter;
|
||||
GList *lp;
|
||||
gint res;
|
||||
GtkWidget *dialog;
|
||||
|
||||
tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
|
||||
if (!gtk_tree_selection_get_selected(tree_selection, NULL, &iter))
|
||||
return;
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &lp, -1);
|
||||
wpdata = lp->data;
|
||||
|
||||
dialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(parent)),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_YES_NO,
|
||||
"Are you sure you want to delete waypoint\n%s", wpdata->name);
|
||||
res = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_hide (dialog);
|
||||
gtk_widget_destroy (dialog);
|
||||
if (res != GTK_RESPONSE_YES) {
|
||||
return;
|
||||
}
|
||||
// fprintf(stderr, "would delete %s\n", wpdata->name);
|
||||
gtk_list_store_remove(GTK_LIST_STORE(store), &iter);
|
||||
|
||||
Mapper->waypoints = g_list_remove(lp, wpdata);
|
||||
g_free(wpdata);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
edit_waypoint (GtkTreeView *treeview, GtkListStore *store, GtkWidget *parent, gpointer user_data)
|
||||
{
|
||||
// mapwin *Mapper = (mapwin *)user_data;
|
||||
waypoint *wpdata;
|
||||
GtkTreeSelection *tree_selection;
|
||||
GtkTreeIter iter;
|
||||
GList *lp;
|
||||
gint result;
|
||||
GtkWidget *dialog, *hbox, *stock, *table, *label;
|
||||
GtkWidget *entry_name, *entry_lat, *entry_lon;
|
||||
gdouble lat, lon;
|
||||
const gchar *tmp_name;
|
||||
|
||||
tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
|
||||
if (!gtk_tree_selection_get_selected(tree_selection, NULL, &iter))
|
||||
return;
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &lp, -1);
|
||||
wpdata = lp->data;
|
||||
unit2latlon(wpdata->unitx, wpdata->unity, lat, lon);
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons("Edit waypoint", GTK_WINDOW(gtk_widget_get_toplevel(parent)),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_STOCK_OK,
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_REJECT,
|
||||
NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 8);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
stock = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), stock, FALSE, FALSE, 0);
|
||||
|
||||
table = gtk_table_new (3, 4, 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), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
|
||||
|
||||
label = gtk_label_new ("Name");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 0, 1);
|
||||
// track_combo = gtk_combo_box_new_text();
|
||||
entry_name = gtk_entry_new();
|
||||
gtk_entry_set_text(GTK_ENTRY(entry_name), wpdata->name);
|
||||
gtk_entry_set_editable(GTK_ENTRY(entry_name), TRUE);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_name, 1, 2, 0, 1);
|
||||
|
||||
label = gtk_label_new ("Latitude");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 1, 2);
|
||||
entry_lat = gtk_spin_button_new_with_range(0.0, 360.0, 0.00000001);
|
||||
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(entry_lat), 8);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(entry_lat), lat);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_lat, 1, 2, 1, 2);
|
||||
|
||||
label = gtk_label_new ("Longitude");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 2, 3);
|
||||
entry_lon = gtk_spin_button_new_with_range(0.0, 360.0, 0.00000001);
|
||||
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(entry_lon), 8);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(entry_lon), lon);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_lon, 1, 2, 2, 3);
|
||||
|
||||
gtk_widget_show_all (hbox);
|
||||
|
||||
result = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
switch (result) {
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
tmp_name = gtk_entry_get_text(GTK_ENTRY(entry_name));
|
||||
g_free(wpdata->name);
|
||||
wpdata->name = g_strdup(tmp_name);
|
||||
lat = gtk_spin_button_get_value(GTK_SPIN_BUTTON(entry_lat));
|
||||
lon = gtk_spin_button_get_value(GTK_SPIN_BUTTON(entry_lon));
|
||||
latlon2unit(lat, lon, wpdata->unitx, wpdata->unity)
|
||||
gtk_list_store_set(GTK_LIST_STORE(store), &iter, 0, wpdata->name, 1, lat, 2, lon, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
new_waypoint (GtkTreeView *treeview, GtkListStore *store, GtkWidget *parent, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
waypoint *wpdata;
|
||||
GtkTreeIter iter;
|
||||
gint result;
|
||||
GtkWidget *dialog, *hbox, *stock, *table, *label;
|
||||
GtkWidget *entry_name, *entry_lat, *entry_lon;
|
||||
gdouble lat, lon;
|
||||
const gchar *tmp_name;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons("Edit waypoint", GTK_WINDOW(gtk_widget_get_toplevel(parent)),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_STOCK_OK,
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_REJECT,
|
||||
NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 8);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
stock = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), stock, FALSE, FALSE, 0);
|
||||
|
||||
table = gtk_table_new (3, 4, 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), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
|
||||
|
||||
unit2latlon(Mapper->xmin, Mapper->ymin, lat, lon);
|
||||
|
||||
label = gtk_label_new ("Name");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 0, 1);
|
||||
// track_combo = gtk_combo_box_new_text();
|
||||
entry_name = gtk_entry_new();
|
||||
gtk_entry_set_text(GTK_ENTRY(entry_name), "Label");
|
||||
gtk_entry_set_editable(GTK_ENTRY(entry_name), TRUE);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_name, 1, 2, 0, 1);
|
||||
|
||||
label = gtk_label_new ("Latitude");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 1, 2);
|
||||
entry_lat = gtk_spin_button_new_with_range(0.0, 360.0, 0.00000001);
|
||||
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(entry_lat), 8);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(entry_lat), lat);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_lat, 1, 2, 1, 2);
|
||||
|
||||
label = gtk_label_new ("Longitude");
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 2, 3);
|
||||
entry_lon = gtk_spin_button_new_with_range(0.0, 360.0, 0.00000001);
|
||||
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(entry_lon), 8);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(entry_lon), lon);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), entry_lon, 1, 2, 2, 3);
|
||||
|
||||
gtk_widget_show_all (hbox);
|
||||
|
||||
result = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
switch (result) {
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
tmp_name = gtk_entry_get_text(GTK_ENTRY(entry_name));
|
||||
wpdata = (waypoint *)g_malloc(sizeof(waypoint));
|
||||
wpdata->name = g_strdup(tmp_name);
|
||||
lat = gtk_spin_button_get_value(GTK_SPIN_BUTTON(entry_lat));
|
||||
lon = gtk_spin_button_get_value(GTK_SPIN_BUTTON(entry_lon));
|
||||
latlon2unit(lat, lon, wpdata->unitx, wpdata->unity)
|
||||
Mapper->waypoints = g_list_prepend(Mapper->waypoints, wpdata);
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(GTK_LIST_STORE(store), &iter, 0, wpdata->name, 1, lat, 2, lon, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_editview_waypoints (GtkWidget *widget, gpointer user_data)
|
||||
{
|
||||
mapwin *Mapper = (mapwin *)user_data;
|
||||
GtkWidget *dialog;
|
||||
gint dresult;
|
||||
GtkWidget *w;
|
||||
GtkWidget *wp_treeview;
|
||||
GtkTreeModel *tree_model;
|
||||
gboolean changed=FALSE;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("My dialog", GTK_WINDOW(gtk_widget_get_toplevel(Mapper->mainwin)),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
"Edit", 1,
|
||||
"Delete", 2,
|
||||
"New", 3,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
/* track list in treeview */
|
||||
w = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (w), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_show(w);
|
||||
tree_model = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_POINTER));
|
||||
wp_treeview = gtk_tree_view_new_with_model (tree_model);
|
||||
#if 0
|
||||
#ifdef HILDON
|
||||
g_object_set(G_OBJECT(Mapper->track_treeview), "allow-checkbox-mode", FALSE, NULL);
|
||||
gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(Mapper->track_treeview), FALSE);
|
||||
#endif
|
||||
#endif
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (wp_treeview), TRUE);
|
||||
g_object_unref (tree_model);
|
||||
gtk_container_add (GTK_CONTAINER (w), wp_treeview);
|
||||
gtk_widget_show(wp_treeview);
|
||||
wp_tv_add_columns(GTK_TREE_VIEW (wp_treeview), Mapper);
|
||||
|
||||
fill_liststore(GTK_LIST_STORE(tree_model), Mapper->waypoints);
|
||||
|
||||
gtk_widget_show_all (dialog);
|
||||
|
||||
dresult = 0;
|
||||
while (dresult >= 0) {
|
||||
dresult = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
||||
switch (dresult) {
|
||||
case 1:
|
||||
edit_waypoint(GTK_TREE_VIEW(wp_treeview), GTK_LIST_STORE(tree_model), dialog, Mapper);
|
||||
changed = TRUE;
|
||||
break;
|
||||
case 2:
|
||||
delete_waypoint(GTK_TREE_VIEW(wp_treeview), GTK_LIST_STORE(tree_model), dialog, Mapper);
|
||||
changed = TRUE;
|
||||
break;
|
||||
case 3:
|
||||
new_waypoint(GTK_TREE_VIEW(wp_treeview), GTK_LIST_STORE(tree_model), dialog, Mapper);
|
||||
changed = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_hide(dialog);
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
if (changed)
|
||||
do_redraw(Mapper);
|
||||
}
|
27
mappix-waypoints.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* mappix-waypoints.h
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_WAYPOINTS_H
|
||||
#define _MAPPIX_WAYPOINTS_H
|
||||
|
||||
void on_editview_waypoints (GtkWidget *, gpointer );
|
||||
|
||||
#endif
|
53
mappix.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
*
|
||||
* mappix
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* we don't do much here, mainly fire up the UI */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mappix.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
mapwin Mapper;
|
||||
#ifdef HILDON
|
||||
osso_context_t *context;
|
||||
#endif
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
#ifdef HILDON
|
||||
context = osso_initialize (OSSO_SERVICE_NAME, APP_VER, TRUE, NULL);
|
||||
g_assert(context);
|
||||
#endif
|
||||
|
||||
Mapper.tracklist = NULL;
|
||||
Mapper.waypoints = NULL;
|
||||
Mapper.cities = NULL;
|
||||
|
||||
create_main_window(&Mapper);
|
||||
|
||||
gtk_main();
|
||||
|
||||
return 0;
|
||||
}
|
133
mappix.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* mappix
|
||||
*
|
||||
* Copyright (C) 2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MAPPIX_H
|
||||
#define _MAPPIX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HILDON
|
||||
#include <hildon-widgets/hildon-app.h>
|
||||
#include <hildon-widgets/hildon-appview.h>
|
||||
#include <hildon-widgets/gtk-infoprint.h>
|
||||
#include <libosso.h>
|
||||
|
||||
|
||||
#define APP_NAME "mappix"
|
||||
#define APP_VER "0.1-1"
|
||||
#define OSSO_SERVICE_NAME "mappix"
|
||||
#endif
|
||||
|
||||
#include "trackdata.h"
|
||||
|
||||
/* what are we doing right now? */
|
||||
typedef enum {
|
||||
MAPPIX_TOOL_NONE,
|
||||
MAPPIX_TOOL_ZOOM_REGION,
|
||||
MAPPIX_TOOL_SELECT_REGION,
|
||||
MAPPIX_TOOL_MOVE,
|
||||
MAPPIX_TOOL_SELECT_TRACKPOINT,
|
||||
MAPPIX_TOOL_MOVE_TRACKPOINT
|
||||
} MappixToolmode;
|
||||
|
||||
typedef enum {
|
||||
MARKER_TYPE_NONE,
|
||||
MARKER_TYPE_FILLED_SQUARE,
|
||||
MARKER_TYPE_SQUARE,
|
||||
MARKER_TYPE_CROSS,
|
||||
MARKER_SELECTED = 0x80
|
||||
} MappixMarkerType;
|
||||
|
||||
// to avoid globals we pass around a monster-struct
|
||||
typedef struct {
|
||||
GtkWidget *mainwin;
|
||||
#ifdef HILDON
|
||||
HildonApp *hildon_app;
|
||||
HildonAppView *hildon_mainview;
|
||||
#endif
|
||||
GdkCursor *cursor_normal, *cursor_mover, *cursor_crosshair, *cursor_hand, *cursor_select;
|
||||
GtkWidget *track_treeview;
|
||||
GtkWidget *drawarea;
|
||||
GdkGC *red_gc;
|
||||
GdkGC *blue_gc;
|
||||
GdkGC *select_gc;
|
||||
GdkPixmap *mappix;
|
||||
GdkPixmap *mappix_blank;
|
||||
GtkWidget *statbar;
|
||||
GtkRadioToolButton *zoom_area_toggle_button, *move_toggle_button;
|
||||
gint linewidth;
|
||||
MappixMarkerType marker_type; // 0=no marker, 1=filled square, 2=non-filled square, 3=cross
|
||||
gint marker_size;
|
||||
gboolean show_marker;
|
||||
guint lstatid; // ID of last statusbar message
|
||||
gint canvas_x;
|
||||
gint canvas_y;
|
||||
double xscale;
|
||||
double yscale;
|
||||
double scale;
|
||||
gint xoffset;
|
||||
gint yoffset;
|
||||
guint pointer_x, pointer_y; // scaled coordinates
|
||||
guint mouse_x, mouse_y; // unscaled coordinates
|
||||
guint mouse_px, mouse_py; // unscaled coordinates of last mouse button press
|
||||
gint xmin, xmax;
|
||||
gint ymin, ymax;
|
||||
MappixToolmode toolmode;
|
||||
gboolean modified;
|
||||
gboolean use_idledraw;
|
||||
gboolean draw_idle_active; // we redraw the tracks in idle loop
|
||||
// gboolean use_ellipse_projection;
|
||||
gboolean draw_selection;
|
||||
gboolean move_selection;
|
||||
GList *tracklist;
|
||||
GList *waypoints;
|
||||
GList *cities;
|
||||
gboolean show_waypoints;
|
||||
gboolean show_cities;
|
||||
gboolean show_scale;
|
||||
} mapwin;
|
||||
|
||||
|
||||
#include "mappix-ui.h"
|
||||
#include "mappix-trackdraw.h"
|
||||
#include "mappix-trackedit.h"
|
||||
#include "mappix-gpxreader.h"
|
||||
#include "mappix-trackrecord.h"
|
||||
#include "mappix-fileio.h"
|
||||
#include "mappix-waypoints.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAPPIX_H */
|
218
nmeap.h
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
Copyright (c) 2005, David M Howard (daveh at dmh2000.com)
|
||||
All rights reserved.
|
||||
|
||||
This product is licensed for use and distribution under the BSD Open Source License.
|
||||
see the file COPYING for more details.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NMEAP_H__
|
||||
#define __NMEAP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NDEBUG 1
|
||||
|
||||
/*
|
||||
============================================
|
||||
COMPILE TIME CONFIGURATION CONSTANTS
|
||||
============================================
|
||||
*/
|
||||
|
||||
/* these constants affect the size of the context object. tweak them as desired but know what you are doing */
|
||||
|
||||
/** maximum number of sentence parsers supported */
|
||||
#define NMEAP_MAX_SENTENCES 8
|
||||
/** length of sentence name. leave this at 5 unless you really know what you are doing */
|
||||
#define NMEAP_MAX_SENTENCE_NAME_LENGTH 5
|
||||
/** max length of a complete sentence. the standard says 82 bytes, but its probably better to go at least 128 since
|
||||
* some units don't adhere to the 82 bytes especially for proprietary sentences */
|
||||
#define NMEAP_MAX_SENTENCE_LENGTH 255
|
||||
/** max tokens in one sentence. 24 is enough for any standard sentence */
|
||||
#define NMEAP_MAX_TOKENS 24
|
||||
|
||||
/* predefined message ID's */
|
||||
|
||||
/* GGA MESSAGE ID */
|
||||
#define NMEAP_GPGGA 1
|
||||
/* RMC MESSAGE ID */
|
||||
#define NMEAP_GPRMC 2
|
||||
|
||||
/** user defined parsers should make ID numbers using NMEAP_USER as the base value, plus some increment */
|
||||
#define NMEAP_USER 100
|
||||
|
||||
/* forward references */
|
||||
struct nmeap_context;
|
||||
struct nmeap_sentence;
|
||||
|
||||
/*
|
||||
============================================
|
||||
CALLOUTS
|
||||
============================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* sentence callout function type
|
||||
* a callout is fired for each registered sentence type
|
||||
* the callout gets the object context and a pointer to sentence specific data.
|
||||
* the callout must cast the 'sentence_data' to the appropriate type for that callout
|
||||
* @param context nmea object context
|
||||
* @param sentence_data sentence specific data
|
||||
*/
|
||||
typedef void (*nmeap_callout_t)(struct nmeap_context *context,void *sentence_data,void *user_data);
|
||||
|
||||
/**
|
||||
* sentence parser function type
|
||||
* stored in the object context and called internally when the sentence name matches
|
||||
* the specified value
|
||||
* the callout gets the object context and a pointer to sentence specific data.
|
||||
* the callout must cast the 'sentence_data' to the appropriate type for that callout
|
||||
* @param context nmea object context
|
||||
* @param sentence_data sentence specific data
|
||||
* @return id of sentence (each sentence parser knows its own ID)
|
||||
*/
|
||||
typedef int (*nmeap_sentence_parser_t)(struct nmeap_context *context,struct nmeap_sentence *sentence);
|
||||
|
||||
|
||||
/* ==== opaque types === */
|
||||
#include "nmeap_def.h"
|
||||
|
||||
|
||||
/*
|
||||
============================================
|
||||
STANDARD SENTENCE DATA STRUCTURES
|
||||
============================================
|
||||
*/
|
||||
|
||||
/** extracted data from a GGA message */
|
||||
struct nmeap_gga {
|
||||
double latitude;
|
||||
double longitude;
|
||||
double altitude;
|
||||
unsigned long time;
|
||||
int satellites;
|
||||
int quality;
|
||||
double hdop;
|
||||
double geoid;
|
||||
};
|
||||
typedef struct nmeap_gga nmeap_gga_t;
|
||||
|
||||
/** extracted data from an RMC message */
|
||||
struct nmeap_rmc {
|
||||
unsigned long time;
|
||||
char warn;
|
||||
double latitude;
|
||||
double longitude;
|
||||
double speed;
|
||||
double course;
|
||||
unsigned long date;
|
||||
double magvar;
|
||||
};
|
||||
|
||||
typedef struct nmeap_rmc nmeap_rmc_t;
|
||||
|
||||
/*
|
||||
============================================
|
||||
METHODS
|
||||
============================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* initialize an NMEA parser. call this function to initialize a user allocated context object
|
||||
* @param context nmea object context. allocated by user statically or dynamically.
|
||||
* @param user_data pointer to user defined data
|
||||
* @return 0 if ok, -1 if initialization failed
|
||||
*/
|
||||
int nmeap_init(nmeap_context_t *context,void *user_data);
|
||||
|
||||
/**
|
||||
* register an NMEA sentence parser
|
||||
* @param context nmea object context
|
||||
* @param sentence_name string matching the sentence name for this parser. e.g. "GPGGA". not including the '$'
|
||||
* @param sentence_parser parser function for this sentence
|
||||
* @param sentence_callout callout triggered when this sentence is received and parsed.
|
||||
* if null, no callout is triggered for this sentence
|
||||
* @param sentence_data user allocated sentence specific data defined by the application. the parser uses
|
||||
this data item to store the extracted data. This data object needs to persist over the life
|
||||
of the parser, so be careful if allocated on the stack.
|
||||
* @return 0 if registered ok, -1 if registration failed
|
||||
*/
|
||||
int nmeap_addParser(nmeap_context_t *context,
|
||||
const char *sentence_name,
|
||||
nmeap_sentence_parser_t sentence_parser,
|
||||
nmeap_callout_t sentence_callout,
|
||||
void *sentence_data
|
||||
);
|
||||
|
||||
/**
|
||||
* parse a buffer of nmea data.
|
||||
* @param context nmea object context
|
||||
* @param buffer buffer of input characters
|
||||
* @param length [in,out] pointer to length of buffer. on return, contains number of characters not used for
|
||||
* the current sentence
|
||||
* @return -1 if error, 0 if the data did not complete a sentence, sentence code if a sentence was found in the stream
|
||||
*/
|
||||
int nmeap_parseBuffer(nmeap_context_t *context,const char *buffer,int *length);
|
||||
|
||||
/**
|
||||
* parse one character of nmea data.
|
||||
* @param context nmea object context
|
||||
* @param ch input character
|
||||
* @return -1 if error, 0 if the data did not complete a sentence, sentence code if a sentence was found in the stream
|
||||
*/
|
||||
int nmeap_parse(nmeap_context_t *context,char ch);
|
||||
|
||||
|
||||
/**
|
||||
* built-in parser for GGA sentences.
|
||||
* @param context nmea object context
|
||||
* @param sentence sentence object for this parser
|
||||
*/
|
||||
int nmeap_gpgga(nmeap_context_t *context,nmeap_sentence_t *sentence);
|
||||
|
||||
/**
|
||||
* built-in parser for RMC sentences.
|
||||
* @param context nmea object context
|
||||
* @param sentence sentence object for this parser
|
||||
*/
|
||||
int nmeap_gprmc(nmeap_context_t *context,nmeap_sentence_t *sentence);
|
||||
|
||||
/**
|
||||
* extract latitude from 2 tokens in ddmm.mmmm,h format.
|
||||
* @param plat pointer to token with numerical latitude
|
||||
* @param phem pointer to token with hemisphere
|
||||
* @return latitude in degrees and fractional degrees
|
||||
*/
|
||||
double nmeap_latitude(const char *plat,const char *phem);
|
||||
|
||||
|
||||
/**
|
||||
* extract longitude from 2 tokens in ddmm.mmmm,h format.
|
||||
* @param plat pointer to token with numerical longitude
|
||||
* @param phem pointer to token with hemisphere
|
||||
* @return longitude in degrees and fractional degrees
|
||||
*/
|
||||
double nmeap_longitude(const char *plat,const char *phem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
621
nmeap01.c
Normal file
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
Copyright (c) 2005, David M Howard (daveh at dmh2000.com)
|
||||
All rights reserved.
|
||||
|
||||
This product is licensed for use and distribution under the BSD Open Source License.
|
||||
see the file COPYING for more details.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* nmeap01.c
|
||||
* nmeap gps data parser
|
||||
*
|
||||
* see the file COPYING for terms of the licnese
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include "nmeap.h"
|
||||
|
||||
/* this only works if you are sure you have an upper case hex digit */
|
||||
#define HEXTOBIN(ch) ((ch <= '9') ? ch - '0' : ch - ('A' - 10))
|
||||
|
||||
/* forward references */
|
||||
int nmeap_init(nmeap_context_t *context,void *user_data);
|
||||
int nmeap_addParser(nmeap_context_t *context,
|
||||
const char *sentence_name,
|
||||
nmeap_sentence_parser_t sentence_parser,
|
||||
nmeap_callout_t sentence_callout,
|
||||
void *sentence_data
|
||||
);
|
||||
int nmeap_tokenize(nmeap_context_t *context);
|
||||
int nmeap_process(nmeap_context_t *context);
|
||||
int nmeap_parse(nmeap_context_t *context,char ch);
|
||||
int nmeap_parseBuffer(nmeap_context_t *context,const char *buffer,int *length);
|
||||
|
||||
/**
|
||||
* get a latitude out of a pair of nmea tokens
|
||||
*/
|
||||
double nmeap_latitude(const char *plat,const char *phem)
|
||||
{
|
||||
double lat;
|
||||
int deg;
|
||||
double min;
|
||||
int ns;
|
||||
|
||||
assert(plat != 0);
|
||||
assert(phem != 0);
|
||||
|
||||
if (*plat == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (*phem == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* north lat is +, south lat is - */
|
||||
if (*phem == 'N') {
|
||||
ns = 1;
|
||||
}
|
||||
else {
|
||||
ns = -1;
|
||||
}
|
||||
|
||||
/* latitude is degrees, minutes, fractional minutes */
|
||||
/* no validation is performed on the token. it better be good.*/
|
||||
/* if it comes back 0.0 then probably the token was bad */
|
||||
lat = atof(plat);
|
||||
|
||||
/* extract the degree part */
|
||||
deg = (int)(lat / 100.0);
|
||||
|
||||
/* mask out the degrees */
|
||||
min = lat - (deg * 100.0);
|
||||
|
||||
/* compute the actual latitude in degrees.decimal-degrees */
|
||||
lat = (deg + (min / 60.0)) * ns;
|
||||
|
||||
return lat;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a longitude out of a pair of nmea tokens
|
||||
*/
|
||||
double nmeap_longitude(const char *plon,const char *phem)
|
||||
{
|
||||
double lon;
|
||||
int deg;
|
||||
double min;
|
||||
int ew;
|
||||
|
||||
assert(plon != 0);
|
||||
assert(phem != 0);
|
||||
|
||||
if (*plon == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (*phem == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* west long is negative, east long is positive */
|
||||
if (*phem == 'E') {
|
||||
ew = 1;
|
||||
}
|
||||
else {
|
||||
ew = -1;
|
||||
}
|
||||
|
||||
/* longitude is degrees, minutes, fractional minutes */
|
||||
/* no validation is performed on the token. it better be good.*/
|
||||
/* if it comes back 0.0 then probably the token was bad */
|
||||
lon = atof(plon);
|
||||
|
||||
/* extract the degree part */
|
||||
deg = (int)(lon / 100.0);
|
||||
|
||||
/* mask out the degrees */
|
||||
min = lon - (deg * 100.0);
|
||||
|
||||
/* compute the actual lonitude in degrees.decimal-degrees */
|
||||
lon = (deg + (min / 60.0)) * ew;
|
||||
|
||||
|
||||
return lon;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an altitude longitude out of a pair of nmea tokens
|
||||
* ALTITUDE is returned in METERS
|
||||
*/
|
||||
double nmeap_altitude(const char *palt,const char *punits)
|
||||
{
|
||||
double alt;
|
||||
|
||||
if (*palt == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* convert with no error checking */
|
||||
alt = atof(palt);
|
||||
|
||||
if (*punits == 'M') {
|
||||
/* already in meters */
|
||||
}
|
||||
else if (*punits == 'F') {
|
||||
/* convert to feet */
|
||||
alt = alt * 3.2808399;
|
||||
}
|
||||
|
||||
return alt;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize an NMEA parser
|
||||
*/
|
||||
int nmeap_init(nmeap_context_t *context,void *user_data)
|
||||
{
|
||||
assert(context != 0);
|
||||
|
||||
memset(context,0,sizeof(*context));
|
||||
|
||||
context->user_data = user_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* register an NMEA sentence parser
|
||||
*/
|
||||
int nmeap_addParser(nmeap_context_t *context,
|
||||
const char *sentence_name,
|
||||
nmeap_sentence_parser_t sentence_parser,
|
||||
nmeap_callout_t sentence_callout,
|
||||
void *sentence_data
|
||||
)
|
||||
{
|
||||
nmeap_sentence_t *s = 0;
|
||||
|
||||
/* runtime error */
|
||||
assert(context != 0);
|
||||
|
||||
/* sentence capacity overflow */
|
||||
if (context->sentence_count >= NMEAP_MAX_SENTENCES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* point at next empty sentence buffer */
|
||||
s = &context->sentence[context->sentence_count];
|
||||
|
||||
/* advance sentence data count */
|
||||
context->sentence_count++;
|
||||
|
||||
/* clear the sentence data */
|
||||
memset(s,0,sizeof(*s));
|
||||
|
||||
/* name */
|
||||
strncpy(s->name,sentence_name,NMEAP_MAX_SENTENCE_NAME_LENGTH);
|
||||
|
||||
/* parser */
|
||||
s->parser = sentence_parser;
|
||||
|
||||
/* callout */
|
||||
s->callout = sentence_callout;
|
||||
|
||||
/* data */
|
||||
s->data = sentence_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tokenize a buffer
|
||||
*/
|
||||
int nmeap_tokenize(nmeap_context_t *context)
|
||||
{
|
||||
char *s;
|
||||
int tokens;
|
||||
int state;
|
||||
|
||||
/* first token is header. assume it is there */
|
||||
tokens = 0;
|
||||
s = context->input;
|
||||
context->token[tokens] = s;
|
||||
|
||||
/* get rest of tokens */
|
||||
tokens = 1;
|
||||
state = 0;
|
||||
while((*s != 0)&&(tokens < NMEAP_MAX_TOKENS)) {
|
||||
switch(state) {
|
||||
case 0:
|
||||
/* looking for end of a token */
|
||||
if (*s == ',') {
|
||||
/* delimit at the comma */
|
||||
*s = 0;
|
||||
/* new token */
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* start of next token, might be another comma */
|
||||
context->token[tokens++] = s;
|
||||
if (*s == ',') {
|
||||
/* delimit at the comma */
|
||||
*s = 0;
|
||||
}
|
||||
else {
|
||||
/* not a comma */
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// next character
|
||||
s++;
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* process a sentence
|
||||
*/
|
||||
int nmeap_process(nmeap_context_t *context)
|
||||
{
|
||||
int id=0;
|
||||
int i;
|
||||
nmeap_sentence_t *s;
|
||||
|
||||
/* copy the input to a debug buffer */
|
||||
/* remove debug_input when everything is working. */
|
||||
strncpy(context->debug_input,context->input,sizeof(context->debug_input));
|
||||
|
||||
/* tokenize the input */
|
||||
context->tokens = nmeap_tokenize(context);
|
||||
|
||||
/* try to find a matching sentence parser */
|
||||
/* this search is O(n). it has a lot of potential for optimization, at the expense of complexity, if you have a lot of sentences */
|
||||
/* binary search instead of linear (have to keep sentences in sorted order) O(NlogN) */
|
||||
/* OR, when sentences are added, create a TRIE structure to find the names with a constant time search O(5) */
|
||||
for(i=0;i<context->sentence_count;i++) {
|
||||
s = &context->sentence[i];
|
||||
assert(s != 0);
|
||||
if (strncmp(context->input_name,s->name,5) == 0) {
|
||||
/* found a match, call its parser */
|
||||
id = (*context->sentence[i].parser)(context,s);
|
||||
if (id > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
+-5-+ +---+
|
||||
v | v |
|
||||
+------+ +------+ +------+ +------+ +------+
|
||||
| 0 |--$--> |1-hdr |--alnum--> |2-data|----\r-->| 6-LF |---\n--->| done |--> 0
|
||||
+------+ +------+ +------+ +------+ +------+
|
||||
| ^
|
||||
* +--------\r-------+
|
||||
V |
|
||||
+------+ +------+ +------+
|
||||
|3-cks |--xdigit-->|4-cks |-xdigit->| 5-CR |
|
||||
+------+ +------+ +------+
|
||||
|
||||
return to start conditions:
|
||||
1. buffer overflow
|
||||
2. invalid character for state
|
||||
|
||||
checksum calculation
|
||||
two hex digits represent the XOR of all characters between, but not
|
||||
including, the "$" and "*". A checksum is required on some
|
||||
sentences.
|
||||
|
||||
*/
|
||||
int nmeap_parse(nmeap_context_t *context,char ch)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
/* check for input buffer overrun first to avoid duplicating code in the
|
||||
individual states
|
||||
*/
|
||||
if (context->input_count >= (sizeof(context->input)-1)) {
|
||||
/* input buffer overrun, restart state machine */
|
||||
context->input_state = 0;
|
||||
/* reset input count */
|
||||
context->input_count = 0;
|
||||
}
|
||||
|
||||
/* store the byte */
|
||||
context->input[context->input_count] = ch;
|
||||
|
||||
/* next buffer position */
|
||||
context->input_count++;
|
||||
|
||||
/* run it through the lexical scanner */
|
||||
switch(context->input_state) {
|
||||
/* LOOKING FOR $ */
|
||||
case 0:
|
||||
if (ch == '$') {
|
||||
/*look for id */
|
||||
context->input_state = 1;
|
||||
context->ccks = 0;
|
||||
context->icks = 0;
|
||||
}
|
||||
else {
|
||||
/* header error, start over */
|
||||
context->err_hdr++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR 5 CHARACTER SENTENCE ID */
|
||||
case 1:
|
||||
/* allow numbers even though it isn't usually done */
|
||||
/* a proprietary id might have a numeral */
|
||||
if (isalnum(ch)) {
|
||||
/* store name separately */
|
||||
context->input_name[context->input_count - 2] = ch;
|
||||
/* checksum */
|
||||
context->ccks ^= ch;
|
||||
/* end of header? */
|
||||
if (context->input_count >= 6) {
|
||||
/* yes, get body */
|
||||
context->input_state = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* bad character, start over */
|
||||
context->err_id++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR CR OR CHECKSUM INDICATOR */
|
||||
case 2:
|
||||
if (ch == '*') {
|
||||
/* this sentence has a checksum */
|
||||
context->input_state = 3;
|
||||
}
|
||||
else if (ch == '\r') {
|
||||
/* carriage return, no checksum, force a match */
|
||||
context->icks = 0;
|
||||
context->ccks = 0;
|
||||
context->input_state = 6;
|
||||
}
|
||||
else {
|
||||
/* continue accumulating data */
|
||||
/* checksum */
|
||||
context->ccks ^= ch;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR FIRST CHECKSUM CHARACTER */
|
||||
case 3:
|
||||
/* must be upper case hex digit */
|
||||
if (isxdigit(ch) && (ch <= 'F')) {
|
||||
/* got first checksum byte */
|
||||
context->input_state = 4;
|
||||
context->icks = HEXTOBIN(ch) << 4;
|
||||
}
|
||||
else {
|
||||
/* input error, restart */
|
||||
context->err_cks++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR SECOND CHECKSUM CHARACTER */
|
||||
case 4:
|
||||
/* must be upper case hex digit */
|
||||
if (isxdigit(ch) && (ch <= 'F')) {
|
||||
/* got second checksum byte */
|
||||
context->input_state = 5;
|
||||
context->icks += HEXTOBIN(ch);
|
||||
}
|
||||
else {
|
||||
/* input error, restart */
|
||||
context->err_cks++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR CR */
|
||||
case 5:
|
||||
if (ch == '\r') {
|
||||
/* carriage return */
|
||||
context->input_state = 6;
|
||||
}
|
||||
else {
|
||||
/* input error, restart */
|
||||
context->err_crl++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
/* LOOKING FOR LINE FEED */
|
||||
case 6:
|
||||
if (ch == '\n') {
|
||||
/* linefeed, line complete */
|
||||
|
||||
/* delimit buffer */
|
||||
context->input[context->input_count] = 0;
|
||||
|
||||
/* if the checksums match, process the sentence */
|
||||
if (context->ccks == context->icks) {
|
||||
/* process */
|
||||
status = nmeap_process(context);
|
||||
|
||||
/* count good messages */
|
||||
context->msgs++;
|
||||
}
|
||||
else {
|
||||
/* count checksum errors */
|
||||
context->err_cks++;
|
||||
}
|
||||
|
||||
/* restart next time */
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
else {
|
||||
/* input error, restart */
|
||||
context->err_crl++;
|
||||
context->input_state = 0;
|
||||
context->input_count = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
context->err_unk++;
|
||||
context->input_state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a buffer of nmea data
|
||||
*/
|
||||
int nmeap_parseBuffer(nmeap_context_t *context,const char *buffer,int *length)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
int rem;
|
||||
int tlen;
|
||||
|
||||
tlen = *length;
|
||||
rem = *length;
|
||||
status = 0;
|
||||
/* for each byte in the buffer */
|
||||
for(i=0;i<tlen;i++) {
|
||||
/* decrement remaining byte count */
|
||||
rem--;
|
||||
/* parse the byte */
|
||||
status = nmeap_parse(context,buffer[i]);
|
||||
if (status != 0) {
|
||||
/* message found or error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* return remaining byte count */
|
||||
*length = rem;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* standard GPGGA sentence parser
|
||||
*/
|
||||
int nmeap_gpgga(nmeap_context_t *context,nmeap_sentence_t *sentence)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* get pointer to sentence data */
|
||||
nmeap_gga_t *gga = (nmeap_gga_t *)sentence->data;
|
||||
|
||||
/* if there is a data element, extract data from the tokens */
|
||||
if (gga != 0) {
|
||||
gga->latitude = nmeap_latitude(context->token[2],context->token[3]);
|
||||
gga->longitude = nmeap_longitude(context->token[4],context->token[5]);
|
||||
gga->altitude = nmeap_altitude(context->token[9],context->token[10]);
|
||||
gga->time = atoi(context->token[1]);
|
||||
gga->satellites = atoi(context->token[7]);
|
||||
gga->quality = atoi(context->token[6]);
|
||||
gga->hdop = atof(context->token[8]);
|
||||
gga->geoid = nmeap_altitude(context->token[11],context->token[12]);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* print raw input string */
|
||||
printf("%s",context->debug_input);
|
||||
|
||||
/* print some validation data */
|
||||
printf("%s==%s %02x==%02x\n",context->input_name,sentence->name,context->icks,context->ccks);
|
||||
|
||||
/* print the tokens */
|
||||
for(i=0;i<context->tokens;i++) {
|
||||
printf("%d:%s\n",i,context->token[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if the sentence has a callout, call it */
|
||||
if (sentence->callout != 0) {
|
||||
(*sentence->callout)(context,gga,context->user_data);
|
||||
}
|
||||
|
||||
return NMEAP_GPGGA;
|
||||
}
|
||||
|
||||
/**
|
||||
* standard GPRMCntence parser
|
||||
*/
|
||||
int nmeap_gprmc(nmeap_context_t *context,nmeap_sentence_t *sentence)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* get pointer to sentence data */
|
||||
nmeap_rmc_t *rmc = (nmeap_rmc_t *)sentence->data;
|
||||
|
||||
/* if there is a data element, use it */
|
||||
if (rmc != 0) {
|
||||
/* extract data from the tokens */
|
||||
rmc->time = atoi(context->token[1]);
|
||||
rmc->warn = *context->token[2];
|
||||
rmc->latitude = nmeap_latitude(context->token[3],context->token[4]);
|
||||
rmc->longitude = nmeap_longitude(context->token[5],context->token[6]);
|
||||
rmc->speed = atof(context->token[7]);
|
||||
rmc->course = atof(context->token[8]);
|
||||
rmc->date = atoi(context->token[9]);
|
||||
rmc->magvar = atof(context->token[10]);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* print raw input string */
|
||||
printf("%s",context->debug_input);
|
||||
|
||||
/* print some validation data */
|
||||
printf("%s==%s %02x==%02x\n",context->input_name,sentence->name,context->icks,context->ccks);
|
||||
|
||||
/* print the tokens */
|
||||
for(i=0;i<context->tokens;i++) {
|
||||
printf("%d:%s\n",i,context->token[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if the sentence has a callout, call it */
|
||||
if (sentence->callout != 0) {
|
||||
(*sentence->callout)(context,rmc,context->user_data);
|
||||
}
|
||||
|
||||
return NMEAP_GPRMC;
|
||||
}
|
||||
|
||||
|
72
nmeap_def.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright (c) 2005, David M Howard (daveh at dmh2000.com)
|
||||
All rights reserved.
|
||||
|
||||
This product is licensed for use and distribution under the BSD Open Source License.
|
||||
see the file COPYING for more details.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NMEAP_DEF_H__
|
||||
#define __NMEAP_DEF_H__
|
||||
|
||||
/**
|
||||
* context for a single sentence
|
||||
*/
|
||||
typedef struct nmeap_sentence {
|
||||
char name[NMEAP_MAX_SENTENCE_NAME_LENGTH + 1];
|
||||
int id;
|
||||
nmeap_sentence_parser_t parser;
|
||||
nmeap_callout_t callout;
|
||||
void *data;
|
||||
} nmeap_sentence_t;
|
||||
|
||||
/**
|
||||
* parser context
|
||||
*/
|
||||
struct nmeap_context {
|
||||
/** support up to 8 sentences */
|
||||
nmeap_sentence_t sentence[NMEAP_MAX_SENTENCES]; /* sentence descriptors */
|
||||
int sentence_count; /* number of initialized descriptors */
|
||||
|
||||
/** sentence input buffer */
|
||||
char input[NMEAP_MAX_SENTENCE_LENGTH + 1]; /* input line buffer */
|
||||
int input_count; /* index into 'input */
|
||||
int input_state; /* current lexical scanner state */
|
||||
char input_name[6]; /* sentence name */
|
||||
char icks; /* input checksum */
|
||||
char ccks; /* computed checksum */
|
||||
|
||||
/* tokenization */
|
||||
char *token[NMEAP_MAX_TOKENS]; /* list of delimited tokens */
|
||||
int tokens; /* list of tokens */
|
||||
|
||||
/** errors and debug. optimize these as desired */
|
||||
unsigned long msgs; /* count of good messages */
|
||||
unsigned long err_hdr; /* header error */
|
||||
unsigned long err_ovr; /* overrun error */
|
||||
unsigned long err_unk; /* unknown error */
|
||||
unsigned long err_id; /* bad character in id */
|
||||
unsigned long err_cks; /* bad checksum */
|
||||
unsigned long err_crl; /* expecting cr or lf, got something else */
|
||||
char debug_input[NMEAP_MAX_SENTENCE_LENGTH + 1]; /* input line buffer for debug */
|
||||
|
||||
/** opaque user data */
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
typedef struct nmeap_context nmeap_context_t;
|
||||
|
||||
#endif /* __NMEAP_DEF_H__ */
|
BIN
pixmaps/stock-curve-free-16.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
pixmaps/stock-curve-smooth-16.png
Normal file
After Width: | Height: | Size: 412 B |
BIN
pixmaps/stock-layer-to-imagesize-16.png
Normal file
After Width: | Height: | Size: 202 B |
BIN
pixmaps/stock-tool-iscissors-22.png
Normal file
After Width: | Height: | Size: 790 B |
BIN
pixmaps/stock-tool-measure-22.png
Normal file
After Width: | Height: | Size: 605 B |
BIN
pixmaps/stock-tool-move-22.png
Normal file
After Width: | Height: | Size: 510 B |
BIN
pixmaps/stock_delete.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
pixmaps/stock_draw-selection.png
Normal file
After Width: | Height: | Size: 552 B |
BIN
pixmaps/stock_frame.png
Normal file
After Width: | Height: | Size: 267 B |
BIN
pixmaps/stock_node-add.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
pixmaps/stock_node-close-path.png
Normal file
After Width: | Height: | Size: 466 B |
BIN
pixmaps/stock_node-convert.png
Normal file
After Width: | Height: | Size: 630 B |
BIN
pixmaps/stock_node-corner-to-smooth.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
pixmaps/stock_node-corner.png
Normal file
After Width: | Height: | Size: 427 B |
BIN
pixmaps/stock_node-curve-split.png
Normal file
After Width: | Height: | Size: 741 B |
BIN
pixmaps/stock_node-delete.png
Normal file
After Width: | Height: | Size: 670 B |
BIN
pixmaps/stock_node-mark-for-deletion.png
Normal file
After Width: | Height: | Size: 764 B |
BIN
pixmaps/stock_node-move.png
Normal file
After Width: | Height: | Size: 678 B |
BIN
pixmaps/stock_node-smooth-to-symmetrical.png
Normal file
After Width: | Height: | Size: 407 B |
BIN
pixmaps/stock_zoom-1.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
pixmaps/stock_zoom-in.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
pixmaps/stock_zoom-next.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
pixmaps/stock_zoom-object.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
pixmaps/stock_zoom-optimal.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
pixmaps/stock_zoom-out.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
pixmaps/stock_zoom-page-width.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
pixmaps/stock_zoom-page.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
pixmaps/stock_zoom-previous.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
pixmaps/stock_zoom-shift.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
pixmaps/stock_zoom.png
Normal file
After Width: | Height: | Size: 997 B |
88
trackdata.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* trackdata
|
||||
*
|
||||
* Copyright (C) 2006,2007 Nils Faerber <nils.faerber@kernelconcepts.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TRACKDATA_H_
|
||||
#define _TRACKDATA_H_
|
||||
|
||||
/* track element */
|
||||
typedef struct {
|
||||
// data
|
||||
gint unitx;
|
||||
gint unity;
|
||||
gfloat elevation;
|
||||
gchar *datetime;
|
||||
gchar nrsat; // number of satellites in view
|
||||
gfloat hdop; // horizontal delution
|
||||
gfloat vdop; // vertital delution
|
||||
gfloat pdop; // ??? other dilution
|
||||
// attributes for UI
|
||||
gboolean selected;
|
||||
} trackdata;
|
||||
|
||||
/* track types, LANEs are no. of lanes per direction */
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
OUTLINE, // like borders
|
||||
RIVER,
|
||||
FOOTPATH,
|
||||
AGRI,
|
||||
CITY,
|
||||
URBAN,
|
||||
MOTORWAY,
|
||||
HIGHWAY,
|
||||
} tracktype;
|
||||
|
||||
|
||||
/* tracklist element */
|
||||
typedef struct {
|
||||
GList *track; // list of trackdata trackpoints
|
||||
gboolean show; // if this track is to be drawn
|
||||
gchar *name; // visible name of this track
|
||||
gint xmax, ymax; // bounding box of this track
|
||||
gint xmin, ymin;
|
||||
tracktype type;
|
||||
} track_head;
|
||||
|
||||
|
||||
/* waypoint / POI */
|
||||
typedef struct {
|
||||
gint unitx;
|
||||
gint unity;
|
||||
gfloat elevation;
|
||||
gchar *name;
|
||||
} waypoint;
|
||||
|
||||
|
||||
/*
|
||||
* cities
|
||||
* Cities are stored in database, internal GList if cities only stores
|
||||
* the cities inside the current view
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
gint unitx;
|
||||
gint unity;
|
||||
gchar *name;
|
||||
guint population;
|
||||
} city;
|
||||
|
||||
#endif
|