Browse Source

Merge branch 'master' of https://github.com/gpsbabel/gpsbabel

tags/gpsbabel_1_5_4
Robert Lipe 3 years ago
parent
commit
f3f74a1d98

+ 1
- 1
Makefile.in View File

@@ -81,7 +81,7 @@ ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o \
vpl.o teletype.o jogmap.o bushnell.o bushnell_trl.o wintec_tes.o \
subrip.o garmin_xt.o garmin_fit.o lowranceusr4.o \
mtk_locus.o googledir.o mapbar_track.o f90g_track.o mapfactor.o energympro.o \
mynav.o ggv_bin.o globalsat_sport.o
mynav.o ggv_bin.o globalsat_sport.o geojson.o

FMTS=@FMTS@


+ 9
- 0
defs.h View File

@@ -105,6 +105,15 @@
# define strdup _strdup
#endif

/* Workaround for lack of va_copy in Visual Studio 2012 and earlier */
#if __WIN32__
# if _MSC_VER
# if _MSC_VER < 1700
# define va_copy(dest, src) ((dest) = (src))
# endif
# endif
#endif

/* Turn off numeric conversion warning */
#if __WIN32__
# if _MSC_VER

+ 172
- 0
geojson.cc View File

@@ -0,0 +1,172 @@
/*
Copyright (C) 2016 Robert Lipe, robertlipe+source@gpsbabel.org

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 USA

*/
#include "defs.h"
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
#include "src/core/file.h"

static gbfile* ofd;
static const char MYNAME[] = "geojson";
static char* compact_opt = NULL;
static QJsonObject* track_object = NULL;
static QJsonArray* track_coords = NULL;

static arglist_t geojson_args[] = {
{"compact", &compact_opt, "Compact Output. Default is off.",
NULL, ARGTYPE_BOOL, ARG_NOMINMAX } ,
ARG_TERMINATOR
};

static void
geojson_rd_init(const QString& fname) {
}

QJsonArray* feature_collection = nullptr;

static void
geojson_wr_init(const QString& fname) {
feature_collection = new QJsonArray;
ofd = gbfopen(fname, "w", MYNAME);
}

static void
geojson_waypt_pr(const Waypoint* waypoint) {
QJsonObject object;
static const QString kType = QStringLiteral("type");
object[kType] = QStringLiteral("Feature");
QJsonObject geometry;
geometry[kType] = QStringLiteral("Point");

QJsonArray coords;
coords.append(waypoint->longitude);
coords.append(waypoint->latitude);
if (waypoint->altitude != unknown_alt && waypoint->altitude != 0) {
coords.append(waypoint->altitude);
}

geometry[kType] = QStringLiteral("Point");
geometry[QStringLiteral("coordinates")] = coords;
object[QStringLiteral("geometry")] = geometry;

// Build up the properties.
QJsonObject properties;
if (!waypoint->shortname.isEmpty()) {
properties["name"] = waypoint->shortname;
}
if (!waypoint->description.isEmpty()) {
properties["description"] = waypoint->description;
}
if (waypoint->HasUrlLink()) {
UrlLink link = waypoint->GetUrlLink();
if (!link.url_.isEmpty()) {
properties["url"] = link.url_;
}
if (!link.url_link_text_.isEmpty()) {
properties["urlname"] = link.url_link_text_;
}
}
if (!properties.empty()) {
object["properties"] = properties;
}
feature_collection->append(object);
}

static void
geojson_rd_deinit() {
}

static void
geojson_wr_deinit(void) {
QJsonObject object;
object[QStringLiteral("type")] = QStringLiteral("FeatureCollection");
object[QStringLiteral("features")] = *feature_collection;

QJsonDocument save(object);
QJsonDocument::JsonFormat style;
style = compact_opt ? QJsonDocument::Compact : QJsonDocument::Indented;
gbfputs(save.toJson(style),ofd);

gbfclose(ofd);
ofd = NULL;
delete feature_collection;
feature_collection = nullptr;
}

