--- /dev/null
+#include "gpscontroller.h"
+
+#include <QObject>
+#include <QGeoPositionInfo>
+#include <QGeoPositionInfoSource>
+#include <QDebug>
+
+QTM_USE_NAMESPACE
+
+GpsController::~GpsController()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ delete m_location;
+ m_location = 0;
+}
+
+GpsController::GpsController() :
+ m_location( QGeoPositionInfoSource::createDefaultSource(this) )
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ m_location->setUpdateInterval( 1*60*1000 );
+
+ connect(
+ m_location, SIGNAL( positionUpdated( QGeoPositionInfo ) ),
+ this, SLOT( updateLocation( QGeoPositionInfo ) )
+ );
+
+ m_location->stopUpdates();
+}
+
+void GpsController::updateLocation( QGeoPositionInfo positionInfo )
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ Location newLocation( positionInfo );
+
+ emit locationChanged( newLocation );
+}
+
+void GpsController::startGps()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+ m_location->startUpdates();
+}
--- /dev/null
+#ifndef GPSCONTROLLER_H
+#define GPSCONTROLLER_H
+
+#include "location.h"
+
+#include <QObject>
+#include <QGeoPositionInfo>
+#include <QGeoPositionInfoSource>
+
+QTM_USE_NAMESPACE
+
+class GpsController : public QObject
+{
+ Q_OBJECT
+
+public:
+ GpsController();
+
+ ~GpsController();
+
+ void startGps();
+ void stopGps();
+
+public Q_SLOTS:
+ void updateLocation( QGeoPositionInfo positionInfo );
+
+Q_SIGNALS:
+ void locationChanged( const Location &newLocation );
+
+private:
+ QGeoPositionInfoSource *m_location;
+};
+
+#endif // GPSCONTROLLER_H
#include <QDebug>
#include <QXmlStreamAttributes>
#include <QStringRef>
+#include <QGeoPositionInfo>
+
+#include <math.h>
+
+const double Location::KkjZoneInfo[6][2] = {
+ {18.0, 500000.0},
+ {21.0, 1500000.0},
+ {24.0, 2500000.0},
+ {27.0, 3500000.0},
+ {30.0, 4500000.0},
+ {33.0, 5500000.0}
+};
+
+QTM_USE_NAMESPACE
Location::Location( QString x, QString y ) :
q( new LocationPrivate( x, y ) ),
connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
}
+Location::Location( const QGeoPositionInfo &positionInfo ) :
+ q( new LocationPrivate() ),
+ manager(0)
+{
+ qreal latitude = positionInfo.coordinate().latitude();
+ qreal longitude = positionInfo.coordinate().longitude();
+
+ KKJ outX(0);
+ KKJ outY(0);
+
+ WGS84lola_to_KKJxy( longitude, latitude, &outX, &outY);
+
+ q->setX( outX );
+ q->setY( outY );
+ q->setValid( true );
+}
+
Location::Location( const Location &from ) :
- QObject( 0 ),
+ QObject(0),
q( new LocationPrivate() ),
- manager( new QNetworkAccessManager(this) )
+ manager(0)
{
q->setX( from.x() );
q->setY( from.y() );
q->setValid( from.isValid() );
- connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
+ if ( from.manager != 0 ) {
+ manager = new QNetworkAccessManager(this);
+ connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
+ }
}
Location::Location() :
Location &Location::operator=( const Location &from )
{
+ q = new LocationPrivate();
q->setX( from.x() );
q->setY( from.y() );
q->setValid( from.isValid() );
- manager = new QNetworkAccessManager(this);
- connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
+ if ( from.manager != 0 ) {
+ manager = new QNetworkAccessManager(this);
+ connect( manager, SIGNAL( finished(QNetworkReply*) ), this, SLOT( replyFinished(QNetworkReply*) ) );
+ } else {
+ manager = 0;
+ }
return *this;
}
{
return q->isValid();
}
+
+
+// Degrees to radians
+double Location::radians(double deg)
+{
+ return deg * M_PI / 180.0;
+}
+
+// Radians to degrees
+double Location::degrees(double rad)
+{
+ return rad * 180.0 / M_PI;
+}
+
+// Function: KKJ_Zone_I
+int Location::KKJ_Zone_I(KKJ easting)
+{
+ int zoneNumber = floor(easting / 1000000.0);
+ if (zoneNumber < 0 || zoneNumber > 5) {
+ zoneNumber = -1;
+ }
+
+ return zoneNumber;
+}
+
+// Function: KKJ_Zone_Lo
+int Location::KKJ_Zone_Lo(double kkjlo)
+{
+ // determine the zonenumber from KKJ easting
+ // takes KKJ zone which has center meridian
+ // longitude nearest (in math value) to
+ // the given KKJ longitude
+ int zoneNumber = 5;
+ while (zoneNumber >= 0) {
+ if (fabs(kkjlo - KkjZoneInfo[zoneNumber][0]) <= 1.5) {
+ break;
+ }
+ zoneNumber--;
+ }
+
+ return zoneNumber;
+}
+
+
+// Function: KKJlalo_to_WGS84lalo
+void Location::KKJlola_to_WGS84lola(double kkjlo, double kkjla, double *outLongitude, double *outLatitude)
+{
+ double dLa = radians(0.124867E+01 + -0.269982E+00 * kkjla + 0.191330E+00 * kkjlo + 0.356119E-02 * kkjla * kkjla + -0.122312E-02 * kkjla * kkjlo + -0.335514E-03 * kkjlo * kkjlo) / 3600.0;
+ double dLo = radians(-0.286111E+02 + 0.114183E+01 * kkjla + -0.581428E+00 * kkjlo + -0.152421E-01 * kkjla * kkjla + 0.118177E-01 * kkjla * kkjlo + 0.826646E-03 * kkjlo * kkjlo) / 3600.0;
+
+ *outLatitude = degrees(radians(kkjla) + dLa);
+ *outLongitude = degrees(radians(kkjlo) + dLo);
+}
+
+
+// Function: WGS84lalo_to_KKJlalo
+void Location::WGS84lola_to_KKJlola(double longitude, double latitude, double *outLongitude, double *outLatitude)
+{
+ double dLa = radians(-0.124766E+01 + 0.269941E+00 * latitude + -0.191342E+00 * longitude + -0.356086E-02 * latitude * latitude + 0.122353E-02 * latitude * longitude + 0.335456E-03 * longitude * longitude) / 3600.0;
+ double dLo = radians(0.286008E+02 + -0.114139E+01 * latitude + 0.581329E+00 * longitude + 0.152376E-01 * latitude * latitude + -0.118166E-01 * latitude * longitude + -0.826201E-03 * longitude * longitude) / 3600.0;
+
+ *outLatitude = degrees(radians(latitude) + dLa);
+ *outLongitude = degrees(radians(longitude) + dLo);
+}
+
+
+// Function: KKJlalo_to_KKJxy
+void Location::KKJlola_to_KKJxy(double lon, double lat, int zoneNumber, KKJ *outX, KKJ *outY)
+{
+ // Hayford ellipsoid
+ double a = 6378388.0;
+ double f = 1.0 / 297.0;
+ double b = (1.0 - f) * a;
+ double bb = b * b;
+ double c = (a / b) * a;
+ double ee = (a * a - bb) / bb;
+ double n = (a - b) / (a + b);
+ double nn = n * n;
+
+ double Lo = radians(lon) - radians(KkjZoneInfo[zoneNumber][0]);
+ double cosLa = cos(radians(lat));
+ double NN = ee * cosLa * cosLa;
+ double LaF = atan(tan(radians(lat)) / cos(Lo * sqrt(1.0 + NN)));
+ double cosLaF = cos(LaF);
+ double t = (tan(Lo) * cosLaF) / sqrt(1.0 + ee * cosLaF * cosLaF);
+ double A = a / (1.0 + n);
+ double A1 = A * (1.0 + nn / 4.0 + nn * nn / 64.0);
+ double A2 = A * 1.5 * n * (1.0 - nn / 8.0);
+ double A3 = A * 0.9375 * nn * (1.0 - nn / 4.0);
+ double A4 = A * 35.0 / 48.0 * nn * n;
+
+ *outY = A1 * LaF - A2 * sin(2.0 * LaF) + A3 * sin(4.0 * LaF) - A4 * sin(6.0 * LaF);
+ *outX = c * log(t + sqrt(1.0 + t * t)) + 500000.0 + zoneNumber * 1000000.0;
+}
+
+// Function: KKJxy_to_KKJlalo
+void Location::KKJxy_to_KKJlola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
+{
+ // Scan iteratively the target area, until find matching
+ // KKJ coordinate value. Area is defined with Hayford Ellipsoid.
+ int zoneNumber = KKJ_Zone_I(x);
+ double minLo = radians(18.5);
+ double maxLo = radians(32.0);
+ double minLa = radians(59.0);
+ double maxLa = radians(70.5);
+
+ int i = 1;
+ KKJ tmpX, tmpY;
+
+ while (i < 35) {
+ double deltaLo = maxLo - minLo;
+ double deltaLa = maxLa - minLa;
+ *outLongitude = degrees(minLo + 0.5 * deltaLo);
+ *outLatitude = degrees(minLa + 0.5 * deltaLa);
+ KKJlola_to_KKJxy(*outLongitude, *outLatitude, zoneNumber, &tmpX, &tmpY);
+ if (tmpY < y) {
+ minLa = minLa + 0.45 * deltaLa;
+ } else {
+ maxLa = minLa + 0.55 * deltaLa;
+ }
+
+ if (tmpX < x) {
+ minLo = minLo + 0.45 * deltaLo;
+ } else {
+ maxLo = minLo + 0.55 * deltaLo;
+ }
+
+ i++;
+ }
+}
+
+void Location::WGS84lola_to_KKJxy(double longitude, double latitude, KKJ *outX, KKJ *outY)
+{
+ double kkjlo, kkjla;
+
+ WGS84lola_to_KKJlola(longitude, latitude, &kkjlo, &kkjla);
+ int zoneNumber = KKJ_Zone_Lo(kkjlo);
+ KKJlola_to_KKJxy(kkjlo, kkjla, zoneNumber, outX, outY);
+}
+
+void Location::KKJxy_to_WGS84lola(KKJ x, KKJ y, double *outLongitude, double *outLatitude)
+{
+ double kkjlo, kkjla;
+
+ KKJxy_to_KKJlola(x, y, &kkjlo, &kkjla);
+ KKJlola_to_WGS84lola(kkjlo, kkjla, outLongitude, outLatitude);
+
+}
+
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
+#include <QGeoPositionInfo>
+#include <math.h>
+
+QTM_USE_NAMESPACE
class Location : public QObject
{
- Q_OBJECT
+Q_OBJECT
public:
Location( QString x, QString y );
+ Location( const QGeoPositionInfo &positionInfo );
Location( const Location &from );
Location &operator=( const Location &from );
Location();
bool isValid() const;
-public Q_SLOTS:
- void resolveAddress( QString address );
+ public Q_SLOTS:
+ void resolveAddress( QString address );
Q_SIGNALS:
void becomeValid();
-private Q_SLOTS:
- void replyFinished( QNetworkReply * reply );
+ private Q_SLOTS:
+ void replyFinished( QNetworkReply * reply );
private:
LocationPrivate *q;
QNetworkAccessManager *manager;
+
+ QString m_x;
+ QString m_y;
+ QString m_valid;
+
+ typedef uint KKJ;
+
+ /**
+ * Transformes WGS84 longitude/latitude coordinates to KKJ x/y coordinates.
+ * @param longitude the input longitude in degrees
+ * @param latitude the input latitude in degrees
+ * @param outX the result x (easting)
+ * @param outY the result y (northing)
+ */
+ void WGS84lola_to_KKJxy(double longitude, double latitude, KKJ *outX, KKJ *outY);
+
+ /**
+ * Transformes KKJ x/y coordinates to WGS84 longitude/latitude coordinates.
+ * @param x the input x (easting)
+ * @param y the input y (northing)
+ * @param outLongitude the result longitude in degrees
+ * @param outLatitude the result latitude in degrees
+ */
+ void KKJxy_to_WGS84lola(KKJ x, KKJ y, double *outLongitude, double *outLatitude);
+
+ // Degrees to radians
+ double radians(double deg);
+
+ // Radians to degrees
+ double degrees(double rad);
+
+ // Constants
+ // Longitude0 and Center meridian of KKJ bands
+ static const double KkjZoneInfo[][2];
+
+ // Function: KKJ_Zone_I
+ int KKJ_Zone_I(KKJ easting);
+
+ // Function: KKJ_Zone_Lo
+ int KKJ_Zone_Lo(double kkjlo);
+
+ // Function: KKJlalo_to_WGS84lalo
+ void KKJlola_to_WGS84lola(double kkjlo, double kkjla, double *outLongitude, double *outLatitude);
+
+ // Function: WGS84lalo_to_KKJlalo
+ void WGS84lola_to_KKJlola(double longitude, double latitude, double *outLongitude, double *outLatitude);
+
+ // Function: KKJlalo_to_KKJxy
+ void KKJlola_to_KKJxy(double lon, double lat, int zoneNumber, KKJ *outX, KKJ *outY);
+
+ // Function: KKJxy_to_KKJlalo
+ void KKJxy_to_KKJlola(KKJ x, KKJ y, double *outLongitude, double *outLatitude);
+
};
#endif // LOCATION_H
+#include <stdio.h>
#include "location_p.h"
#include <QXmlStreamReader>
{
}
+LocationPrivate::~LocationPrivate()
+{
+}
+
void LocationPrivate::parseReply( const QByteArray &reply )
{
QXmlStreamReader xml( reply );
}
}
+void LocationPrivate::setX( uint x )
+{
+ m_x = QString( "%1" ).arg( x );
+}
+
void LocationPrivate::setX( QString x )
{
m_x = x;
return m_x;
}
+void LocationPrivate::setY( uint y )
+{
+ m_y = QString( "%1" ).arg( y );
+}
+
void LocationPrivate::setY( QString y )
{
m_y = y;
Q_OBJECT
public:
+ QString m_x;
+ QString m_y;
+ bool m_valid;
LocationPrivate( QString x, QString y );
LocationPrivate();
+ virtual ~LocationPrivate();
+ void setX( uint x );
void setX( QString x );
QString x() const;
+ void setY( uint y );
void setY( QString y );
QString y() const;
void parseReply( const QByteArray &reply );
-private:
- QString m_x;
- QString m_y;
- bool m_valid;
};
#endif // LOCATION_P_H
#include "ui_zouba.h"
#include "uicontroller.h"
#include "location.h"
+#include "gpscontroller.h"
#include "ytv.h"
uiController, SLOT( displayRoute( RouteData ) )
);
- Location *from = new Location();
+ GpsController *gpsController = new GpsController();
Location *to = new Location();
QObject::connect(
- from, SIGNAL( becomeValid() ),
- route, SLOT( setFromLocation() )
+ gpsController, SIGNAL( locationChanged( Location ) ),
+ route, SLOT( setFromLocation( Location ) )
);
QObject::connect(
to, SIGNAL( becomeValid() ),
route, SLOT( setToLocation() )
);
- ui.homeaddress->setText( home );
+ ui.homeaddress->setText( "GPS" );
ui.workaddress->setText( work );
- from->resolveAddress( home );
+ gpsController->startGps();
to->resolveAddress( work );
QObject::connect(
- uiController, SIGNAL( homeAddressChanged( QString ) ),
- from, SLOT( resolveAddress( QString ) )
- );
-
- QObject::connect(
uiController, SIGNAL( workAddressChanged( QString ) ),
to, SLOT( resolveAddress( QString ) )
);
- /* toggle doesn't work yet because 'from' is connected to 'homeAddressChanged'
- QObject::connect(
- uiController, SIGNAL( directionChanged() ),
- route, SLOT( toggleDirection() )
- );
- */
-
widget->show();
return app.exec();
}
void Route::setFromLocation( const Location &location )
{
+ qDebug() << __PRETTY_FUNCTION__;
if ( location.isValid() ) {
+ qDebug() << "from location is valid";
q->setFromLocation( location );
+ if ( q->toValid() ) {
+ qDebug() << "to is also valid; getting route";
+ getRoute();
+ }
} else {
+ qDebug() << "location is NOT valid - obtaining from sender";
Location *locationPtr = qobject_cast<Location*>(sender());
if ( locationPtr ) {
q->setFromLocation( *locationPtr );
if ( q->toValid() ) {
+ qDebug() << "to is also valid; getting route";
getRoute();
+ } else {
+ qDebug() << "to is NOT valid";
}
+ } else {
+ qDebug() << "locationPtr is zero - cast didn't work";
}
}
}
void Route::setToLocation( const Location &location )
{
+ qDebug() << __PRETTY_FUNCTION__;
if ( location.isValid() ) {
+ qDebug() << "to is valid";
q->setToLocation( location );
+ if ( q->fromValid() ) {
+ qDebug() << "from is also valid; getting route";
+ getRoute();
+ } else {
+ qDebug() << "from is NOT valid";
+ }
} else {
+ qDebug() << "to is not valid; getting from sender";
Location *locationPtr = qobject_cast<Location*>(sender());
if ( locationPtr ) {
q->setToLocation( *locationPtr );
if ( q->fromValid() ) {
+ qDebug() << "from is also valid; getting route";
getRoute();
+ } else {
+ qDebug() << "from is not valid";
}
+ } else {
+ qDebug() << "locationPtr is zero; cast failed";
}
}
}
#include <QObject>
#include <QtDebug>
#include <QByteArray>
+#include <QGeoPositionInfo>
+#include "location.h"
+#include "location_p.h"
#include "ut_location.h"
+QTM_USE_NAMESPACE
+
QByteArray sampleInput(
"\
<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?><MTRXML version=\"1.0\">\
<GEOCODE key=\"taivaanvuohentie 7,helsinki\">\
-<LOC name1=\"Taivaanvuohentie\" number=\"7\" city=\"Helsinki\" code=\"\" address=\"\" type=\"900\" category=\"street\" x=\"2549183\" y=\"6672570\" lon=\"24.88256\" lat=\"60.16183\" />\
+<LOC name1=\"Taivaanvuohentie\" number=\"7\" city=\"Helsinki\" code=\"\" address=\"\" type=\"900\" category=\"street\" x=\"2549182\" y=\"6672569\" lon=\"24.88256\" lat=\"60.16183\" />\
</GEOCODE>\
</MTRXML>\
"
void Ut_Location::init()
{
- m_subject = new LocationPrivate();
}
void Ut_Location::cleanup()
{
- delete m_subject;
- m_subject = 0;
}
void Ut_Location::initTestCase()
void Ut_Location::testParseReply()
{
- m_subject->parseReply( sampleInput );
+ LocationPrivate m_subject;
+
+ m_subject.parseReply( sampleInput );
- QCOMPARE( m_subject->x(), QString( "2549183" ) );
- QCOMPARE( m_subject->y(), QString( "6672570" ) );
+ QCOMPARE( m_subject.x(), QString( "2549182" ) );
+ QCOMPARE( m_subject.y(), QString( "6672569" ) );
}
void Ut_Location::testSet()
{
- QString x( "2549183" );
- QString y( "6672570" );
- m_subject->setX( x );
- m_subject->setY( y );
- QCOMPARE( x, m_subject->x() );
- QCOMPARE( y, m_subject->y() );
+ LocationPrivate m_subject;
+
+ QString x( "2549182" );
+ QString y( "6672569" );
+ m_subject.setX( x );
+ m_subject.setY( y );
+ QCOMPARE( x, m_subject.x() );
+ QCOMPARE( y, m_subject.y() );
+}
+
+void Ut_Location::testConstructorQGeoPositionInfo()
+{
+ QGeoPositionInfo thisPositionInfo( QGeoCoordinate( 60.16183, 24.88256 ), QDateTime( QDate( 1965, 11, 11 ) ) );
+ Location subject( thisPositionInfo );
+
+ QString x( "2549182" );
+ QString y( "6672569" );
+ QCOMPARE( subject.x(), x );
+ QCOMPARE( subject.y(), y );
}
QTEST_MAIN(Ut_Location)
class Ut_Location : public QObject
{
- Q_OBJECT
+Q_OBJECT
public:
private slots:
- void init();
- void cleanup();
- void initTestCase();
- void cleanupTestCase();
- void testParseReply();
- void testSet();
+ void init();
+ void cleanup();
+ void initTestCase();
+ void cleanupTestCase();
+ void testParseReply();
+ void testSet();
+ void testConstructorQGeoPositionInfo();
private:
- LocationPrivate *m_subject;
+ LocationPrivate *m_subject;
};
#endif // UT_LOCATION_H
CONFIG += \
qt \
debug \
+ mobility \
+
+MOBILITY = \
+ location \
+ bearer \
QT += \
testlib \
+ network \
INCLUDEPATH += \
../.. \
DEPENDPATH += $$INCLUDEPATH
+LIBS += \
+ /usr/lib/libQtLocation.so \
+
TEMPLATE = app
SOURCES = \
ut_location.cpp \
+ ../../location.cpp \
../../location_p.cpp \
HEADERS += \
ut_location.h \
+ ../../location.h \
../../location_p.h \
CONFIG += \
qt \
debug \
+ mobility \
+
+MOBILITY = \
+ location \
+ bearer \
QT += \
testlib \
TEMPLATE = app
+LIBS += \
+ /usr/lib/libQtLocation.so \
+
SOURCES = \
ut_route.cpp \
../../route_p.cpp \
-CONFIG += qt \
- debug
-QT += network
+CONFIG += \
+ qt \
+ debug \
+ mobility \
+
+MOBILITY = \
+ location \
+ bearer \
+
+LIBS += \
+ /usr/lib/libQtLocation.so \
+
+DEFINES+= Q_WS_MAEMO_5
+
+QT += \
+ network \
+
TEMPLATE = app
+
FORMS = zouba.ui
-SOURCES = main.cpp \
+
+SOURCES += \
+ main.cpp \
route.cpp \
route_p.cpp \
uicontroller.cpp \
location.cpp \
- location_p.cpp
-HEADERS += route.h \
+ location_p.cpp \
+ gpscontroller.cpp \
+
+HEADERS += \
+ route.h \
route_p.h \
uicontroller.h \
location.h \
location_p.h \
- ytv.h
+ ytv.h \
+ gpscontroller.h \
+