File indexing completed on 2024-12-08 09:32:24

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
0004 //
0005 
0006 #include "vehicletracking.h"
0007 
0008 #include <QApplication>
0009 #include <QThread>
0010 #include <QTimer>
0011 #include <qmath.h>
0012 #include <QDebug>
0013 #include <QVBoxLayout>
0014 
0015 #include <marble/MarbleWidget.h>
0016 #include <marble/MarbleGlobal.h>
0017 #include <marble/GeoDataDocument.h>
0018 #include <marble/GeoDataLineString.h>
0019 #include <marble/GeoDataTreeModel.h>
0020 #include <marble/MarbleModel.h>
0021 
0022 
0023 using namespace Marble;
0024 
0025 CarWorker::CarWorker(const GeoDataCoordinates &city, qreal radius, qreal speed) :
0026     QObject(),
0027     m_timer(new QTimer(this)),
0028     m_city(city),
0029     m_radius(radius),
0030     m_speed(speed),
0031     m_alpha(0.0)
0032 {}
0033 
0034 void CarWorker::startWork()
0035 {
0036     m_timer->setInterval(0);
0037     connect(m_timer, SIGNAL(timeout()), this, SLOT(iterate()));
0038     m_timer->start();
0039 }
0040 
0041 void CarWorker::iterate()
0042 {
0043     qreal lon = m_city.longitude(GeoDataCoordinates::Degree) + m_radius * qCos(m_alpha * DEG2RAD);
0044     qreal lat = m_city.latitude(GeoDataCoordinates::Degree) + m_radius * qSin(m_alpha * DEG2RAD);
0045 
0046     GeoDataCoordinates coord(lon, lat, 0.0, GeoDataCoordinates::Degree);
0047     emit coordinatesChanged(coord);
0048 
0049     m_alpha += m_speed;
0050 }
0051 
0052 void CarWorker::finishWork()
0053 {
0054     m_timer->stop();
0055 }
0056 
0057 Window::Window(QWidget *parent) :
0058     QWidget(parent),
0059     m_marbleWidget(new MarbleWidget)
0060 {
0061     QVBoxLayout *layout = new QVBoxLayout(this);
0062     layout->addWidget(m_marbleWidget);
0063     setLayout(layout);
0064 
0065     // Load the OpenStreetMap map
0066     m_marbleWidget->setMapThemeId(QStringLiteral("earth/openstreetmap/openstreetmap.dgml"));
0067     m_marbleWidget->setProjection( Mercator );
0068     setGeometry(80, 60, 1000, 800);
0069     GeoDataCoordinates Kiev(30.523333, 50.45, 0.0, GeoDataCoordinates::Degree);
0070     m_marbleWidget->centerOn(Kiev);
0071     m_marbleWidget->setZoom(2300);
0072 
0073     m_carFirst = new GeoDataPlacemark(QStringLiteral("Bus"));
0074     m_carSecond = new GeoDataPlacemark(QStringLiteral("Car"));
0075 
0076     GeoDataDocument *document = new GeoDataDocument;
0077 
0078     document->append(m_carFirst);
0079     document->append(m_carSecond);
0080 
0081     m_marbleWidget->model()->treeModel()->addDocument(document);
0082 
0083     show();
0084 }
0085 
0086 void Window::startCars()
0087 {
0088     GeoDataCoordinates Kiev(30.523333, 50.45, 0.0, GeoDataCoordinates::Degree);
0089 
0090     m_threadFirst = new QThread;
0091     m_firstWorker = new CarWorker(Kiev, (qreal)0.1, (qreal)0.7);
0092     m_firstWorker->moveToThread(m_threadFirst);
0093 
0094     connect(m_firstWorker, SIGNAL(coordinatesChanged(GeoDataCoordinates)),
0095             this, SLOT(setCarCoordinates(GeoDataCoordinates)), Qt::BlockingQueuedConnection);
0096 
0097     m_threadSecond = new QThread;
0098     m_secondWorker = new CarWorker(Kiev, (qreal)0.2, (qreal)-0.5);
0099     m_secondWorker->moveToThread(m_threadSecond);
0100 
0101     connect(m_secondWorker, SIGNAL(coordinatesChanged(GeoDataCoordinates)),
0102             this, SLOT(setCarCoordinates(GeoDataCoordinates)), Qt::BlockingQueuedConnection);
0103 
0104     connect(m_threadFirst, SIGNAL(started()), m_firstWorker, SLOT(startWork()));
0105     connect(m_threadFirst, SIGNAL(finished()), m_firstWorker, SLOT(finishWork()));
0106 
0107     connect(m_threadSecond, SIGNAL(started()), m_secondWorker, SLOT(startWork()));
0108     connect(m_threadSecond, SIGNAL(finished()), m_secondWorker, SLOT(finishWork()));
0109 
0110     m_threadFirst->start();
0111     m_threadSecond->start();
0112 }
0113 
0114 void Window::setCarCoordinates(const GeoDataCoordinates &coord)
0115 {
0116     CarWorker *worker = qobject_cast<CarWorker*>(sender());
0117     if (worker == m_firstWorker) {
0118         m_carFirst->setCoordinate(coord);
0119         m_marbleWidget->model()->treeModel()->updateFeature(m_carFirst);
0120     } else if (worker == m_secondWorker) {
0121         m_carSecond->setCoordinate(coord);
0122         m_marbleWidget->model()->treeModel()->updateFeature(m_carSecond);
0123     }
0124 }
0125 
0126 // Main (start point)
0127 int main(int argc, char** argv)
0128 {
0129     QApplication app(argc,argv);
0130 
0131     Window window;
0132     window.startCars();
0133 
0134     return app.exec();
0135 }
0136 
0137 #include "moc_vehicletracking.cpp"