static void
geojson_read(void) {
}

static void geojson_track_hdr(const route_head* track) {
track_object = new QJsonObject();

(*track_object)[QStringLiteral("type")] = QStringLiteral("Feature");
track_coords = new QJsonArray();

QJsonObject properties;
if (!track->rte_name.isEmpty()) {
properties["name"] = track->rte_name;
}
(*track_object)["properties"] = properties;
}

static void geojson_track_disp(const Waypoint* trackpoint) {

QJsonArray coords;
coords.append(trackpoint->longitude);
coords.append(trackpoint->latitude);
if (trackpoint->altitude != unknown_alt && trackpoint->altitude != 0) {
coords.append(trackpoint->altitude);
}
(*track_coords).append(coords);
}

static void geojson_track_tlr(const route_head* track) {
QJsonObject geometry;
geometry[QStringLiteral("type")] = QStringLiteral("LineString");
geometry[QStringLiteral("coordinates")] = *track_coords;
(*track_object)[QStringLiteral("geometry")] = geometry;
feature_collection->append(*track_object);
delete track_object;
track_object = NULL;
delete track_coords;
track_coords = NULL;
}

static void
geojson_write(void) {
waypt_disp_all(geojson_waypt_pr);
track_disp_all(geojson_track_hdr, geojson_track_tlr, geojson_track_disp);
}

ff_vecs_t geojson_vecs = {
ff_type_file,
{ (ff_cap)(/*ff_cap_read | */ff_cap_write), ff_cap_write, ff_cap_none },
geojson_rd_init,
geojson_wr_init,
geojson_rd_deinit,
geojson_wr_deinit,
geojson_read,
geojson_write,
NULL,
geojson_args,
CET_CHARSET_UTF8, 0 /* CET-REVIEW */
};

+ 7
- 0
gui/app.pro View File

@@ -28,6 +28,13 @@ unix:OBJECTS_DIR = objects
unix:RCC_DIR = objects

mac:LIBS += -framework IOKit -framework CoreFoundation
unix {
CONFIG += link_pkgconfig
packagesExist(libudev) {
DEFINES += HAVE_UDEV
PKGCONFIG += libudev
}
}

UI_DIR = tmp


+ 69
- 1
gui/serial_unix.cc View File

@@ -21,6 +21,68 @@
#include "mainwindow.h"
#if !defined (Q_OS_MAC) // FIXME: find a better way to hide this on Mac.

#ifdef HAVE_UDEV
#include <libudev.h>
#include <QDebug>

static QStringList dynamicDevices()
{
struct udev *udev = udev_new();
if(!udev) {
qDebug() << "Can't create udev";
return QStringList();
}

QSet<QString> devices;

struct udev_enumerate *enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "tty");
udev_enumerate_scan_devices(enumerate);

struct udev_list_entry *device;
udev_list_entry_foreach(device, udev_enumerate_get_list_entry(enumerate)) {
const char *path = udev_list_entry_get_name(device);
struct udev_device *dev = udev_device_new_from_syspath(udev, path);

bool okMaj, okMin;
int major = QString(udev_device_get_property_value(dev, "MAJOR")).toInt(&okMaj);
int minor = QString(udev_device_get_property_value(dev, "MINOR")).toInt(&okMin);
if(!okMaj || !okMin) {
major = -1;
minor = -1;
}

// see Documentation/devices.txt in the linux tree
if( !( (major == 4 || major == 5) && 0 <= minor && minor <= 63 ) ) {
devices << QString::fromUtf8(udev_device_get_devnode(dev));
/*
udev_device_get_sysattr_list_entry(dev);
udev_device_get_tags_list_entry(dev);
struct udev_list_entry *prop;
qDebug() << "Device Node Path:" << udev_device_get_devnode(dev) << path;
udev_list_entry_foreach(prop, udev_device_get_properties_list_entry(dev)) {
qDebug() << " " << udev_list_entry_get_name(prop)
<< "=>" << udev_list_entry_get_value(prop);
}
*/
}
udev_device_unref(dev);
}
udev_enumerate_unref(enumerate);
udev_unref(udev);

QStringList list = devices.toList();
qSort(list);
return list;
}
#else
static QStringList dynamicDevices()
{
return QStringList();
}
#endif


static const char *deviceNames[] = {
"/dev/ttyS0",
"/dev/ttyS1",
@@ -33,8 +95,14 @@ static const char *deviceNames[] = {

void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
{
const QStringList devices = dynamicDevices();
box->addItems(devices);

for (int i=0; deviceNames[i]; i++) {
box->addItem(deviceNames[i]);
if(!devices.contains(deviceNames[i])) {
box->addItem(deviceNames[i]);
}
}
}

#endif

+ 8
- 6
height.cc View File

@@ -109,12 +109,14 @@ correct_height(const Waypoint* wpt)
{
Waypoint* waypointp = (Waypoint*) wpt;

if (addopt) {
waypointp->altitude += addf;
}

if (wgs84tomslopt) {
waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude);
if (waypointp->altitude != unknown_alt) {
if (addopt) {
waypointp->altitude += addf;
}
if (wgs84tomslopt) {
waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude);
}
}
}


+ 1
- 1
jeeps/gpsserial.cc View File

@@ -82,7 +82,7 @@ void GPS_Serial_Error(const char* mb, ...)
*s++ = ':';
*s++ = ' ';

FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0,
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0,
GetLastError(), 0, s, sizeof(msg) - b - 2, 0);
GPS_Error(msg);


+ 1
- 1
jeeps/gpsusbwin.cc View File

@@ -189,7 +189,7 @@ HANDLE garmin_usb_start(HDEVINFO hdevinfo, SP_DEVICE_INTERFACE_DATA* infodata)
static char** get_garmin_mountpoints(void)
{
#define BUFSIZE 512
TCHAR szTemp[MAX_PATH];
char szTemp[MAX_PATH];
char* p = szTemp;
char** dlist = (char **) xmalloc(sizeof(*dlist));


+ 14
- 13
kml.cc View File

@@ -868,15 +868,21 @@ static void kml_output_lookat(const Waypoint* waypointp)
writer->writeEndElement(); // Close LookAt tag
}

static void kml_output_positioning(void)
static void kml_output_positioning(bool tessellate)
{
// These elements must be output as a sequence, i.e. in order.
if (extrude) {
writer->writeTextElement("extrude", "1");
}

if (tessellate) {
writer->writeTextElement("tessellate", "1");
}

if (floating) {
writer->writeTextElement("altitudeMode", "absolute");
}

if (extrude) {
writer->writeTextElement("extrude", "1");
}
}

/* Output something interesing when we can for route and trackpoints */
@@ -1022,11 +1028,7 @@ static void kml_output_point(const Waypoint* waypointp, kml_point_type pt_type)
}

writer->writeStartElement("Point");
kml_output_positioning();

if (extrude) {
writer->writeTextElement("extrude", "1");
}
kml_output_positioning(false);
kml_write_coordinates(waypointp);
writer->writeEndElement(); // Close Point tag

@@ -1092,8 +1094,7 @@ static void kml_output_tailer(const route_head* header)
writer->writeEndElement(); // Close LineString tag
}
writer->writeStartElement("LineString");
kml_output_positioning();
writer->writeTextElement("tessellate","1");
kml_output_positioning(true);
writer->writeStartElement("coordinates");
writer->writeCharacters("\n");
}
@@ -1625,7 +1626,7 @@ static void kml_waypt_pr(const Waypoint* waypointp)

// Location
writer->writeStartElement("Point");
kml_output_positioning();
kml_output_positioning(false);
kml_write_coordinates(waypointp);
writer->writeEndElement(); // Close Point tag

@@ -1760,7 +1761,7 @@ static void kml_mt_hdr(const route_head* header)
writer->writeOptionalTextElement("name", header->rte_name);
writer->writeTextElement("styleUrl", "#multiTrack");
writer->writeStartElement("gx:Track");
kml_output_positioning();
kml_output_positioning(false);

QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) {
Waypoint* tpt = (Waypoint*)elem;

+ 69
- 34
mtk_logger.cc View File

@@ -227,6 +227,7 @@ static char* OPT_erase; /* erase ? command option */
static char* OPT_erase_only; /* erase_only ? command option */
static char* OPT_log_enable; /* enable ? command option */
static char* csv_file; /* csv ? command option */
static char* OPT_block_size_kb; /* block_size_kb ? command option */
static enum MTK_DEVICE_TYPE mtk_device = MTK_LOGGER;

struct mtk_loginfo mtk_info;
@@ -267,6 +268,10 @@ static arglist_t mtk_sargs[] = {
"csv", &csv_file, "MTK compatible CSV output file",
NULL, ARGTYPE_STRING, ARG_NOMINMAX
},
{
"block_size_kb", &OPT_block_size_kb, "Size of blocks in KB to request from device",
"1", ARGTYPE_INT, "1", "64"
},
ARG_TERMINATOR
};

@@ -531,8 +536,9 @@ static void mtk_read(void)
char cmd[256];
char* line = NULL;
unsigned char crc, *data = NULL;
int cmdLen, j, bsize, i, len, ff_len, null_len, rc, init_scan, retry_cnt, log_enabled;
unsigned int line_size, data_size, data_addr, addr, addr_max;
int cmdLen, i, len, rc, init_scan, retry_cnt, log_enabled;
unsigned int j, bsize, scan_bsize, read_bsize_kb, read_bsize, scan_step, ff_len, null_len, chunk_size;
unsigned int line_size, data_size, data_addr, addr, addr_max, rcvd_addr, rcvd_bsize;
unsigned long dsize, dpos = 0;
FILE* dout;
char* fusage = NULL;
@@ -608,11 +614,25 @@ static void mtk_read(void)
}
}

bsize = 0x0400;
scan_step = 0x10000;
scan_bsize = 0x0400;
read_bsize_kb = strtol(OPT_block_size_kb, NULL, 10);
if (errno == ERANGE || read_bsize_kb < 1) {
read_bsize_kb = 1;
} else if (read_bsize_kb > 64) {
read_bsize_kb = 64;
}
read_bsize = read_bsize_kb * 1024;
dbg(2, "Download block size is %d bytes\n", read_bsize);
if (init_scan) {
bsize = scan_bsize;
} else {
bsize = read_bsize;
}
addr = 0x0000;

line_size = 2*bsize + 32; // logdata as nmea/hex.
data_size = bsize + 32;
line_size = 2*read_bsize + 32; // logdata as nmea/hex.
data_size = read_bsize + 32;
if ((line = (char*) xmalloc(line_size)) == NULL) {
fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size);
}
@@ -636,6 +656,7 @@ mtk_retry:
do_send_cmd(cmd, cmdLen);

