1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-23 16:25:12 +03:00

Fixes #3843: GPS logging in decimal degrees format. Companion export to Google Earth fixed.

This commit is contained in:
Damjan Adamic 2016-09-25 22:02:27 +02:00
parent 5864834661
commit 5157a9f33c
4 changed files with 70 additions and 53 deletions

View file

@ -945,43 +945,43 @@ bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
return s1.toLower() < s2.toLower(); return s1.toLower() < s2.toLower();
} }
bool GpsGlitchFilter::isGlitch(double latitude, double longitude) bool GpsGlitchFilter::isGlitch(GpsCoord coord)
{ {
if ((fabs(latitude) < 0.1) && (fabs(longitude) < 0.1)) { if ((fabs(coord.latitude) < 0.1) && (fabs(coord.longitude) < 0.1)) {
return true; return true;
} }
if (lastValid) { if (lastValid) {
if (fabs(latitude - lastLat) > 0.01) { if (fabs(coord.latitude - lastLat) > 0.01) {
// qDebug() << "GpsGlitchFilter(): latitude glitch " << latitude << lastLat; // qDebug() << "GpsGlitchFilter(): latitude glitch " << coord.latitude << lastLat;
if ( ++glitchCount < 10) { if ( ++glitchCount < 10) {
return true; return true;
} }
} }
if (fabs(longitude - lastLon) > 0.01) { if (fabs(coord.longitude - lastLon) > 0.01) {
// qDebug() << "GpsGlitchFilter(): longitude glitch " << longitude << lastLon; // qDebug() << "GpsGlitchFilter(): longitude glitch " << coord.longitude << lastLon;
if ( ++glitchCount < 10) { if ( ++glitchCount < 10) {
return true; return true;
} }
} }
} }
lastLat = latitude; lastLat = coord.latitude;
lastLon = longitude; lastLon = coord.longitude;
lastValid = true; lastValid = true;
glitchCount = 0; glitchCount = 0;
return false; return false;
} }
bool GpsLatLonFilter::isValid(const QString & latitude, const QString & longitude) bool GpsLatLonFilter::isValid(GpsCoord coord)
{ {
if (lastLat == latitude) { if (lastLat == coord.latitude) {
return false; return false;
} }
if (lastLon == longitude) { if (lastLon == coord.longitude) {
return false; return false;
} }
lastLat = latitude; lastLat = coord.latitude;
lastLon = longitude; lastLon = coord.longitude;
return true; return true;
} }
@ -997,17 +997,26 @@ double toDecimalCoordinate(const QString & value)
return result; return result;
} }
QStringList extractLatLon(const QString & position) GpsCoord extractGpsCoordinates(const QString & position)
{ {
QStringList result; GpsCoord result;
QStringList parts = position.split(' '); QStringList parts = position.split(' ');
if (parts.size() != 2) { if (parts.size() == 2) {
result.append(""); QString value = parts.at(0).trimmed();
result.append(""); QChar direction = value.at(value.size()-1);
} if (direction == 'E' || direction == 'W') {
else { // OpenTX 2.1 format: "NNN.MMM[E|W] NNN.MMM[N|S]" <longitude> <latitude>
result.append(parts.at(1).trimmed()); result.latitude = toDecimalCoordinate(parts.at(1).trimmed());
result.append(parts.at(0).trimmed()); result.longitude = toDecimalCoordinate(parts.at(0).trimmed());
}
else {
// OpenTX 2.2 format: "DD.DDDDDD DD.DDDDDD" <latitude> <longitude> both in Signed degrees format (DDD.dddd)
// Precede South latitudes and West longitudes with a minus sign.
// Latitudes range from -90 to 90.
// Longitudes range from -180 to 180.
result.latitude = parts.at(0).trimmed().toDouble();
result.longitude = parts.at(1).trimmed().toDouble();
}
} }
return result; return result;
} }

View file

