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:
parent
5864834661
commit
5157a9f33c
4 changed files with 70 additions and 53 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue