2018-04-15 10:08:50 +02:00
|
|
|
#include "map/gcs.h"
|
|
|
|
#include "oziparsers.h"
|
|
|
|
|
|
|
|
static qint64 delphi2unixMS(double date)
|
|
|
|
{
|
|
|
|
return (qint64)((date - 25569.0) * 86400000);
|
|
|
|
}
|
|
|
|
|
2018-07-24 17:21:45 +02:00
|
|
|
static bool isASCII(const QByteArray &ba)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < ba.size(); i++) {
|
|
|
|
quint8 c = (quint8)ba.at(i);
|
|
|
|
if (c > 0x7f && c != 0xD1)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static QByteArray &decode(QByteArray &ba)
|
|
|
|
{
|
|
|
|
if (isASCII(ba))
|
|
|
|
ba.replace('\xD1', ',');
|
|
|
|
|
|
|
|
return ba;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-15 10:08:50 +02:00
|
|
|
bool PLTParser::parse(QFile *file, QList<TrackData> &tracks,
|
2019-01-31 01:46:53 +01:00
|
|
|
QList<RouteData> &routes, QList<Area> &polygons,
|
|
|
|
QVector<Waypoint> &waypoints)
|
2018-04-15 10:08:50 +02:00
|
|
|
{
|
|
|
|
Q_UNUSED(waypoints);
|
|
|
|
Q_UNUSED(routes);
|
2019-01-31 01:46:53 +01:00
|
|
|
Q_UNUSED(polygons);
|
2018-04-15 10:08:50 +02:00
|
|
|
bool res;
|
|
|
|
const GCS *gcs = 0;
|
|
|
|
|
|
|
|
_errorLine = 1;
|
|
|
|
_errorString.clear();
|
|
|
|
|
|
|
|
tracks.append(TrackData());
|
|
|
|
TrackData &track = tracks.last();
|
2019-02-11 23:28:08 +01:00
|
|
|
track.append(SegmentData());
|
|
|
|
SegmentData &segment = track.last();
|
2018-04-15 10:08:50 +02:00
|
|
|
|
|
|
|
while (!file->atEnd()) {
|
|
|
|
QByteArray line = file->readLine();
|
|
|
|
|
|
|
|
if (_errorLine == 1) {
|
2018-06-02 16:41:27 +02:00
|
|
|
QString fileType(QString::fromUtf8(line).trimmed());
|
|
|
|
if (!fileType.startsWith("OziExplorer Track Point File")) {
|
2018-04-15 10:08:50 +02:00
|
|
|
_errorString = "Not a PLT file";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine == 2) {
|
|
|
|
if (!(gcs = GCS::gcs(QString(line.trimmed())))) {
|
|
|
|
_errorString = "Invalid/unknown datum";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine == 5) {
|
|
|
|
QList<QByteArray> list = line.split(',');
|
|
|
|
if (list.size() >= 4)
|
|
|
|
track.setName(list.at(3));
|
|
|
|
} else if (_errorLine > 6) {
|
|
|
|
QList<QByteArray> list = line.split(',');
|
|
|
|
if (list.size() < 2) {
|
|
|
|
_errorString = "Parse error";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal lat = list.at(0).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lat < -90.0 || lat > 90.0)) {
|
|
|
|
_errorString = "Invalid latitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
qreal lon = list.at(1).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lon < -180.0 || lon > 180.0)) {
|
|
|
|
_errorString = "Invalid longitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Trackpoint tp(gcs->toWGS84(Coordinates(lon, lat)));
|
|
|
|
|
|
|
|
if (list.size() >= 4) {
|
|
|
|
QByteArray field(list.at(3).trimmed());
|
|
|
|
if (!field.isEmpty()) {
|
|
|
|
double elevation = field.toDouble(&res);
|
|
|
|
if (!res) {
|
|
|
|
_errorString = "Invalid elevation";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (elevation != -777)
|
|
|
|
tp.setElevation(elevation * 0.3048);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (list.size() >= 5) {
|
|
|
|
QByteArray field(list.at(4).trimmed());
|
|
|
|
if (!field.isEmpty()) {
|
|
|
|
double date = field.toDouble(&res);
|
|
|
|
if (!res) {
|
|
|
|
_errorString = "Invalid date";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
tp.setTimestamp(QDateTime::fromMSecsSinceEpoch(
|
|
|
|
delphi2unixMS(date)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-11 23:28:08 +01:00
|
|
|
|
|
|
|
segment.append(tp);
|
2018-04-15 10:08:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_errorLine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RTEParser::parse(QFile *file, QList<TrackData> &tracks,
|
2019-01-31 01:46:53 +01:00
|
|
|
QList<RouteData> &routes, QList<Area> &polygons,
|
|
|
|
QVector<Waypoint> &waypoints)
|
2018-04-15 10:08:50 +02:00
|
|
|
{
|
|
|
|
Q_UNUSED(waypoints);
|
|
|
|
Q_UNUSED(tracks);
|
2019-01-31 01:46:53 +01:00
|
|
|
Q_UNUSED(polygons);
|
2018-04-15 10:08:50 +02:00
|
|
|
bool res, record = false;
|
|
|
|
const GCS *gcs = 0;
|
|
|
|
|
|
|
|
_errorLine = 1;
|
|
|
|
_errorString.clear();
|
|
|
|
|
|
|
|
|
|
|
|
while (!file->atEnd()) {
|
|
|
|
QByteArray line = file->readLine();
|
|
|
|
|
|
|
|
if (_errorLine == 1) {
|
2018-06-02 16:41:27 +02:00
|
|
|
QString fileType(QString::fromUtf8(line).trimmed());
|
|
|
|
if (!fileType.startsWith("OziExplorer Route File")) {
|
2018-04-15 10:08:50 +02:00
|
|
|
_errorString = "Not a RTE file";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine == 2) {
|
|
|
|
if (!(gcs = GCS::gcs(QString(line.trimmed())))) {
|
|
|
|
_errorString = "Invalid/unknown datum";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine > 4) {
|
|
|
|
QList<QByteArray> list = line.split(',');
|
|
|
|
if (list.size() < 2) {
|
|
|
|
_errorString = "Parse error";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list.at(0).trimmed() == "R") {
|
|
|
|
routes.append(RouteData());
|
|
|
|
record = true;
|
|
|
|
|
2018-07-24 17:21:45 +02:00
|
|
|
if (list.size() >= 3) {
|
|
|
|
QByteArray name(list.at(2).trimmed());
|
|
|
|
routes.last().setName(decode(name));
|
|
|
|
}
|
|
|
|
if (list.size() >= 4) {
|
|
|
|
QByteArray description(list.at(3).trimmed());
|
|
|
|
routes.last().setDescription(decode(description));
|
|
|
|
}
|
2018-04-15 10:08:50 +02:00
|
|
|
} else if (list.at(0).trimmed() == "W") {
|
|
|
|
if (!record || list.size() < 7) {
|
|
|
|
_errorString = "Parse error";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal lat = list.at(5).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lat < -90.0 || lat > 90.0)) {
|
|
|
|
_errorString = "Invalid latitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
qreal lon = list.at(6).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lon < -180.0 || lon > 180.0)) {
|
|
|
|
_errorString = "Invalid longitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Waypoint wp(gcs->toWGS84(Coordinates(lon, lat)));
|
|
|
|
|
2018-07-24 17:21:45 +02:00
|
|
|
QByteArray name(list.at(4).trimmed());
|
2018-04-15 10:08:50 +02:00
|
|
|
if (!name.isEmpty())
|
2018-07-24 17:21:45 +02:00
|
|
|
wp.setName(decode(name));
|
2018-04-15 10:08:50 +02:00
|
|
|
if (list.size() >= 8) {
|
|
|
|
QByteArray field(list.at(7).trimmed());
|
|
|
|
if (!field.isEmpty()) {
|
|
|
|
double date = field.toDouble(&res);
|
|
|
|
if (!res) {
|
|
|
|
_errorString = "Invalid date";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
wp.setTimestamp(QDateTime::fromMSecsSinceEpoch(
|
|
|
|
delphi2unixMS(date)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (list.size() >= 14) {
|
2018-07-24 17:21:45 +02:00
|
|
|
QByteArray description(list.at(13).trimmed());
|
|
|
|
if (!description.isEmpty())
|
|
|
|
wp.setDescription(decode(description));
|
2018-04-15 10:08:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
routes.last().append(wp);
|
|
|
|
} else {
|
|
|
|
_errorString = "Parse error";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_errorLine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WPTParser::parse(QFile *file, QList<TrackData> &tracks,
|
2019-01-31 01:46:53 +01:00
|
|
|
QList<RouteData> &routes, QList<Area> &polygons,
|
|
|
|
QVector<Waypoint> &waypoints)
|
2018-04-15 10:08:50 +02:00
|
|
|
{
|
|
|
|
Q_UNUSED(tracks);
|
|
|
|
Q_UNUSED(routes);
|
2019-01-31 01:46:53 +01:00
|
|
|
Q_UNUSED(polygons);
|
2018-04-15 10:08:50 +02:00
|
|
|
bool res;
|
|
|
|
const GCS *gcs = 0;
|
|
|
|
|
|
|
|
_errorLine = 1;
|
|
|
|
_errorString.clear();
|
|
|
|
|
|
|
|
while (!file->atEnd()) {
|
|
|
|
QByteArray line = file->readLine();
|
|
|
|
|
|
|
|
if (_errorLine == 1) {
|
2018-06-02 16:41:27 +02:00
|
|
|
QString fileType(QString::fromUtf8(line).trimmed());
|
|
|
|
if (!fileType.startsWith("OziExplorer Waypoint File")) {
|
2018-04-15 10:08:50 +02:00
|
|
|
_errorString = "Not a WPT file";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine == 2) {
|
|
|
|
if (!(gcs = GCS::gcs(QString(line.trimmed())))) {
|
|
|
|
_errorString = "Invalid/unknown datum";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (_errorLine > 4) {
|
|
|
|
QList<QByteArray> list = line.split(',');
|
|
|
|
if (list.size() < 4) {
|
|
|
|
_errorString = "Parse error";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal lat = list.at(2).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lat < -90.0 || lat > 90.0)) {
|
|
|
|
_errorString = "Invalid latitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
qreal lon = list.at(3).trimmed().toDouble(&res);
|
|
|
|
if (!res || (lon < -180.0 || lon > 180.0)) {
|
|
|
|
_errorString = "Invalid longitude";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Waypoint wp(gcs->toWGS84(Coordinates(lon, lat)));
|
|
|
|
|
2018-07-24 17:21:45 +02:00
|
|
|
QByteArray name(list.at(1).trimmed());
|
2018-04-15 10:08:50 +02:00
|
|
|
if (!name.isEmpty())
|
2018-07-24 17:21:45 +02:00
|
|
|
wp.setName(decode(name));
|
2018-04-15 10:08:50 +02:00
|
|
|
if (list.size() >= 5) {
|
|
|
|
QByteArray field(list.at(4).trimmed());
|
|
|
|
if (!field.isEmpty()) {
|
|
|
|
double date = field.toDouble(&res);
|
|
|
|
if (!res) {
|
|
|
|
_errorString = "Invalid date";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
wp.setTimestamp(QDateTime::fromMSecsSinceEpoch(
|
|
|
|
delphi2unixMS(date)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (list.size() >= 11) {
|
2018-07-24 17:21:45 +02:00
|
|
|
QByteArray description(list.at(10).trimmed());
|
|
|
|
if (!description.isEmpty())
|
|
|
|
wp.setDescription(decode(description));
|
2018-04-15 10:08:50 +02:00
|
|
|
}
|
|
|
|
if (list.size() >= 15) {
|
|
|
|
QByteArray field(list.at(14).trimmed());
|
|
|
|
if (!field.isEmpty()) {
|
|
|
|
double elevation = list.at(14).trimmed().toDouble(&res);
|
|
|
|
if (!res) {
|
|
|
|
_errorString = "Invalid elevation";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (elevation != -777)
|
|
|
|
wp.setElevation(elevation * 0.3048);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
waypoints.append(wp);
|
|
|
|
}
|
|
|
|
|
|
|
|
_errorLine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|