memset(line, '\0', line_size);
rcvd_addr = addr;
do {
rc = gbser_read_line(fd, line, line_size-1, TIMEOUT, 0x0A, 0x0D);
if (rc != gbser_OK) {
@@ -654,12 +675,12 @@ mtk_retry:
if (strncmp(line, "$PMTK182,8", 10) == 0) { // $PMTK182,8,00005000,FFFFFFF
retry_cnt = 0;
data_addr = strtoul(&line[11], NULL, 16);
fseek(dout, data_addr, SEEK_SET);
// fixme - we should check if all data before data_addr is already received
i = 20;
j = 0;
j = data_addr - addr;
ff_len = 0; // number of 0xff bytes.
null_len = 0; // number of 0x00 bytes.
while (i < (len-3)) {
while (i + 3 < len && j < data_size) {
data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 +
(isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA));
if (data[j] == 0xff) {
@@ -671,34 +692,24 @@ mtk_retry:
i += 2;
j++;
}
rcvd_addr = addr + j;
chunk_size = rcvd_addr - data_addr;
if (init_scan) {
if (dsize > 0 && addr < dsize) {
fseek(dout, addr, SEEK_SET);
if (fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0) {
dpos = addr;
dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr);
} else {
dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr);
}
}
if (ff_len == j) { // data in sector - we've found max sector..
addr_max = addr;
if (ff_len == chunk_size) { // data in sector - we've found max sector..
addr_max = data_addr;
rcvd_addr = data_addr;
dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10);
break;
}
len = 0;
} else {
if (null_len == j) { // 0x00 block - bad block....
if (null_len == chunk_size) { // 0x00 block - bad block....
fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line);
}
if (fwrite(data, 1, j, dout) != j) {
fatal(MYNAME ": Failed to write temp. binary file\n");
}
if (ff_len == j) { // 0xff block - read complete...
if (ff_len == chunk_size) { // 0xff block - read complete...
len = ff_len;
addr_max = addr;
addr_max = data_addr;
rcvd_addr = data_addr;
break;
} else {
len = 0;
}
}
} else if (strncmp(line, "$PMTK001,182,7,", 15) == 0) { // Command ACK
@@ -711,15 +722,38 @@ mtk_retry:
}
}
}
} while (len != 0);
} while (rcvd_addr < addr + bsize);

rcvd_bsize = rcvd_addr - addr;
dbg(2, "Received %d bytes\n", rcvd_bsize);

if (init_scan) {
addr += 0x10000;
if (addr >= addr_max) { // initial scan complete...
init_scan = 0;
addr = dpos;
if (dsize > 0 && addr < dsize) {
fseek(dout, addr, SEEK_SET);
if (fread(line, 1, rcvd_bsize, dout) == rcvd_bsize && memcmp(line, data, rcvd_bsize) == 0) {
dpos = addr;
dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr);
} else {
dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr);
init_scan = 0;
addr = dpos;
bsize = read_bsize;
}
}
if (init_scan) {
addr += scan_step;
if (addr >= addr_max) { // initial scan complete...
init_scan = 0;
addr = dpos;
bsize = read_bsize;
}
}
} else {
addr += bsize;
fseek(dout, addr, SEEK_SET);
if (fwrite(data, 1, rcvd_bsize, dout) != rcvd_bsize) {
fatal(MYNAME ": Failed to write temp. binary file\n");
}
addr += rcvd_bsize;
if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) {
int perc;
perc = 100 - 100*(addr_max-addr)/addr_max;
@@ -731,6 +765,7 @@ mtk_retry:
}
}
if (dout != NULL) {
ftruncate(fileno(dout), addr_max);
fclose(dout);
}
if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) {

+ 149
- 0
reference/geocaching~json.json View File

@@ -0,0 +1,149 @@
{
"features": [
{
"geometry": {
"coordinates": [
-87.134699999999995,
35.972033332999999
],
"type": "Point"
},
"properties": {
"description": "Mountain Bike Heaven by susy1313",
"name": "GCEBB",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=3771",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.679550000000006,
36.090683333000001
],
"type": "Point"
},
"properties": {
"description": "The Troll by a182pilot & Family",
"name": "GC1A37",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=6711",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.620116667000005,
35.996266667
],
"type": "Point"
},
"properties": {
"description": "Dive Bomber by JoGPS & family",
"name": "GC1C2B",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=7211",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.648616666999999,
36.038483333000002
],
"type": "Point"
},
"properties": {
"description": "FOSTER by JoGPS & Family",
"name": "GC25A9",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=9641",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.741766666999993,
36.112183332999997
],
"type": "Point"
},
"properties": {
"description": "Logan Lighthouse by JoGps & Family",
"name": "GC2723",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=10019",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.790516667000006,
36.064083332999999
],
"type": "Point"
},
"properties": {
"description": "Ganier Cache by Susy1313",
"name": "GC2B71",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=11121",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.809733332999997,
36.087766666999997
],
"type": "Point"
},
"properties": {
"description": "Shy's Hill by FireFighterEng33",
"name": "GC309F",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=12447",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.891999999999996,
36.057499999999997
],
"type": "Point"
},
"properties": {
"description": "GittyUp by JoGPS / Warner Parks",
"name": "GC317A",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=12666",
"urlname": "Cache Details"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-86.867283333000003,
36.082799999999999
],
"type": "Point"
},
"properties": {
"description": "Inlighting by JoGPS / Warner Parks",
"name": "GC317D",
"url": "http://www.geocaching.com/seek/cache_details.asp?ID=12669",
"urlname": "Cache Details"
},
"type": "Feature"
}
],
"type": "FeatureCollection"
}