@ -178,11 +178,19 @@ QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int ma
bool caseInsensitiveLessThan(const QString &s1, const QString &s2); bool caseInsensitiveLessThan(const QString &s1, const QString &s2);
class GpsCoord
{
public:
GpsCoord(): latitude(0), longitude(0) {};
double latitude; // Precede South latitudes and West longitudes with a minus sign. Latitudes range from -90 to 90.
double longitude; // Longitudes range from -180 to 180.
};
class GpsGlitchFilter class GpsGlitchFilter
{ {
public: public:
GpsGlitchFilter() : lastValid(false), glitchCount(0) {}; GpsGlitchFilter() : lastValid(false), glitchCount(0) {};
bool isGlitch(double latitude, double longitude); bool isGlitch(GpsCoord coord);
private: private:
bool lastValid; bool lastValid;
@ -195,15 +203,16 @@ class GpsLatLonFilter
{ {
public: public:
GpsLatLonFilter() {}; GpsLatLonFilter() {};
bool isValid(const QString & latitude, const QString & longitude); bool isValid(GpsCoord coord);
private: private:
QString lastLat; double lastLat;
QString lastLon; double lastLon;
}; };
double toDecimalCoordinate(const QString & value);
QStringList extractLatLon(const QString & position);
GpsCoord extractGpsCoordinates(const QString & position);
class TableLayout class TableLayout
{ {

View file

@ -229,7 +229,7 @@ QList<QStringList> LogsDialog::filterGePoints(const QList<QStringList> & input)
} }
} }
if (gpscol == 0) { if (gpscol == 0) {
QMessageBox::critical(this, tr("Error: no GPS data not found"), QMessageBox::critical(this, tr("Error: no GPS data not found"),
tr("The column containing GPS coordinates must be named \"GPS\".\n\n\ tr("The column containing GPS coordinates must be named \"GPS\".\n\n\
The columns for altitude \"GAlt\" and for speed \"GSpd\" are optional")); The columns for altitude \"GAlt\" and for speed \"GSpd\" are optional"));
return result; return result;
@ -244,21 +244,17 @@ The columns for altitude \"GAlt\" and for speed \"GSpd\" are optional"));
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
if ((ui->logTable->item(i-1, 1)->isSelected() && rangeSelected) || !rangeSelected) { if ((ui->logTable->item(i-1, 1)->isSelected() && rangeSelected) || !rangeSelected) {
QStringList latlon = extractLatLon(input.at(i).at(gpscol)); GpsCoord coord = extractGpsCoordinates(input.at(i).at(gpscol));
QString latitude = latlon[0];
QString longitude = latlon[1];
double flatitude = toDecimalCoordinate(latitude);
double flongitude = toDecimalCoordinate(longitude);
// glitch filter // glitch filter
if ( glitchFilter.isGlitch(flatitude, flongitude) ) { if ( glitchFilter.isGlitch(coord) ) {
// qDebug() << "filterGePoints(): GPS glitch detected at" << i << flatitude << flongitude; // qDebug() << "filterGePoints(): GPS glitch detected at" << i << coord.latitude << coord.longitude;
continue; continue;
} }
// lat long pair filter // lat long pair filter
if ( !latLonFilter.isValid(latitude, longitude) ) { if ( !latLonFilter.isValid(coord) ) {
// qDebug() << "filterGePoints(): Lat-Lon pair wrong, skipping at" << i << latitude << longitude; // qDebug() << "filterGePoints(): Lat-Lon pair wrong, skipping at" << i << coord.latitude << coord.longitude;
continue; continue;
} }
@ -333,7 +329,7 @@ void LogsDialog::exportToGoogleEarth()
// declare additional fields // declare additional fields
for (int i=0; i<dataPoints.at(0).count()-2; i++) { for (int i=0; i<dataPoints.at(0).count()-2; i++) {
if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) { if (ui->FieldsTW->item(i, 0) && ui->FieldsTW->item(i, 0)->isSelected() && !nondataCols.contains(i+2)) {
QString origName = dataPoints.at(0).at(i+2); QString origName = dataPoints.at(0).at(i+2);
QString safeName = origName; QString safeName = origName;
safeName.replace(" ","_"); safeName.replace(" ","_");
@ -363,14 +359,12 @@ void LogsDialog::exportToGoogleEarth()
} }
// coordinate data points // coordinate data points
outputStream.setRealNumberNotation(QTextStream::FixedNotation);
outputStream.setRealNumberPrecision(8);
for (int i=1; i<n; i++) { for (int i=1; i<n; i++) {
QStringList latlon = extractLatLon(dataPoints.at(i).at(gpscol)); GpsCoord coord = extractGpsCoordinates(dataPoints.at(i).at(gpscol));
QString latitude = latlon[0];
QString longitude = latlon[1];
int altitude = altcol ? dataPoints.at(i).at(altcol).toFloat() : 0; int altitude = altcol ? dataPoints.at(i).at(altcol).toFloat() : 0;
latitude.sprintf("%3.8f", toDecimalCoordinate(latitude)); outputStream << "\t\t\t\t\t<gx:coord>" << coord.longitude << " " << coord.latitude << " " << altitude << " </gx:coord>\n" ;
longitude.sprintf("%3.8f", toDecimalCoordinate(longitude));
outputStream << "\t\t\t\t\t<gx:coord>" << longitude << " " << latitude << " " << altitude << " </gx:coord>\n" ;
} }
// additional data for data points // additional data for data points
@ -387,7 +381,7 @@ void LogsDialog::exportToGoogleEarth()
// add values for additional fields // add values for additional fields
for (int i=0; i<dataPoints.at(0).count()-2; i++) { for (int i=0; i<dataPoints.at(0).count()-2; i++) {
if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) { if (ui->FieldsTW->item(i, 0) && ui->FieldsTW->item(i, 0)->isSelected() && !nondataCols.contains(i+2)) {
QString safeName = dataPoints.at(0).at(i+2);; QString safeName = dataPoints.at(0).at(i+2);;
safeName.replace(" ","_"); safeName.replace(" ","_");
outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\""<< safeName <<"\">\n"; outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\""<< safeName <<"\">\n";
@ -564,7 +558,7 @@ void LogsDialog::on_fileOpen_BT_clicked()
ui->logTable->setSelectionBehavior(QAbstractItemView::SelectRows); ui->logTable->setSelectionBehavior(QAbstractItemView::SelectRows);
for (int i=2; i<csvlog.at(0).count(); i++) { for (int i=2; i<csvlog.at(0).count(); i++) {
QTableWidgetItem* item= new QTableWidgetItem(csvlog.at(0).at(i)); QTableWidgetItem* item= new QTableWidgetItem(csvlog.at(0).at(i));
ui->FieldsTW->setItem(0,i-2,item); ui->FieldsTW->setItem(i-2, 0, item);
} }
ui->FieldsTW->resizeRowsToContents(); ui->FieldsTW->resizeRowsToContents();
ui->logTable->setColumnCount(csvlog.at(0).count()); ui->logTable->setColumnCount(csvlog.at(0).count());

View file

@ -305,10 +305,15 @@ void logsWrite()
TelemetryItem & telemetryItem = telemetryItems[i]; TelemetryItem & telemetryItem = telemetryItems[i];
if (sensor.logs) { if (sensor.logs) {
if (sensor.unit == UNIT_GPS) { if (sensor.unit == UNIT_GPS) {
if (telemetryItem.gps.longitude && telemetryItem.gps.latitude) if (telemetryItem.gps.longitude && telemetryItem.gps.latitude) {
f_printf(&g_oLogFile, "%f %f,", float(telemetryItem.gps.longitude)/1000000, float(telemetryItem.gps.latitude)/1000000); div_t qr = div(telemetryItem.gps.latitude, 1000000);
else f_printf(&g_oLogFile, "%d.%06d ", qr.quot, abs(qr.rem));
qr = div(telemetryItem.gps.longitude, 1000000);
f_printf(&g_oLogFile, "%d.%06d,", qr.quot, abs(qr.rem));
}
else {
f_printf(&g_oLogFile, ","); f_printf(&g_oLogFile, ",");
}
} }
else if (sensor.unit == UNIT_DATETIME) { else if (sensor.unit == UNIT_DATETIME) {
if (telemetryItem.datetime.datestate) if (telemetryItem.datetime.datestate)