nanomap/monavlayer.cpp

187 lines
5.5 KiB
C++

/*
* Copyright 2010 Niels Kummerfeldt <niels.kummerfeldt@tu-harburg.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "monavlayer.h"
#include "mapwidget.h"
#include "projection.h"
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QPluginLoader>
#include <QtCore/QSettings>
MonavLayer::MonavLayer(MapWidget *map) :
AbstractLayer(map),
m_gpsLookup(0),
m_router(0),
m_loaded(true),
m_routeStart(),
m_routeEnd(),
m_track(),
m_trackOnScreen(),
m_trackOffset(),
m_zoomLevel(0)
{
QSettings set(QDir::homePath()+"/Maps/nanomap.conf", QSettings::NativeFormat);
set.beginGroup("monav");
QString dataDir = set.value("datadir").toString();
QString routerLib = set.value("router",
"/usr/lib/monav/libcontractionhierarchiesclient.so").toString();
QString gpsLookupLib = set.value("gpslookup",
"/usr/lib/monav/libgpsgridclient.so").toString();
set.endGroup();
QSettings pluginSettings(dataDir+"/plugins.ini", QSettings::IniFormat);
QString routerName = pluginSettings.value("router").toString();
QString gpsLookupName = pluginSettings.value("gpsLookup").toString();
QPluginLoader rLoader(routerLib);
QObject *plugin = rLoader.instance();
if (plugin) {
m_router = qobject_cast<IRouter*>(plugin);
if (m_router) {
m_router->SetInputDirectory(dataDir);
m_loaded = m_loaded && m_router->LoadData();
} else {
m_loaded = false;
}
}
QPluginLoader gLoader(gpsLookupLib);
plugin = gLoader.instance();
if (plugin) {
m_gpsLookup = qobject_cast<IGPSLookup*>(plugin);
if (m_gpsLookup) {
m_gpsLookup->SetInputDirectory(dataDir);
m_loaded = m_loaded && m_gpsLookup->LoadData();
} else {
m_loaded = false;
}
}
}
void MonavLayer::zoom(int level)
{
m_zoomLevel = level;
if (m_track.count() > 1) {
int scale = 1 << level;
m_trackOnScreen.clear();
m_trackOffset = map()->raw2screen(m_track.first().x(), m_track.first().y(), scale);
m_trackOnScreen << QPoint(0, 0);
for (int i = 1; i < m_track.count(); ++i) {
QPointF p = m_track.at(i);
m_trackOnScreen << map()->raw2screen(p.x(), p.y(), scale) - m_trackOffset;
}
}
}
void MonavLayer::pan(const QPoint &move)
{
m_trackOffset += move;
}
void MonavLayer::paint(QPainter *painter)
{
if (!m_loaded) {
return;
}
if (m_trackOnScreen.count() > 1) {
QPoint p1, p2 = m_trackOnScreen.first();
for (int i = 1; i < m_trackOnScreen.count(); ++i) {
p1 = m_trackOnScreen.at(i);
painter->drawLine(p1 + m_trackOffset, p2 + m_trackOffset);
p2 = p1;
}
}
QPoint p = map()->geo2screen(m_routeStart.x(), m_routeStart.y());
QPolygon tri;
tri << p << p+QPoint(-5, -9) << p+QPoint(5, -9) << p;
painter->setBrush(Qt::red);
painter->drawPolygon(tri);
p = map()->geo2screen(m_routeEnd.x(), m_routeEnd.y());
tri.clear();
tri << p << p+QPoint(-5, -9) << p+QPoint(5, -9) << p;
painter->setBrush(Qt::blue);
painter->drawPolygon(tri);
}
void MonavLayer::keyPressed(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_R:
{
if (event->modifiers() == Qt::NoModifier) {
findRoute();
}
break;
}
case Qt::Key_S:
{
if (event->modifiers() == Qt::NoModifier) {
m_routeStart = map()->geoPos();
}
break;
}
case Qt::Key_E:
{
if (event->modifiers() == Qt::NoModifier) {
m_routeEnd = map()->geoPos();
}
break;
}
}
}
void MonavLayer::findRoute()
{
if (!m_loaded) {
return;
}
QVector<IRouter::Node> nodes;
QVector<IRouter::Edge> edges;
double lookupRadius = 1000.0;
double dist;
UnsignedCoordinate startCoord(GPSCoordinate(m_routeStart.y(), m_routeStart.x()));
IGPSLookup::Result startPos;
if (!m_gpsLookup->GetNearestEdge(&startPos, startCoord, lookupRadius)) {
qDebug() << "source not found";
return;
}
UnsignedCoordinate endCoord(GPSCoordinate(m_routeEnd.y(), m_routeEnd.x()));
IGPSLookup::Result endPos;
if (!m_gpsLookup->GetNearestEdge(&endPos, endCoord, lookupRadius)) {
qDebug() << "target not found";
return;
}
if (m_router->GetRoute(&dist, &nodes, &edges, startPos, endPos)) {
qDebug() << "route found";
m_track.clear();
for (int j = 0; j < nodes.size(); ++j) {
GPSCoordinate c = nodes[j].coordinate.ToGPSCoordinate();
m_track << QPointF(Projection::lon2rawx(c.longitude), Projection::lat2rawy(c.latitude));
}
zoom(m_zoomLevel);
}
}