File merkaartor-20091019_r144.diff of Package merkaartor
Index: clean.sh
===================================================================
--- clean.sh (revision 0)
+++ clean.sh (revision 144)
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+make distclean
+rm -rf binaries \
+ plugins/background/MYahooBackground/tmp \
+ plugins/qtstyle/skulpture22/tmp
Property changes on: clean.sh
___________________________________________________________________
Added: svn:executable
+ *
Index: build.sh
===================================================================
--- build.sh (revision 0)
+++ build.sh (revision 144)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+libdir=/usr/local/lib
+arch | grep -q x86_64 && libdir=/usr/local/lib64
+
+lrelease Merkaartor.pro
+qmake Merkaartor.pro PREFIX=/usr/local \
+ NODEBUG=0 \
+ GDAL=1 \
+ GPSD=1 \
+ GEOIMAGE=1 \
+ LIBDIR=$libdir \
+ FORCE_CUSTOM_STYLE=1
+make
+sudo make install
Property changes on: build.sh
___________________________________________________________________
Added: svn:executable
+ *
Index: src/MainWindow.h
===================================================================
--- src/MainWindow.h (revision 107)
+++ src/MainWindow.h (working copy)
@@ -160,6 +160,9 @@ class MainWindow : public QMainWindow, public Ui::
void move_triggered();
void add_triggered();
void reverse_triggered();
+ // signal forwarding
+ void continue_filtering(double, double, bool, bool, QPoint);
+ void update_delta(double londelta, double latdelta);
public:
MainWindowPrivate* p;
@@ -191,7 +194,12 @@ class MainWindow : public QMainWindow, public Ui::
void projectionTriggered(QAction* anAction);
#endif
void styleTriggered(QAction* anAction);
- void updateGpsPosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading);
+ // set adjustposition to true for only updating the position marker, but not recording the trackpoint
+ void updateGpsPosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading,
+ bool adjustposition);
+ // opens the trackfilter dialog
+ void GPSFilter(QString errmsg, double londelta, double latdelta, bool correctFutureTackpoints,
+ QPoint filterposition);
void applyStyles(QList<FeaturePainter>* thePainters);
public:
Index: src/GPS/trackfilterdialog.h
===================================================================
--- src/GPS/trackfilterdialog.h (revision 0)
+++ src/GPS/trackfilterdialog.h (revision 144)
@@ -0,0 +1,36 @@
+#ifndef TRACKFILTERDIALOG_H
+#define TRACKFILTERDIALOG_H
+
+#include <QDialog>
+
+#include "ui_trackfilterdialog.h"
+
+// trackfilter dialog window
+class TrackFilterDialog : public QDialog, public Ui::TrackFilterDialog
+{
+ Q_OBJECT
+
+private:
+ // for remembering previous deltas
+ double londelta, latdelta;
+
+public:
+ TrackFilterDialog(QWidget *parent = 0, double londelta = 0, double latdelta = 0,
+ bool correctFutureTackpoints = 0, QPoint *filterposition = NULL);
+
+signals:
+ // continue with updated position
+ void continue_filtering(double londelta, double latdelta, bool record, bool change_lon_lat_deltas, QPoint filterposition);
+ // show updated position with position marker on the map
+ void update_delta(double londelta,double latdelta);
+
+private slots:
+ // show updated position on the map when spinboxes/sliders are changed
+ void update();
+ // when pressing 'Use trackpoint' button
+ void accept();
+ // when pressing 'Discard trackpoint' button
+ void reject();
+};
+
+#endif
Index: src/GPS/trackfilterdialog.ui
===================================================================
--- src/GPS/trackfilterdialog.ui (revision 0)
+++ src/GPS/trackfilterdialog.ui (revision 144)
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TrackFilterDialog</class>
+ <widget class="QDialog" name="TrackFilterDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>438</width>
+ <height>302</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>438</width>
+ <height>302</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>TrackFilter</string>
+ </property>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>10</y>
+ <width>201</width>
+ <height>181</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Correct Position (meter)</string>
+ </property>
+ <widget class="QSlider" name="lonhorizontalSlider">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>60</y>
+ <width>84</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <number>-500</number>
+ </property>
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ <property name="singleStep">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSlider" name="latverticalSlider">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>30</y>
+ <width>16</width>
+ <height>84</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <number>-500</number>
+ </property>
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="latspinBox">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>140</y>
+ <width>55</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <number>-500</number>
+ </property>
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="lonspinBox">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>90</y>
+ <width>55</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <number>-500</number>
+ </property>
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>261</x>
+ <y>41</y>
+ <width>161</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="useTrackpointButton">
+ <property name="text">
+ <string>Use Trackpoint</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>38</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="discardTrackpointButton">
+ <property name="text">
+ <string>Discard Trackpoint</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QCheckBox" name="correctFutureTrackpointscheckBox">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>210</y>
+ <width>321</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Use correction also for future Trackpoints</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="ErrorMessage">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>260</y>
+ <width>391</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Error Message</string>
+ </property>
+ </widget>
+ </widget>
+ <tabstops>
+ <tabstop>latspinBox</tabstop>
+ <tabstop>latverticalSlider</tabstop>
+ <tabstop>lonspinBox</tabstop>
+ <tabstop>lonhorizontalSlider</tabstop>
+ <tabstop>useTrackpointButton</tabstop>
+ <tabstop>discardTrackpointButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>useTrackpointButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TrackFilterDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>337</x>
+ <y>55</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>317</x>
+ <y>180</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>discardTrackpointButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TrackFilterDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>311</x>
+ <y>139</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>336</x>
+ <y>180</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
Index: src/GPS/trackfilterdialog.cpp
===================================================================
--- src/GPS/trackfilterdialog.cpp (revision 0)
+++ src/GPS/trackfilterdialog.cpp (revision 144)
@@ -0,0 +1,88 @@
+#include <QtGui>
+
+#include "trackfilterdialog.h"
+
+TrackFilterDialog::TrackFilterDialog(QWidget *parent, double lon_delta, double lat_delta,
+ bool correctFutureTrackpoints, QPoint *filterposition)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ // move dialog window to initial or latest position
+ move(*filterposition);
+
+ // remember current deltas;
+ londelta=lon_delta;
+ latdelta=lat_delta;
+
+ // show current state, whether deltas were used not only for one trackpoint
+ correctFutureTrackpointscheckBox->setChecked(correctFutureTrackpoints);
+
+ // connect spinbox/slider for latitude
+ QObject::connect(latspinBox, SIGNAL(valueChanged(int)),
+ latverticalSlider, SLOT(setValue(int)));
+ QObject::connect(latverticalSlider, SIGNAL(valueChanged(int)),
+ latspinBox, SLOT(setValue(int)));
+
+ // show current delta for latitude in spinbox/slider
+ latspinBox->setValue((int)(latdelta*40000000/360));
+
+ // connect spinbox/slider for longitude in spinbox/slider
+ QObject::connect(lonspinBox, SIGNAL(valueChanged(int)),
+ lonhorizontalSlider, SLOT(setValue(int)));
+ QObject::connect(lonhorizontalSlider, SIGNAL(valueChanged(int)),
+ lonspinBox, SLOT(setValue(int)));
+
+ // show current delta for longitude
+ lonspinBox->setValue((int)(londelta*40000000/360));
+
+ // call update() if anything is changed in spinbox/slider for latitude/longitude
+ QObject::connect(latspinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(update()));
+ QObject::connect(lonspinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(update()));
+
+ // show current position with position marker on the map
+ update();
+}
+
+void TrackFilterDialog::update()
+{
+ // show updated position with position marker on the map
+ emit update_delta((lonspinBox->value() * 360.0 / 40000000) - londelta,
+ (latspinBox->value() * 360.0 / 40000000) - latdelta);
+}
+
+void TrackFilterDialog::accept()
+{
+ // continue with updated deltas
+
+ //
+ // FIXME: Make sure that values for latspinBox/lonspinBox are the
+ // same next time if 'Use for future Trackpoints' checkbox
+ // is set. Currently this is sometimes broken due to
+ // rounding errors and conversion issues between int and
+ // double types.
+ //
+ emit continue_filtering(lonspinBox->value() * 360.0 / 40000000,
+ latspinBox->value() * 360.0 / 40000000,
+ 1, // record trackpoint
+ correctFutureTrackpointscheckBox->isChecked(),
+ pos() // dialog window position
+ );
+ // close dialog window
+ done(0);
+}
+
+void TrackFilterDialog::reject()
+{
+ // continue with previous deltas
+ emit continue_filtering(londelta,
+ latdelta,
+ 0, // do not record trackpoint
+ correctFutureTrackpointscheckBox->isChecked(),
+ pos() // dialog window position
+ );
+ // close dialog window
+ done(1);
+}
Index: src/GPS/qgpsdevice.h
===================================================================
--- src/GPS/qgpsdevice.h (revision 107)
+++ src/GPS/qgpsdevice.h (working copy)
@@ -25,6 +25,8 @@
#include <QThread>
#include <QDateTime>
#include <QFile>
+#include <QStringList>
+#include <qpoint.h>
class QString;
class QMutex;
@@ -113,6 +115,13 @@ class QGPSDevice : public QThread
float speed() { return cur_speed; }
float variation() { return cur_variation; }
float dillution() { return cur_dillution; }
+ // returns current deltas for latitude/longitude (used when showing current position)
+ double latdelta() { return cur_latdelta; }
+ double londelta() { return cur_londelta; }
+ // returns current update deltas for latitude/longitude (used when showing current position)
+ // introduced for the temporary changes of deltas in trackfilter dialog
+ double updatelatdelta() { return update_latdelta; }
+ double updatelondelta() { return update_londelta; }
CardinalDirection latCardinal() { return cur_latCardinal; }
CardinalDirection longCardinal() { return cur_longCardinal; }
@@ -126,11 +135,15 @@ class QGPSDevice : public QThread
int latDegrees();
int latMinutes();
int latSeconds();
+ // better precision required when used for NMEA
+ double latSecondsf();
int longDegrees();
int longMinutes();
int longSeconds();
-
+ // better precision required when used for NMEA
+ double longSecondsf();
+
public slots:
virtual void startDevice();
@@ -138,9 +151,13 @@ class QGPSDevice : public QThread
signals:
- void updatePosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading);
+ // set adjustposition to true for only updating the position marker, but not recording the trackpoint
+ void updatePosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading,
+ bool adjustposition);
void updateStatus();
void doStopDevice();
+ // trigger opening the trackfilter dialog
+ void gpsfilter(QString errmsg, double londelta, double latdelta, bool correctFutureTackpoints, QPoint filterposition);
protected:
@@ -175,13 +192,34 @@ class QGPSDevice : public QThread
QDateTime cur_datetime;
+ // current/previous timestamp for calculating acceleration
+ double cur_timestamp;
+ double prev_timestamp;
+ // deltas and update deltas for showing position of trackpoint
+ double cur_latdelta;
+ double cur_londelta;
+ double update_latdelta;
+ double update_londelta;
float cur_latitude;
float cur_longitude;
float cur_altitude;
float cur_heading;
float cur_speed;
+ // previous speed for calculating acceleration
+ float prev_speed;
+ // backup speed, so it can easily be restored if trackpoint is discarded
+ float tmp_speed;
float cur_variation;
float cur_dillution;
+
+ // flag being set when trackfilter dialog is opened/closed
+ bool filterdialogvisible;
+ // flag to set whether deltas are also to be used for future trackpoints
+ bool correctFutureTackpoints;
+ // position of dialog window
+ QPoint filterpos;
+ // buffer for trackpoints; used when filterdialog=true
+ QStringList linesbuffer;
CardinalDirection cur_latCardinal;
CardinalDirection cur_longCardinal;
@@ -196,6 +234,9 @@ class QGPSDevice : public QThread
FixType cur_fixType;
FixMode cur_fixMode;
FixStatus cur_fixStatus;
+
+ // NMEA file to record trackpoints
+ QFile *LogFile;
bool parseGGA(const char *ggaString = 0);
bool parseGLL(const char *ggaString = 0);
@@ -278,11 +319,23 @@ class QGPSDDevice : public QGPSDevice
protected:
virtual void run();
+ public slots:
+ // continue filtering with updated deltas
+ virtual void continueFiltering(double londelta, double latdelta, bool record,
+ bool change_lon_lat_deltas, QPoint filterposition);
+ // show updated position of trackpoint, but don't record it
+ virtual void UpdateDelta(double londelta, double latdelta);
+
private:
void onLinkReady();
void onDataAvailable();
void onStop();
+ // write NMEA log
+ void writeLog();
+ // calculate checksum of NMEA sentence
+ int checksum(const char *buf);
+
void parse(const QString& s);
void parseO(const QString& s);
void parseY(const QString& s);
Index: src/GPS/GPS.pri
===================================================================
--- src/GPS/GPS.pri (revision 107)
+++ src/GPS/GPS.pri (working copy)
@@ -1,16 +1,19 @@
FORMS += \
- qgpsmainwindowui.ui
+ qgpsmainwindowui.ui \
+ trackfilterdialog.ui
HEADERS += qgps.h \
qgpssatellitetracker.h \
qgpsdevice.h \
- SatelliteStrengthView.h
+ SatelliteStrengthView.h \
+ trackfilterdialog.h
SOURCES += qgps.cpp \
qgpssatellitetracker.cpp \
qgpsdevice.cpp \
- SatelliteStrengthView.cpp
+ SatelliteStrengthView.cpp \
+ trackfilterdialog.cpp
DEFINES += USE_GPS
Index: src/GPS/qgpsdevice.cpp
===================================================================
--- src/GPS/qgpsdevice.cpp (revision 107)
+++ src/GPS/qgpsdevice.cpp (working copy)
@@ -36,6 +36,13 @@
#include "Preferences/MerkaartorPreferences.h"
+// filter limits are currently hard-coded
+#define MAXSPEED 25
+#define MINACCEL -10
+#define MAXACCEL 4
+/* about HDOP=6.66 */
+#define MAXDILLUTION 100
+
/* GPSSLOTFORWARDER */
GPSSlotForwarder::GPSSlotForwarder(QGPSDevice* aTarget)
@@ -76,11 +83,30 @@ QGPSDevice::QGPSDevice()
{
mutex = new QMutex(QMutex::Recursive);
+ // initialize new members
+ cur_timestamp = 0;
+ prev_timestamp = 0;
+ // trackfilter not active
+ filterdialogvisible = 0;
+ // no deltas required
+ cur_latdelta = 0;
+ cur_londelta = 0;
+ update_latdelta = 0;
+ update_londelta = 0;
+ // nothing to correct
+ correctFutureTackpoints = 0;
+ // show trackfilter dialog at the top left corner of the screen
+ // when being opened
+ filterpos.setX(0);
+ filterpos.setY(0);
+
setLatitude(0);
setLongitude(0);
setAltitude(0);
setHeading(0);
setSpeed(0);
+ // assume a previous speed of 0
+ prev_speed = 0;
setVariation(0);
setFixMode(QGPSDevice::FixAuto);
@@ -112,6 +138,13 @@ int QGPSDevice::latSeconds()
double s = (m * 60) - int(m * 60);
return int(s * 60);
}
+// NMEA needs a better precision
+double QGPSDevice::latSecondsf()
+{
+ double m = fabs(latitude()) - latDegrees();
+ double s = (m * 60) - int(m * 60);
+ return s * 60;
+}
int QGPSDevice::longDegrees() { return (int) (fabs(longitude())); }
int QGPSDevice::longMinutes()
{
@@ -124,6 +157,13 @@ int QGPSDevice::longSeconds()
double s = (m * 60) - int(m * 60);
return int(s * 60);
}
+// NMEA needs a better precision
+double QGPSDevice::longSecondsf()
+{
+ double m = fabs(longitude()) - longDegrees();
+ double s = (m * 60) - int(m * 60);
+ return (s * 60);
+}
bool QGPSDevice::isActiveSat(int prn)
{
@@ -767,7 +807,8 @@ void QGPSComDevice::parse(const QByteArray& buffer
//strcpy(nmeastr_rmc, bufferString);
if (parseRMC(bufferString.data()))
if (fixStatus() == QGPSDevice::StatusActive && (fixType() == QGPSDevice::Fix3D || fixType() == QGPSDevice::FixUnavailable))
- emit updatePosition(latitude(), longitude(), dateTime(), altitude(), speed(), heading());
+ // adjustposition=false
+ emit updatePosition(latitude(), longitude(), dateTime(), altitude(), speed(), heading(), 0);
}
emit updateStatus();
}
@@ -890,7 +931,8 @@ void QGPSFileDevice::onDataAvailable()
//strcpy(nmeastr_rmc, bufferString);
if (parseRMC(bufferString))
if (fixStatus() == QGPSDevice::StatusActive && (fixType() == QGPSDevice::Fix3D || fixType() == QGPSDevice::FixUnavailable))
- emit updatePosition(latitude(), longitude(), dateTime(), altitude(), speed(), heading());
+ // adjustpostion=false
+ emit updatePosition(latitude(), longitude(), dateTime(), altitude(), speed(), heading(), 0);
}
mutex->unlock();
@@ -907,13 +949,34 @@ QGPSDDevice::QGPSDDevice(const QString& device)
setDevice(device);
}
+// open NMEA logfile
bool QGPSDDevice::openDevice()
{
+ if (M_PREFS->getGpsSaveLog()) {
+ QString fn = "log-" + QDateTime::currentDateTime().toString(Qt::ISODate) + ".nmea";
+ fn.replace(':', '-');
+ LogFile = new QFile(M_PREFS->getGpsLogDir() + "/"+fn);
+ if (!LogFile->open(QIODevice::WriteOnly)) {
+ QMessageBox::critical(NULL, tr("GPS log error"),
+ tr("Unable to create GPS log file: %1.").arg(M_PREFS->getGpsLogDir() + "/"+fn),
+ QMessageBox::Ok);
+ delete LogFile;
+ LogFile = NULL;
+ }
+ }
+
return true;
}
+// close NMEA logfile
bool QGPSDDevice::closeDevice()
{
+ if (LogFile && LogFile->isOpen()) {
+ LogFile->close();
+ delete LogFile;
+ }
+ LogFile = NULL;
+
return true;
}
@@ -933,6 +996,8 @@ void QGPSDDevice::run()
connect(Server,SIGNAL(readyRead()),&Forward,SLOT(onDataAvailable()));
connect(this,SIGNAL(doStopDevice()),&Forward,SLOT(onStop()));
exec();
+ // close NMEA logfile
+ closeDevice();
}
void QGPSDDevice::onDataAvailable()
@@ -954,15 +1019,27 @@ void QGPSDDevice::onDataAvailable()
void QGPSDDevice::parse(const QString& s)
{
- qDebug() << "parsing " << s.toUtf8().data() << "*";
- QStringList Args(s.split(',',QString::SkipEmptyParts));
- for (int i=0; i<Args.count(); ++i)
- {
- QString Left(Args[i].left(2));
- if (Left == "O=")
+ // write trackpoint data to buffer
+ linesbuffer << s;
+ // look at buffer
+ while (!linesbuffer.isEmpty()) {
+ // read buffer and parse data if trackfilter dialog is not open;
+ // otherwise return immediately
+ if (!filterdialogvisible) {
+ QString first=linesbuffer.first();
+ linesbuffer.removeFirst();
+ qDebug() << "parsing " << first.toUtf8().data() << "*";
+ QStringList Args(first.split(',',QString::SkipEmptyParts));
+ for (int i=0; i<Args.count(); ++i) {
+ QString Left(Args[i].left(2));
+ if (Left == "O=")
parseO(Args[i].right(Args[i].length()-2));
- if (Left == "Y=")
+ if (Left == "Y=")
parseY(Args[i].right(Args[i].length()-2));
+ }
+ } else {
+ return;
+ }
}
}
@@ -990,40 +1067,286 @@ void QGPSDDevice::parseY(const QString& s)
void QGPSDDevice::parseO(const QString& s)
{
+ double timestamp;
+
if (s.isEmpty()) return;
setFixType(FixInvalid);
+ setFixStatus(StatusVoid); // by Travers Carter <tcarter@noggin.com.au>
if (s[0] == '?') return;
QStringList Args(s.split(' ',QString::SkipEmptyParts));
if (Args.count() < 5) return;
setFixType(Fix2D);
+ setFixStatus(StatusActive); // by Travers Carter <tcarter@noggin.com.au>
setLatitude(Args[3].toDouble());
setLongitude(Args[4].toDouble());
+
+ // Update the timestamp (by Travers Carter <tcarter@noggin.com.au>)
+ cur_datetime = QDateTime::fromTime_t(Args[1].toDouble()).toUTC();
+
+ // make sure we update prev_timestamp and prev_speed, which
+ // are later being used by acceleration filter, only when
+ // timestamp of trackpoint data changes
+ timestamp = Args[1].toDouble();
+ if (cur_timestamp) {
+ if (timestamp - cur_timestamp > 0) {
+ printf("*** timestamp changed ***\n");
+ prev_timestamp = cur_timestamp;
+ prev_speed = speed();
+ }
+ } else {
+ prev_timestamp = timestamp;
+ }
+
+ cur_timestamp = timestamp;
+
+ // Debug output
+ printf("timestamp: %f\n", timestamp);
+ printf("prev_timestamp: %f\n", prev_timestamp);
+ printf("cur_timestamp: %f\n", cur_timestamp);
+
double Alt = 0;
if (Args.count() > 5)
Alt = Args[5].toDouble();
double Speed = 0;
if (Args.count() > 9)
- Speed = Args[9].toDouble();
+ Speed = Args[9].toDouble() / 1000 * 3600; // Convert from metres/sec to km/h
+ // (by Travers Carter <tcarter@noggin.com.au>)
double Heading = 0;
if (Args.count() > 7)
Heading = Args[7].toDouble();
- emit updatePosition(Args[3].toDouble(),
- Args[4].toDouble(),
- QDateTime::currentDateTime(),
- Alt, Speed, Heading);
+
+ // Update the fix type (by Travers Carter <tcarter@noggin.com.au>)
+ if (Args.count() > 14) {
+ if (Args[14] == "1") {
+ setFixType(FixUnavailable);
+ } else if (Args[14] == "3") {
+ setFixType(Fix3D);
+ }
+ }
+
+ // Dillution filter
+ double Dillution = 0;
+ if (Args.count() > 6) {
+ Dillution = Args[6].toDouble();
+ printf("Dillution: %f\n", Dillution);
+ if (Dillution > MAXDILLUTION) {
+ qDebug() << "dillution :" << Dillution << " m > "
+ << MAXDILLUTION << "--> dropping trackpoint";
+ setHeading(Heading);
+ setAltitude(Alt);
+ setSpeed(Speed);
+ emit updateStatus();
+ QString errmsg;
+ errmsg=QString("Horizontal error estimate too high (%1m > %2m)")
+ .arg(Dillution).arg(MAXDILLUTION);
+ // trigger opening the trackfilter dialog
+ emit gpsfilter(errmsg, cur_londelta, cur_latdelta, correctFutureTackpoints, filterpos);
+ // flag it as openend, so trackpoint data is buffered
+ filterdialogvisible=1;
+ return;
+ }
+ }
+ setDillution(Dillution);
+
+ printf("prev_speed: %f m/s\n",prev_speed/3.6);
+ printf("cur_speed: %f m/s\n", Speed/3.6);
+
+ // Speed/acceleration filters (higher priority for speed filter)
+ if (Speed > MAXSPEED) {
+ qDebug() << "speed :" << Speed << " km/h > " << MAXSPEED << "--> dropping trackpoint";
+ setHeading(Heading);
+ setAltitude(Alt);
+ setSpeed(Speed);
+ emit updateStatus();
+ QString errmsg;
+ errmsg=QString("Speed too high (%1km/h > %2km/h)").arg(Speed).arg(MAXSPEED);
+ // trigger opening the trackfilter dialog
+ emit gpsfilter(errmsg, cur_londelta, cur_latdelta, correctFutureTackpoints, filterpos);
+ // flag it as openend, so trackpoint data is buffered
+ filterdialogvisible=1;
+ return;
+ } else if ((cur_timestamp - prev_timestamp) > 0) {
+ float accel = (Speed - prev_speed)/
+ (3.6 * (cur_timestamp - prev_timestamp));
+ printf("accel: %f m/(s*s)\n", accel);
+ if (accel > MAXACCEL || accel < MINACCEL ) {
+ qDebug() << "accel: " << accel << " m/(s*s) not in"
+ << "[" << MINACCEL << "..." << MAXACCEL
+ << "] --> dropping trackpoint";
+ setHeading(Heading);
+ setAltitude(Alt);
+ setSpeed(Speed);
+ emit updateStatus();
+ QString errmsg;
+ errmsg=QString("Acceleration (%1m/(s*s)) not in limits [%2m/(s*s)...%3m/(s*s)]")
+ .arg(accel).arg(MINACCEL).arg(MAXACCEL);
+ // trigger opening the trackfilter dialog
+ emit gpsfilter(errmsg, cur_latdelta, cur_londelta, correctFutureTackpoints, filterpos);
+ // flag it as openend, so trackpoint data is buffered
+ filterdialogvisible=1;
+ return;
+ }
+ }
+
+ emit updatePosition(Args[3].toDouble()+cur_latdelta,
+ Args[4].toDouble()+cur_londelta,
+ cur_datetime, // by Travers Carter <tcarter@noggin.com.au>
+ Alt, Speed, Heading, 0);
setHeading(Heading);
setAltitude(Alt);
setSpeed(Speed);
emit updateStatus();
-
+ setLatitude(latitude() + latdelta());
+ setLongitude(longitude() + londelta());
+ // write recorded trackpoint to NMEA logfile
+ writeLog();
}
void QGPSDDevice::onLinkReady()
{
if (!Server) return;
Server->write("w+");
- Server->write("j=1");
+ // clear all fix data at the start of each poll cycle; we don't want
+ // to use the dillution from previous trackpoints for our filter!
+ Server->write("j=0");
}
+
+void QGPSDDevice::continueFiltering(double londelta, double latdelta, bool record, bool change_lon_lat_deltas, QPoint filterposition)
+{
+ // remember trackfilter dialog window position
+ filterpos.setX(filterposition.x());
+ filterpos.setY(filterposition.y());
+ // no longer use any update deltas for show current trackpoint position
+ update_latdelta = 0;
+ update_londelta = 0;
+ if (change_lon_lat_deltas) {
+ // save new deltas
+ cur_latdelta=latdelta;
+ cur_londelta=londelta;
+ // remember state for next run
+ correctFutureTackpoints = 1;
+ } else {
+ // reset deltas
+ cur_latdelta = 0;
+ cur_londelta = 0;
+ // remember state for next run
+ correctFutureTackpoints = 0;
+ }
+ if (record) {
+ // show updated position on map
+ emit updatePosition(latitude()+latdelta,
+ longitude()+londelta,
+ dateTime(),
+ altitude(), speed(), heading(), 0);
+ emit updateStatus();
+
+ // update latitude/longitude of trackpoint
+ setLatitude(latitude() + cur_latdelta);
+ setLongitude(longitude() + cur_londelta);
+ // write trackpoint to NMEA logfile
+ writeLog();
+ } else {
+ // restore backup speed since trackpoint has been discarded
+ setSpeed(tmp_speed);
+ }
+ // trackpoint data no longer needs to be buffered
+ filterdialogvisible=0;
+}
+
+void QGPSDDevice::UpdateDelta(double londelta, double latdelta)
+{
+ // new update deltas
+ update_latdelta = latdelta;
+ update_londelta = londelta;
+
+ // only show updated position (adjustposition=true)
+ emit updatePosition(latitude(),
+ longitude(),
+ dateTime(),
+ altitude(), speed(), heading(), 1);
+}
+
+// calculates checksum for NMEA sentence
+int QGPSDDevice::checksum(const char * buf) {
+ int x = 0;
+ const char *p;
+
+ for (p=buf; *p; p++) {
+ x ^= *p;
+ }
+
+ return x;
+}
+
+// write GPRMC/GPGGA NMEA sentences for each trackpoint data
+void QGPSDDevice::writeLog()
+{
+ char buf[80];
+ char cksum[3];
+ char date[7];
+ char time[11];
+ char *lc_numeric_locale;
+
+ QByteArray line="";
+ if (LogFile) {
+ QString qdate=cur_datetime.toString("ddMMyy");
+ QString qtime=cur_datetime.toString("hhmmss.zzz");
+ strcpy(date,qdate.toUtf8());
+ strcpy(time,qtime.toUtf8());
+ // backup current LC_NUMERIC locale
+ lc_numeric_locale=setlocale(LC_NUMERIC, NULL);
+ // make sure to use "decimal point" as radix character for speed value
+ setlocale(LC_NUMERIC, "C");
+ snprintf(buf, sizeof(buf), "GPRMC,%s,A,%.2i%.2i.%.4i,%s,%.3i%.2i.%.4i,%s,%f,,%s,,",
+ time,
+ latDegrees(),
+ latMinutes(),
+ (int)(latSecondsf()*10000/60),
+ (latitude() > 0) ? "N" : "S",
+ longDegrees(),
+ longMinutes(),
+ (int)(longSecondsf()*10000/60),
+ (longitude() > 0) ? "E" : "W",
+ speed()/1.852,
+ date);
+ // restore previous LC_NUMERIC locale
+ setlocale(LC_NUMERIC, lc_numeric_locale);
+ snprintf(cksum, sizeof(cksum),"%.2X", checksum(buf));
+ line.append("$");
+ line.append(buf);
+ line.append("*");
+ line.append(cksum);
+ line.append("\n");
+ // finally
+ LogFile->write(line);
+ // backup current LC_NUMERIC locale
+ lc_numeric_locale=setlocale(LC_NUMERIC, NULL);
+ // make sure to use "decimal point" as radix character for speed value
+ setlocale(LC_NUMERIC, "C");
+ snprintf(buf, sizeof(buf), "GPGGA,%s,%.2i%.2i.%.4i,%s,%.3i%.2i.%.4i,%s,1,,,%.2f,M,0.0,M,,",
+ time,
+ latDegrees(),
+ latMinutes(),
+ (int)(latSecondsf()*10000/60),
+ (longitude() > 0) ? "N" : "S",
+ longDegrees(),
+ longMinutes(),
+ (int)(longSecondsf()*10000/60),
+ (latitude() > 0) ? "E" : "W",
+ altitude());
+ // restore previous LC_NUMERIC locale
+ setlocale(LC_NUMERIC, lc_numeric_locale);
+ snprintf(cksum, sizeof(cksum),"%.2X", checksum(buf));
+ line = "";
+ line.append("$");
+ line.append(buf);
+ line.append("*");
+ line.append(cksum);
+ line.append("\n");
+ // finally
+ LogFile->write(line);
+ }
+}
#endif
#ifdef Q_OS_SYMBIAN
@@ -1079,9 +1402,10 @@ void QGPSS60Device::onLocationChanged(double latit
setLongitude(longitude);
setAltitude(altitude);
setSpeed(speed);
-
+
+ // adjustposition=false
emit updatePosition(latitude, longitude, QDateTime::currentDateTime(),
- altitude, speed, cur_heading);
+ altitude, speed, cur_heading, 0);
}
void QGPSS60Device::onStatusChanged(XQLocation::DeviceStatus)
Index: src/MapView.cpp
===================================================================
--- src/MapView.cpp (revision 107)
+++ src/MapView.cpp (working copy)
@@ -260,7 +260,13 @@ void MapView::drawGPS(QPainter & P)
{
if (Main->gps()->getGpsDevice()) {
if (Main->gps()->getGpsDevice()->fixStatus() == QGPSDevice::StatusActive) {
- Coord vp(angToInt(Main->gps()->getGpsDevice()->latitude()), angToInt(Main->gps()->getGpsDevice()->longitude()));
+ // consider current and updated deltas for latitude/longitude
+ Coord vp(angToInt(Main->gps()->getGpsDevice()->latitude()
+ +Main->gps()->getGpsDevice()->latdelta()
+ +Main->gps()->getGpsDevice()->updatelatdelta()),
+ angToInt(Main->gps()->getGpsDevice()->longitude()
+ +Main->gps()->getGpsDevice()->londelta()
+ +Main->gps()->getGpsDevice()->updatelondelta()));
QPointF g = p->theTransform.map(projection().project(vp));
QPixmap pm = getPixmapFromFile(":/Gps/Gps_Marker.svg", 32);
P.drawPixmap(g - QPoint(16, 16), pm);
Index: src/MainWindow.cpp
===================================================================
--- src/MainWindow.cpp (revision 107)
+++ src/MainWindow.cpp (working copy)
@@ -72,6 +72,7 @@
#include "qgps.h"
#include "qgpsdevice.h"
+#include "trackfilterdialog.h"
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
@@ -2480,8 +2481,16 @@ void MainWindow::on_gpsConnectAction_triggered()
QGPSS60Device* aGps = new QGPSS60Device();
#endif
if (aGps->openDevice()) {
- connect(aGps, SIGNAL(updatePosition(float, float, QDateTime, float, float, float)),
- this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float)));
+ // new: bool adjustposition
+ connect(aGps, SIGNAL(updatePosition(float, float, QDateTime, float, float, float, bool)),
+ this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float, bool)));
+ // run GPSFilter, i.e. open trackfilter dialog when gpsfilter signal received
+ connect(aGps, SIGNAL(gpsfilter(QString, double, double, bool, QPoint)),
+ this, SLOT(GPSFilter(QString, double, double, bool, QPoint)));
+ // forward continue_filtering signal
+ connect(this, SIGNAL(continue_filtering(double, double, bool, bool, QPoint)),
+ aGps, SLOT(continueFiltering(double, double, bool, bool, QPoint)));
+ connect(this, SIGNAL(update_delta(double, double)), aGps, SLOT(UpdateDelta(double, double)));
gpsConnectAction->setEnabled(false);
gpsReplayAction->setEnabled(false);
@@ -2510,8 +2519,9 @@ void MainWindow::on_gpsReplayAction_triggered()
QGPSFileDevice* aGps = new QGPSFileDevice(fileName);
if (aGps->openDevice()) {
- connect(aGps, SIGNAL(updatePosition(float, float, QDateTime, float, float, float)),
- this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float)));
+ // new: bool adjustposition
+ connect(aGps, SIGNAL(updatePosition(float, float, QDateTime, float, float, float, bool)),
+ this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float, bool)));
gpsConnectAction->setEnabled(false);
gpsReplayAction->setEnabled(false);
@@ -2535,13 +2545,15 @@ void MainWindow::on_gpsDisconnectAction_triggered(
gpsRecordAction->setChecked(false);
gpsPauseAction->setChecked(false);
- disconnect(theGPS->getGpsDevice(), SIGNAL(updatePosition(float, float, QDateTime, float, float, float)),
- this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float)));
+ // new: bool adjustposition
+ disconnect(theGPS->getGpsDevice(), SIGNAL(updatePosition(float, float, QDateTime, float, float, float, bool)),
+ this, SLOT(updateGpsPosition(float, float, QDateTime, float, float, float, bool)));
theGPS->stopGps();
theGPS->resetGpsStatus();
}
-void MainWindow::updateGpsPosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading)
+void MainWindow::updateGpsPosition(float latitude, float longitude, QDateTime time, float altitude, float speed, float heading,
+ bool adjustposition)
{
Q_UNUSED(heading)
if (theGPS->getGpsDevice()) {
@@ -2555,7 +2567,9 @@ void MainWindow::on_gpsDisconnectAction_triggered(
}
}
- if (gpsRecordAction->isChecked() && !gpsPauseAction->isChecked()) {
+ // do not record trackpoint if adjustposition is set (used by trackfilter dialog)
+ if (gpsRecordAction->isChecked() && !gpsPauseAction->isChecked()
+ && !adjustposition) {
TrackPoint* pt = new TrackPoint(gpsCoord);
pt->setTime(time);
pt->setElevation(altitude);
@@ -2614,6 +2628,20 @@ void MainWindow::on_gpsPauseAction_triggered()
}
}
+void MainWindow::GPSFilter(QString errmsg, double londelta, double latdelta, bool correctFutureTackpoints, QPoint filterposition)
+{
+ // open trackfilter dialog
+ TrackFilterDialog *dialog = new TrackFilterDialog(this, londelta, latdelta, correctFutureTackpoints, &filterposition);
+ // forward signals
+ connect(dialog,SIGNAL(continue_filtering(double, double, bool, bool, QPoint)),
+ this,SIGNAL(continue_filtering(double, double, bool, bool, QPoint)));
+ connect(dialog, SIGNAL(update_delta(double, double)), this, SIGNAL(update_delta(double, double)));
+ dialog->ErrorMessage->setText(errmsg);
+ dialog->show();
+
+ return;
+}
+
void MainWindow::on_toolTemplatesSaveAction_triggered()
{
QString f = QFileDialog::getSaveFileName(this, tr("Save Tag Templates"), "", tr("Merkaartor tag templates (*.mat)"));