+ 211
- 0
reference/track/segmented_tracks~geojson.json View File

@@ -0,0 +1,211 @@
{
"features": [
{
"geometry": {
"coordinates": [
[
-86.844139609999999,
35.826145640999997
],
[
-86.843587434,
35.824858661
],
[
-86.843868790000002,
35.825508290000002
],
[
-86.843399026,
35.825659280000004
],
[
-86.843647121000004,
35.826200632000003
],
[
-86.843137330000005,
35.825023495000003
],
[
-86.842846089999995,
35.825764722999999
],
[
-86.842592054999997,
35.825212972999999
],
[
-86.842083658999996,
35.825409925000002
],
[
-86.842527868000005,
35.826530337999998
],
[
-86.841916886999996,
35.826227992
],
[
-86.841882385999995,
35.826752995
],
[
-86.841275397999993,
35.825879004999997
],
[
-86.840954045999993,
35.826506488
],
[
-86.840764704999998,
35.826053416000001
],
[
-86.840254282000004,
35.826187447999999
],
[
-86.840499359999995,
35.826664997000002
],
[
-86.840954045999993,
35.826506488
],
[
-86.839682814,
35.826441473000003
],
[
-86.840327092999999,
35.827349034999997
],
[
-86.839510243000007,
35.827133899000003
],
[
-86.839451225000005,
35.827576071000003
],
[
-86.838781982,
35.826743954000001
]
],
"type": "LineString"
},
"properties": {
"name": "No Times"
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
[
-86.844139609999999,
35.836145641000002
],
[
-86.843587434,
35.834858660999998
],
[
-86.843868790000002,
35.83550829
],
[
-86.843399026,
35.835659280000002
],
[
-86.843647121000004,
35.836200632000001
],
[
-86.843137330000005,
35.835023495000002
],
[
-86.842846089999995,
35.835764722999997
],
[
-86.842592054999997,
35.835212972999997
],
[
-86.842083658999996,
35.835409925
],
[
-86.842527868000005,
35.836530338000003
],
[
-86.841916886999996,
35.836227991999998
],
[
-86.841882385999995,
35.836752994999998
],
[
-86.841275397999993,
35.835879005000002
],
[
-86.840954045999993,
35.836506487999998
],
[
-86.840764704999998,
35.836053415999999
],
[
-86.840254282000004,
35.836187447999997
],
[
-86.840499359999995,
35.836664997
],
[
-86.840954045999993,
35.836506487999998
],
[
-86.839682814,
35.836441473000001
],
[
-86.840327092999999,
35.837349035000003
],
[
-86.839510243000007,
35.837133899000001
],
[
-86.839451225000005,
35.837576071000001
],
[
-86.838781982,
35.836743953999999
]
],
"type": "LineString"
},
"properties": {
"name": "With Times"
},
"type": "Feature"
}
],
"type": "FeatureCollection"
}

+ 2
- 2
skytraq.cc View File

