1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-19 06:15:10 +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();
}
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;
}
if (lastValid) {
if (fabs(latitude - lastLat) > 0.01) {
// qDebug() << "GpsGlitchFilter(): latitude glitch " << latitude << lastLat;
if (fabs(coord.latitude - lastLat) > 0.01) {
// qDebug() << "GpsGlitchFilter(): latitude glitch " << coord.latitude << lastLat;
if ( ++glitchCount < 10) {
return true;
return true;
}
}
if (fabs(longitude - lastLon) > 0.01) {
// qDebug() << "GpsGlitchFilter(): longitude glitch " << longitude << lastLon;
if (fabs(coord.longitude - lastLon) > 0.01) {
// qDebug() << "GpsGlitchFilter(): longitude glitch " << coord.longitude << lastLon;
if ( ++glitchCount < 10) {
return true;
return true;
}
}
}
lastLat = latitude;
lastLon = longitude;
lastLat = coord.latitude;
lastLon = coord.longitude;
lastValid = true;
glitchCount = 0;
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;
}
if (lastLon == longitude) {
if (lastLon == coord.longitude) {
return false;
}
lastLat = latitude;
lastLon = longitude;
lastLat = coord.latitude;
lastLon = coord.longitude;
return true;
}
@ -997,17 +997,26 @@ double toDecimalCoordinate(const QString & value)
return result;
}
QStringList extractLatLon(const QString & position)
GpsCoord extractGpsCoordinates(const QString & position)
{
QStringList result;
GpsCoord result;
QStringList parts = position.split(' ');
if (parts.size() != 2) {
result.append("");
result.append("");
}
else {
result.append(parts.at(1).trimmed());
result.append(parts.at(0).trimmed());
if (parts.size() == 2) {
QString value = parts.at(0).trimmed();
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 {
// 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;
}

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);
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
{
public:
GpsGlitchFilter() : lastValid(false), glitchCount(0) {};
bool isGlitch(double latitude, double longitude);
bool isGlitch(GpsCoord coord);
private:
bool lastValid;
@ -195,15 +203,16 @@ class GpsLatLonFilter
{
public:
GpsLatLonFilter() {};
bool isValid(const QString & latitude, const QString & longitude);
bool isValid(GpsCoord coord);
private:
QString lastLat;
QString lastLon;
double lastLat;
double lastLon;
};
double toDecimalCoordinate(const QString & value);
QStringList extractLatLon(const QString & position);
GpsCoord extractGpsCoordinates(const QString & position);
class TableLayout
{

View file

@ -229,7 +229,7 @@ QList<QStringList> LogsDialog::filterGePoints(const QList<QStringList> & input)
}
}
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\
The columns for altitude \"GAlt\" and for speed \"GSpd\" are optional"));
return result;
@ -244,21 +244,17 @@ The columns for altitude \"GAlt\" and for speed \"GSpd\" are optional"));
for (int i = 1; i < n; i++) {
if ((ui->logTable->item(i-1, 1)->isSelected() && rangeSelected) || !rangeSelected) {
QStringList latlon = extractLatLon(input.at(i).at(gpscol));
QString latitude = latlon[0];
QString longitude = latlon[1];
double flatitude = toDecimalCoordinate(latitude);
double flongitude = toDecimalCoordinate(longitude);
GpsCoord coord = extractGpsCoordinates(input.at(i).at(gpscol));
// glitch filter
if ( glitchFilter.isGlitch(flatitude, flongitude) ) {
// qDebug() << "filterGePoints(): GPS glitch detected at" << i << flatitude << flongitude;
if ( glitchFilter.isGlitch(coord) ) {
// qDebug() << "filterGePoints(): GPS glitch detected at" << i << coord.latitude << coord.longitude;
continue;
}
// lat long pair filter
if ( !latLonFilter.isValid(latitude, longitude) ) {
// qDebug() << "filterGePoints(): Lat-Lon pair wrong, skipping at" << i << latitude << longitude;
if ( !latLonFilter.isValid(coord) ) {
// qDebug() << "filterGePoints(): Lat-Lon pair wrong, skipping at" << i << coord.latitude << coord.longitude;
continue;
}
@ -333,7 +329,7 @@ void LogsDialog::exportToGoogleEarth()
// declare additional fields
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 safeName = origName;
safeName.replace(" ","_");
@ -363,14 +359,12 @@ void LogsDialog::exportToGoogleEarth()
}
// coordinate data points
outputStream.setRealNumberNotation(QTextStream::FixedNotation);
outputStream.setRealNumberPrecision(8);
for (int i=1; i<n; i++) {
QStringList latlon = extractLatLon(dataPoints.at(i).at(gpscol));
QString latitude = latlon[0];
QString longitude = latlon[1];
GpsCoord coord = extractGpsCoordinates(dataPoints.at(i).at(gpscol));
int altitude = altcol ? dataPoints.at(i).at(altcol).toFloat() : 0;
latitude.sprintf("%3.8f", toDecimalCoordinate(latitude));
longitude.sprintf("%3.8f", toDecimalCoordinate(longitude));
outputStream << "\t\t\t\t\t<gx:coord>" << longitude << " " << latitude << " " << altitude << " </gx:coord>\n" ;
outputStream << "\t\t\t\t\t<gx:coord>" << coord.longitude << " " << coord.latitude << " " << altitude << " </gx:coord>\n" ;
}
// additional data for data points
@ -387,7 +381,7 @@ void LogsDialog::exportToGoogleEarth()
// add values for additional fields
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);;
safeName.replace(" ","_");
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);
for (int i=2; i<csvlog.at(0).count(); 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->logTable->setColumnCount(csvlog.at(0).count());

View file

@ -305,10 +305,15 @@ void logsWrite()
TelemetryItem & telemetryItem = telemetryItems[i];
if (sensor.logs) {
if (sensor.unit == UNIT_GPS) {
if (telemetryItem.gps.longitude && telemetryItem.gps.latitude)
f_printf(&g_oLogFile, "%f %f,", float(telemetryItem.gps.longitude)/1000000, float(telemetryItem.gps.latitude)/1000000);
else
if (telemetryItem.gps.longitude && telemetryItem.gps.latitude) {
div_t qr = div(telemetryItem.gps.latitude, 1000000);
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, ",");
}
}
else if (sensor.unit == UNIT_DATETIME) {
if (telemetryItem.datetime.datestate)