From 30a345577a644125502f6e4f8b58ea3077ec8dad Mon Sep 17 00:00:00 2001 From: Robert Lipe <robertlipe@gpsbabel.org> Date: Mon, 4 Sep 2017 23:20:00 -0500 Subject: [PATCH] Prefer QStringLiteral over implicit conversion from Latin1 for Q5 5.9. Based on work by Bernd Zeimetz. --- gpx.cc | 14 +++++++------- magproto.cc | 6 +++--- unicsv.cc | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gpx.cc b/gpx.cc index 3b3b963c..36701e52 100644 --- gpx.cc +++ gpx.cc @@ -494,7 +494,7 @@ tag_cache_desc(const QXmlStreamAttributes& attr) { cache_descr_is_html = 0; if (attr.hasAttribute("html")) { - if (attr.value("html").toString().compare("True") == 0) { + if (attr.value("html").toString() == QStringLiteral("True")) { cache_descr_is_html = 1; } } @@ -509,16 +509,16 @@ tag_gs_cache(const QXmlStreamAttributes& attr) gc_data->id = attr.value("id").toString().toInt(); } if (attr.hasAttribute("available")) { - if (attr.value("available").toString().compare("True", Qt::CaseInsensitive) == 0) { + if (attr.value("available").toString().compare(QStringLiteral("True"), Qt::CaseInsensitive) == 0) { gc_data->is_available = status_true; - } else if (attr.value("available").toString().compare("False", Qt::CaseInsensitive) == 0) { + } else if (attr.value("available").toString().compare(QStringLiteral("False"), Qt::CaseInsensitive) == 0) { gc_data->is_available = status_false; } } if (attr.hasAttribute("archived")) { - if (attr.value("archived").toString().compare("True", Qt::CaseInsensitive) == 0) { + if (attr.value("archived").toString().compare(QStringLiteral("True"), Qt::CaseInsensitive) == 0) { gc_data->is_archived = status_true; - } else if (attr.value("archived").toString().compare("False", Qt::CaseInsensitive) == 0) { + } else if (attr.value("archived").toString().compare(QStringLiteral("False"), Qt::CaseInsensitive) == 0) { gc_data->is_archived = status_false; } } @@ -972,7 +972,7 @@ gpx_end(const QString& el) * last date we saw in this log. */ case tt_cache_log_type: - if ((cdatastr.compare("Found it") == 0) && + if ((cdatastr.compare(QStringLiteral("Found it")) == 0) && (0 == wpt_tmp->gc_data->last_found.toTime_t())) { wpt_tmp->AllocGCData()->last_found = gc_log_date; } @@ -1423,7 +1423,7 @@ fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) fprint_xml_chain(tag->child, wpt); } if (wpt && wpt->gc_data->exported.isValid() && - tag->tagname.compare("groundspeak:cache") == 0) { + tag->tagname.compare(QStringLiteral("groundspeak:cache")) == 0) { writer->writeTextElement("time", wpt->gc_data->exported.toPrettyString()); } diff --git a/magproto.cc b/magproto.cc index 7c82e9fb..0deb7f33 100644 --- magproto.cc +++ magproto.cc @@ -819,11 +819,11 @@ mag_rd_init_common(const QString& portname) */ QString exten = QFileInfo(curfname).suffix(); if (exten.length() > 0) { - if (0 == exten.compare("upt", Qt::CaseInsensitive)) { + if (0 == exten.compare(QStringLiteral("upt"), Qt::CaseInsensitive)) { extension_hint = WPTDATAMASK; - } else if (0 == exten.compare("log", Qt::CaseInsensitive)) { + } else if (0 == exten.compare(QStringLiteral("log"), Qt::CaseInsensitive)) { extension_hint = TRKDATAMASK; - } else if (0 == exten.compare("rte", Qt::CaseInsensitive)) { + } else if (0 == exten.compare(QStringLiteral("rte"), Qt::CaseInsensitive)) { extension_hint = RTEDATAMASK; } } diff --git a/unicsv.cc b/unicsv.cc index 4a7d78ed..6312e9d2 100644 --- unicsv.cc +++ unicsv.cc @@ -430,13 +430,13 @@ unicsv_parse_time(const QString& str, int* msec, time_t* date) static status_type unicsv_parse_status(const QString& str) { - if (str.compare("true", Qt::CaseInsensitive) == 0 || - str.compare("yes", Qt::CaseInsensitive) == 0 || + if (str.compare(QStringLiteral("true"), Qt::CaseInsensitive) == 0 || + str.compare(QStringLiteral("yes"), Qt::CaseInsensitive) == 0 || str == "1") { return status_true; } - if (str.compare("false", Qt::CaseInsensitive) == 0 || - str.compare("no", Qt::CaseInsensitive) == 0 || + if (str.compare(QStringLiteral("false"), Qt::CaseInsensitive) == 0 || + str.compare(QStringLiteral("no"), Qt::CaseInsensitive) == 0 || str == "0") { return status_false; } From 604178aa8ad4d3c3ad218df24c1e9a6a1f683bb3 Mon Sep 17 00:00:00 2001 From: Harel Mazor <harel.mazor@gmail.com> Date: Tue, 24 Jan 2017 00:35:04 +0200 Subject: [PATCH] Added geojson read capablity, moved magic strings to constants, fixed windows compilation issues. --- GPSBabel.pro | 4 +- geojson.cc | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- mtk_logger.cc | 5 ++ tef_xml.cc | 24 +++---- 4 files changed, 200 insertions(+), 41 deletions(-) diff --git a/GPSBabel.pro b/GPSBabel.pro index 4b8e378a..1c06c4ab 100644 --- geojson.cc +++ geojson.cc @@ -23,11 +23,30 @@ #include "src/core/file.h" static gbfile* ofd; +static QString input_file_name; static const char MYNAME[] = "geojson"; static char* compact_opt = NULL; static QJsonObject* track_object = NULL; static QJsonArray* track_coords = NULL; +static const QString FEATURE_COLLECTION = QStringLiteral("FeatureCollection"); +static const QString FEATURE = QStringLiteral("Feature"); +static const QString POINT = QStringLiteral("Point"); +static const QString MULTIPOINT = QStringLiteral("MultiPoint"); +static const QString LINESTRING = QStringLiteral("LineString"); +static const QString MULTILINESTRING = QStringLiteral("MultiLineString"); +static const QString POLYGON = QStringLiteral("Polygon"); +static const QString MULTIPOLYGON = QStringLiteral("MultiPolygon"); +static const QString TYPE = QStringLiteral("type"); +static const QString FEATURES = QStringLiteral("features"); +static const QString COORDINATES = QStringLiteral("coordinates"); +static const QString GEOMETRY = QStringLiteral("geometry"); +static const QString PROPERTIES = QStringLiteral("properties"); +static const QString NAME = QStringLiteral("name"); +static const QString DESCRIPTION = QStringLiteral("description"); +static const QString URL = QStringLiteral("url"); +static const QString URLNAME = QStringLiteral("urlname"); + static arglist_t geojson_args[] = { {"compact", &compact_opt, "Compact Output. Default is off.", NULL, ARGTYPE_BOOL, ARG_NOMINMAX } , @@ -36,6 +55,7 @@ static arglist_t geojson_args[] = { static void geojson_rd_init(const QString& fname) { + input_file_name = fname; } QJsonArray* feature_collection = nullptr; @@ -48,57 +68,55 @@ geojson_wr_init(const QString& fname) { 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); + geometry[TYPE] = POINT; + QJsonArray coordinates; + coordinates.append(waypoint->longitude); + coordinates.append(waypoint->latitude); if (waypoint->altitude != unknown_alt && waypoint->altitude != 0) { - coords.append(waypoint->altitude); + coordinates.append(waypoint->altitude); } + geometry[COORDINATES] = coordinates; - geometry[kType] = QStringLiteral("Point"); - geometry[QStringLiteral("coordinates")] = coords; - object[QStringLiteral("geometry")] = geometry; + QJsonObject feature; + feature[TYPE] = FEATURE; + feature[GEOMETRY] = geometry; // Build up the properties. QJsonObject properties; if (!waypoint->shortname.isEmpty()) { - properties["name"] = waypoint->shortname; + properties[NAME] = waypoint->shortname; } if (!waypoint->description.isEmpty()) { - properties["description"] = waypoint->description; + properties[DESCRIPTION] = waypoint->description; } if (waypoint->HasUrlLink()) { UrlLink link = waypoint->GetUrlLink(); if (!link.url_.isEmpty()) { - properties["url"] = link.url_; + properties[URL] = link.url_; } if (!link.url_link_text_.isEmpty()) { - properties["urlname"] = link.url_link_text_; + properties[URLNAME] = link.url_link_text_; } } if (!properties.empty()) { - object["properties"] = properties; + feature[PROPERTIES] = properties; } - feature_collection->append(object); + feature_collection->append(feature); } static void geojson_rd_deinit() { + gbfclose(ofd); + ofd = NULL; } static void geojson_wr_deinit(void) { QJsonObject object; - object[QStringLiteral("type")] = QStringLiteral("FeatureCollection"); - object[QStringLiteral("features")] = *feature_collection; + object[TYPE] = FEATURE_COLLECTION; + object[FEATURES] = *feature_collection; QJsonDocument save(object); QJsonDocument::JsonFormat style; @@ -111,21 +129,157 @@ geojson_wr_deinit(void) { feature_collection = nullptr; } +static Waypoint* +waypoint_from_coordinates(const QJsonArray& coordinates) +{ + auto waypoint = new Waypoint(); + waypoint->latitude = coordinates.at(1).toDouble(); + waypoint->longitude = coordinates.at(0).toDouble(); + if (coordinates.size() > 2) + { + waypoint->altitude = coordinates.at(3).toDouble(); + } + return waypoint; +} + +static void +routes_from_polygon_coordinates(const QJsonArray& polygon) +{ + for (auto lineStringIterator = polygon.begin(); lineStringIterator != polygon.end(); ++lineStringIterator) + { + QJsonArray coordinates = (*lineStringIterator).toArray(); + auto route = route_head_alloc(); + route_add_head(route); + for (auto coordinates_iterator = coordinates.begin(); coordinates_iterator != coordinates.end(); ++coordinates_iterator) + { + auto waypoint = waypoint_from_coordinates((*coordinates_iterator).toArray()); + route_add_wpt(route, waypoint); + } + } +} + static void geojson_read(void) { + QFile file; + file.setFileName(input_file_name); + file.open(QIODevice::ReadOnly | QIODevice::Text); + QString file_content = file.readAll(); + file.close(); + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(file_content.toUtf8(), &error); + QJsonObject rootObject = document.object(); + + if (rootObject[TYPE] != FEATURE_COLLECTION) + { + return; + } + QJsonArray features = rootObject.value(FEATURES).toArray(); + for (auto iterator = features.begin(); iterator != features.end(); ++iterator) + { + QJsonObject feature = (*iterator).toObject(); + QJsonObject properties = (feature.value(PROPERTIES)).toObject(); + QString name; + QString description; + if (!properties.empty()) + { + if (properties.contains(NAME)) + { + name = properties[NAME].toString(); + } + if (properties.contains(DESCRIPTION)) + { + description = properties[DESCRIPTION].toString(); + } + } + + QJsonObject geometry = feature.value(GEOMETRY).toObject(); + auto geometry_type = geometry[TYPE]; + if (geometry_type == POINT) + { + QJsonArray coordinates = geometry.value(COORDINATES).toArray(); + auto waypoint = waypoint_from_coordinates(coordinates); + waypoint->shortname = name; + waypoint->description = description; + if (properties.contains(URL)) + { + QString url = properties[URL].toString(); + if (properties.contains(URLNAME)) + { + QString url_text = properties[URLNAME].toString(); + waypoint->AddUrlLink(UrlLink(url, url_text)); + } + else + { + waypoint->AddUrlLink(UrlLink(url)); + } + } + waypt_add(waypoint); + } + else if (geometry_type == MULTIPOINT) + { + QJsonArray coordinates = geometry.value(COORDINATES).toArray(); + for (auto coordinates_iterator = coordinates.begin(); coordinates_iterator != coordinates.end(); ++coordinates_iterator) + { + auto waypoint = waypoint_from_coordinates((*coordinates_iterator).toArray()); + waypt_add(waypoint); + } + } + else if (geometry_type == LINESTRING) + { + QJsonArray coordinates = geometry.value(COORDINATES).toArray(); + auto route = route_head_alloc(); + route->rte_name = name; + route_add_head(route); + for (auto coordinates_iterator = coordinates.begin(); coordinates_iterator != coordinates.end(); ++coordinates_iterator) + { + auto waypoint = waypoint_from_coordinates((*coordinates_iterator).toArray()); + route_add_wpt(route, waypoint); + } + } + else if (geometry_type == POLYGON) + { + QJsonArray polygon = geometry.value(COORDINATES).toArray(); + routes_from_polygon_coordinates(polygon); + } + else if (geometry_type == MULTIPOLYGON) + { + QJsonArray polygons = geometry.value(COORDINATES).toArray(); + for (auto polygons_iterator = polygons.begin(); polygons_iterator != polygons.end(); ++polygons_iterator) + { + QJsonArray polygon = (*polygons_iterator).toArray(); + routes_from_polygon_coordinates(polygon); + } + } + else if (geometry_type == MULTILINESTRING) + { + QJsonArray line_strings = geometry.value(COORDINATES).toArray(); + for (auto lineStringIterator = line_strings.begin(); lineStringIterator != line_strings.end(); ++lineStringIterator) + { + QJsonArray coordinates = (*lineStringIterator).toArray(); + auto route = route_head_alloc(); + track_add_head(route); + for (auto coordinates_iterator = coordinates.begin(); coordinates_iterator != coordinates.end(); ++coordinates_iterator) + { + auto waypoint = waypoint_from_coordinates((*coordinates_iterator).toArray()); + route_add_wpt(route, waypoint); + } + } + } + } } + static void geojson_track_hdr(const route_head* track) { track_object = new QJsonObject(); - (*track_object)[QStringLiteral("type")] = QStringLiteral("Feature"); + (*track_object)[TYPE] = FEATURE; track_coords = new QJsonArray(); QJsonObject properties; if (!track->rte_name.isEmpty()) { - properties["name"] = track->rte_name; + properties[NAME] = track->rte_name; } - (*track_object)["properties"] = properties; + (*track_object)[PROPERTIES] = properties; } static void geojson_track_disp(const Waypoint* trackpoint) { @@ -141,9 +295,9 @@ static void geojson_track_disp(const Waypoint* trackpoint) { 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; + geometry[TYPE] = LINESTRING; + geometry[COORDINATES] = *track_coords; + (*track_object)[GEOMETRY] = geometry; feature_collection->append(*track_object); delete track_object; track_object = NULL; diff --git a/mtk_logger.cc b/mtk_logger.cc index 29a2680c..d68fe6db 100644 --- mtk_logger.cc +++ mtk_logger.cc @@ -69,6 +69,11 @@ #define MYNAME "mtk_logger" +#ifdef __WIN32__ +#include <io.h> +#define ftruncate _chsize +#endif + /* MTK packet id's -- currently unused... */ enum MTK_NMEA_PACKET { PMTK_TEST = 0, diff --git a/tef_xml.cc b/tef_xml.cc index b32d69b3..37dd85ba 100644 --- tef_xml.cc +++ tef_xml.cc @@ -72,11 +72,11 @@ tef_start(xg_string args, const QXmlStreamAttributes* attrv) bool valid = false; foreach(QXmlStreamAttribute attr, *attrv) { - if (attr.name().compare("Comment", Qt::CaseInsensitive) == 0) { - if (attr.value().compare("TourExchangeFormat", Qt::CaseInsensitive) == 0) { + if (attr.name().compare(QString("Comment"), Qt::CaseInsensitive) == 0) { + if (attr.value().compare(QString("TourExchangeFormat"), Qt::CaseInsensitive) == 0) { valid = true; } - } else if (attr.name().compare("Version", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("Version"), Qt::CaseInsensitive) == 0) { version = attr.value().toString().toDouble(); } } @@ -95,9 +95,9 @@ tef_header(xg_string args, const QXmlStreamAttributes* attrv) { route = route_head_alloc(); foreach(QXmlStreamAttribute attr, *attrv) { - if (attr.name().compare("Name", Qt::CaseInsensitive) == 0) { + if (attr.name().compare(QString("Name"), Qt::CaseInsensitive) == 0) { route->rte_name = attr.value().toString().trimmed(); - } else if (attr.name().compare("Software", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("Software"), Qt::CaseInsensitive) == 0) { route->rte_desc = attr.value().toString().trimmed(); } } @@ -248,20 +248,20 @@ tef_item_start(xg_string args, const QXmlStreamAttributes* attrv) QString attrstr = attr.value().toString(); QByteArray attrtext = attrstr.toUtf8(); - if (attr.name().compare("SegDescription", Qt::CaseInsensitive) == 0) { + if (attr.name().compare(QString("SegDescription"), Qt::CaseInsensitive) == 0) { wpt_tmp->shortname = attrstr.trimmed(); - } else if (attr.name().compare("PointDescription", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("PointDescription"), Qt::CaseInsensitive) == 0) { wpt_tmp->description = attrstr.trimmed(); - } else if (attr.name().compare("ViaStation", Qt::CaseInsensitive) == 0 && - attr.value().compare("true", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("ViaStation"), Qt::CaseInsensitive) == 0 && + attr.value().compare(QString("true"), Qt::CaseInsensitive) == 0) { wpt_tmp->wpt_flags.fmt_use = 1; /* only a flag */ /* new in TEF V2 */ - } else if (attr.name().compare("Instruction", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("Instruction"), Qt::CaseInsensitive) == 0) { wpt_tmp->description = attrstr.trimmed(); - } else if (attr.name().compare("Altitude", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("Altitude"), Qt::CaseInsensitive) == 0) { wpt_tmp->altitude = attrstr.toDouble(); - } else if (attr.name().compare("TimeStamp", Qt::CaseInsensitive) == 0) { + } else if (attr.name().compare(QString("TimeStamp"), Qt::CaseInsensitive) == 0) { /* nothing for the moment */ } }