1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-19 14:25:11 +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') {
// OpenTX 2.1 format: "NNN.MMM[E|W] NNN.MMM[N|S]" <longitude> <latitude>
result.latitude = toDecimalCoordinate(parts.at(1).trimmed());
result.longitude = toDecimalCoordinate(parts.at(0).trimmed());
} }
else { else {
result.append(parts.at(1).trimmed()); // OpenTX 2.2 format: "DD.DDDDDD DD.DDDDDD" <latitude> <longitude> both in Signed degrees format (DDD.dddd)
result.append(parts.at(0).trimmed()); // 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

@ -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,11 +305,16 @@ 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)
f_printf(&g_oLogFile, "%4d-%02d-%02d %02d:%02d:%02d,", telemetryItem.datetime.year, telemetryItem.datetime.month, telemetryItem.datetime.day, telemetryItem.datetime.hour, telemetryItem.datetime.min, telemetryItem.datetime.sec); f_printf(&g_oLogFile, "%4d-%02d-%02d %02d:%02d:%02d,", telemetryItem.datetime.year, telemetryItem.datetime.month, telemetryItem.datetime.day, telemetryItem.datetime.hour, telemetryItem.datetime.min, telemetryItem.datetime.sec);