@@ -77,11 +77,11 @@ arglist_t skytraq_args[] = {
},
{
"targetlocation", &opt_set_location, "Set location finder target location as lat,lng",
"", ARGTYPE_STRING, "", ""
NULL, ARGTYPE_STRING, "", ""
},
{
"configlog", &opt_configure_logging, "Configure logging parameter as tmin:tmax:dmin:dmax",
"", ARGTYPE_STRING, "", ""
NULL, ARGTYPE_STRING, "", ""
},
{
"baud", &opt_dlbaud, "Baud rate used for download",

+ 10
- 0
testo.d/geojson.test View File

@@ -0,0 +1,10 @@
#
# As this format is initially write-only, we're comparing our own "golden"
# output to what the newly built writer creates.
#

gpsbabel -i gpx -f ${REFERENCE}/geocaching.gpx -o geojson -F ${TMPDIR}/geo.json
compare ${REFERENCE}/geocaching~json.json ${TMPDIR}/geo.json

gpsbabel -i gpx -f ${REFERENCE}/track/segmented_tracks.gpx -o geojson -F ${TMPDIR}/track.json
compare ${REFERENCE}/track/segmented_tracks~geojson.json ${TMPDIR}/track.json

+ 8
- 0
vecs.cc View File

@@ -54,6 +54,7 @@ extern ff_vecs_t gcdb_vecs;
extern ff_vecs_t gdb_vecs;
extern ff_vecs_t geoniche_vecs;
extern ff_vecs_t geo_vecs;
extern ff_vecs_t geojson_vecs;
extern ff_vecs_t globalsat_sport_vecs;
extern ff_vecs_t glogbook_vecs;
extern ff_vecs_t google_dir_vecs;
@@ -1077,6 +1078,13 @@ vecs_t vec_list[] = {
"trc",
NULL,
},
{
&geojson_vecs,
"geojson",
"GeoJson",
"json",
NULL,
},
{
&ggv_bin_vecs,
"ggv_bin",

+ 6
- 1
xmldoc/filters/options/track-speed.xml View File

@@ -3,7 +3,12 @@ This option computes a value for the GPS speed at each trackpoint.
This is most useful with trackpoints from formats that don't support
speed information or for trackoints synthesized by the
<link linkend="filter_interpolate">interpolate</link>
filter. The speed at each trackpoint is the average speed from the
filter.</para>
<para>
The speed at each trackpoint is the average speed from the
previous trackpoint (distance divided by time). The first trackpoint
in each track is assigned a speed of "unknown."
</para>
<para>
The unit of speed is meters per second.
</para>

+ 31
- 0
xmldoc/formats/geojson.xml View File

@@ -0,0 +1,31 @@
<para>
This module supports a subset of the <ulink url="http://geojson.org/">GeoJSON</ulink> format.
</para>
<para>
GeoJSON is a poor fit for GPSBabel's internal data structures as GPSBabel
was designed more around common GPS features (waypoints, tracks, routes)
than about GIS-style concepts like MultiPolygons or Geometry Collections.
In reality, for all but the most simple uses (such as converting a format
that GPSBabel supports well to something like Leaflet, you should not expect
high fidelity transfers through this format.
</para>
<para>
Initially, only write support for waypoints and tracks is available.
Waypoints are converted to a FeatureCollection of Points.
The properties for name and description are written, where available.
Tracks are converted to a LineString.
</para>
<para>
Potential future work includes the ability to read Point Features and/or
LineStrings as these would map into our concept of waypoints and
routes/tracks.
The potentially nested/recursive nature of GeoJSON in general would be
an awkward implementation.
</para>
<para>
Initial development was free-handed by looking at the <ulink url="https://tools.ietf.org/html/rfc7946 ">GeoJSON RFC</ulink>. Corner cases were handled by
using <ulink url="http://www.gdal.org/ogr2ogr.html">GDAL's ogr2ogr</ulink>
to convert GPX to JSON and compare the output. The results were then
<ulink url="http://geojsonlint.com/">JSON validated</ulink> and viewed on
<ulink url="http://geojson.io/">JSON web viewer</ulink>.
</para>

+ 5
- 0
xmldoc/formats/options/geojson-compact.xml View File

@@ -0,0 +1,5 @@
<para>
This option, when set, reduces the amount of whitespace in the
generated GeoJSON. This reduces the size, especially when uncompressed,
but reduces the readibility to humans.
</para>

Loading…
Cancel
Save