diff --git a/abstractlayer.cpp b/abstractlayer.cpp new file mode 100644 index 0000000..bd3ef4d --- /dev/null +++ b/abstractlayer.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "abstractlayer.h" + +#include "mapwidget.h" + +AbstractLayer::AbstractLayer(MapWidget *map) : + QObject(map), + m_map(map), + m_visible(true) +{ +} + +void AbstractLayer::load(const QString &filename) +{ + Q_UNUSED(filename) +} + +void AbstractLayer::zoom(int level) +{ + Q_UNUSED(level) +} + +void AbstractLayer::pan(const QPoint &move) +{ + Q_UNUSED(move) +} + +void AbstractLayer::triggerAction() +{ +} + +void AbstractLayer::paintLayer(QPainter *painter) +{ + if (m_visible) { + painter->save(); + paint(painter); + painter->restore(); + } +} + +MapWidget *AbstractLayer::map() const +{ + return m_map; +} + +bool AbstractLayer::isVisible() const +{ + return m_visible; +} + +void AbstractLayer::setVisible(bool visible) +{ + m_visible = visible; +} + +void AbstractLayer::toggleVisibility() +{ + m_visible = !m_visible; +} + diff --git a/abstractlayer.h b/abstractlayer.h new file mode 100644 index 0000000..f9a08bb --- /dev/null +++ b/abstractlayer.h @@ -0,0 +1,64 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef ABSTRACT_LAYER_H +#define ABSTRACT_LAYER_H + +#include +#include + +class MapWidget; + +enum Layer +{ + Tracks, + Marker, + Time, + System, + User +}; + +class AbstractLayer : public QObject +{ + Q_OBJECT +public: + AbstractLayer(MapWidget *map); + + virtual void load(const QString &filename); + virtual void zoom(int level); + virtual void pan(const QPoint &move); + virtual void triggerAction(); + + void paintLayer(QPainter *painter); + + MapWidget *map() const; + bool isVisible() const; + void setVisible(bool visible = true); + void toggleVisibility(); + +protected: + virtual void paint(QPainter *painter) = 0; + +private: + MapWidget *m_map; + bool m_visible; + +}; + +#endif // ABSTRACT_LAYER_H diff --git a/batterylayer.cpp b/batterylayer.cpp new file mode 100644 index 0000000..824e2d1 --- /dev/null +++ b/batterylayer.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "batterylayer.h" + +#include "mapwidget.h" + +#include +#include +//#include +#include +#include + +BatteryLayer::BatteryLayer(MapWidget *map) : + AbstractLayer(map), + m_updateTimer(new QTimer(this)), + m_percent(0), + m_isCharging(false) +{ + m_updateTimer->setInterval(60 * 1000); + connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(repaint())); + m_updateTimer->start(); + +// QFileSystemWatcher *w = new QFileSystemWatcher(this); +// w->addPath("/sys/class/power_supply/battery/capacity"); +// w->addPath("/sys/class/power_supply/battery/status"); +// connect(w, SIGNAL(fileChanged(QString)), this, SLOT(fileChanged(QString))); + + repaint(); +} + +void BatteryLayer::paint(QPainter *painter) +{ + int w = map()->width(); + int h = map()->height(); + + painter->setBrush(QBrush(QColor(255, 255, 255, 210))); + painter->drawRoundedRect(w - 111, h - 17, 110, 16, 5, 5); + painter->drawText(w - 101, h - 15, 90, 14, Qt::AlignCenter, QString("%1%").arg(m_percent)); + if (m_isCharging) { + painter->setBrush(QBrush(QColor(0, 255, 0, 110))); + } else { + painter->setBrush(QBrush(QColor(0, 0, 255, 110))); + } + painter->drawRoundedRect(w - 111, h - 17, 10 + m_percent, 16, 5, 5); +} + +void BatteryLayer::repaint() +{ + if (isVisible()) { + int percent = m_percent; + QFile capacity("/sys/class/power_supply/battery/capacity"); + if (capacity.open(QFile::ReadOnly | QFile::Text)) { + QTextStream in(&capacity); + QString l = in.readLine(); + percent = l.toInt(); + } + + bool charging = m_isCharging; + QFile status("/sys/class/power_supply/battery/status"); + if (status.open(QFile::ReadOnly | QFile::Text)) { + QTextStream in(&status); + QString l = in.readLine().toLower(); + charging = (l == "charging"); + } + + if (charging != m_isCharging || percent != m_percent) { + m_percent = percent; + m_isCharging = charging; + map()->update(); + } + } +} + +void BatteryLayer::fileChanged(const QString &filename) +{ + qDebug() << filename; + repaint(); +} + diff --git a/batterylayer.h b/batterylayer.h new file mode 100644 index 0000000..e368f4c --- /dev/null +++ b/batterylayer.h @@ -0,0 +1,48 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef BATTERY_LAYER_H +#define BATTERY_LAYER_H + +#include "abstractlayer.h" + +#include +#include + +class BatteryLayer : public AbstractLayer +{ + Q_OBJECT +public: + BatteryLayer(MapWidget *map); + +protected: + virtual void paint(QPainter *painter); + +private slots: + void repaint(); + void fileChanged(const QString &filename); + +private: + QTimer *m_updateTimer; + int m_percent; + bool m_isCharging; + +}; + +#endif // BATTERY_LAYER_H diff --git a/gpxlayer.cpp b/gpxlayer.cpp new file mode 100644 index 0000000..ecd49e0 --- /dev/null +++ b/gpxlayer.cpp @@ -0,0 +1,141 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "gpxlayer.h" + +#include "mapwidget.h" +#include "projection.h" + +#include +#include +#include + +GpxLayer::GpxLayer(MapWidget *map) : + AbstractLayer(map) +{ +} + +void GpxLayer::load(const QString &filename) +{ + QFile file(filename); + if (file.open(QIODevice::ReadOnly)) { + QXmlStreamReader xml(&file); + + QPolygonF points; + QList elev; + QList time; + + QString tag, tag2; + QString name; + QPointF pos; + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == "trkpt") { + tag = "trkpt"; + float lat = xml.attributes().value("lat").toString().toFloat(); + float lon = xml.attributes().value("lon").toString().toFloat(); + + points << QPointF(Projection::lon2rawx(lon), Projection::lat2rawy(lat)); + } else if (xml.name() == "ele") { + tag2 = "ele"; + } else if (xml.name() == "time") { + tag2 = "time"; + } else if (xml.name() == "wpt") { + tag = "wpt"; + float lat = xml.attributes().value("lat").toString().toFloat(); + float lon = xml.attributes().value("lon").toString().toFloat(); + + pos = QPointF(lon, lat); + } else if (xml.name() == "name") { + tag2 = "name"; + } else if (xml.name() == "trk" || + xml.name() == "trkseg") { + } else { + tag2.clear(); + } + } else if (xml.isEndElement()) { + if (xml.name() == "trkseg") { + if (!points.isEmpty()) { + m_track << points; + m_track << QPointF(); + } + points.clear(); + elev.clear(); + time.clear(); + } else if (xml.name() == "wpt") { + //addMarker(pos, name); + name.clear(); + } + } else if (xml.isCharacters() && !xml.isWhitespace()) { + if (tag == "trkpt") { + if (tag2 == "ele") { + elev << xml.text().toString().toFloat(); + } else if (tag2 == "time") { + QDateTime dt = QDateTime::fromString(xml.text().toString(), Qt::ISODate); + time << dt.toTime_t(); + } + } else if (tag == "wpt") { + if (tag2 == "name") { + name = xml.text().toString(); + } + } + } + } + zoom(0); + } +} + +void GpxLayer::zoom(int 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); + if (!p.isNull()) { + m_trackOnScreen << map()->raw2screen(p.x(), p.y(), scale) - m_trackOffset; + } else { + m_trackOnScreen << QPoint(); + } + } + } +} + +void GpxLayer::pan(const QPoint &move) +{ + m_trackOffset += move; +} + +void GpxLayer::paint(QPainter *painter) +{ + 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); + if (!p1.isNull()) { + painter->drawLine(p1 + m_trackOffset, p2 + m_trackOffset); + p2 = p1; + } + } + } +} + diff --git a/gpxlayer.h b/gpxlayer.h new file mode 100644 index 0000000..c402d07 --- /dev/null +++ b/gpxlayer.h @@ -0,0 +1,47 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef GPX_LAYER_H +#define GPX_LAYER_H + +#include "abstractlayer.h" + +#include + +class GpxLayer : public AbstractLayer +{ + Q_OBJECT +public: + GpxLayer(MapWidget *map); + + virtual void load(const QString &filename); + virtual void zoom(int level); + virtual void pan(const QPoint &move); + +protected: + virtual void paint(QPainter *painter); + +private: + QPolygonF m_track; + QList m_trackOnScreen; + QPoint m_trackOffset; + +}; + +#endif // GPX_LAYER_H diff --git a/mainwidget.cpp b/mainwidget.cpp index fc10af1..f7ed106 100644 --- a/mainwidget.cpp +++ b/mainwidget.cpp @@ -23,6 +23,13 @@ #include "mapwidget.h" #include "markerlist.h" +#include "batterylayer.h" +#include "gpxlayer.h" +#include "markerlayer.h" +#include "timelayer.h" + +#include +#include #include MainWidget::MainWidget(QWidget *parent) @@ -32,19 +39,43 @@ MainWidget::MainWidget(QWidget *parent) m_markerList(new MarkerList(this)), m_dlWidget(new DownloadWidget(this)) { + QString fileName; + if (QApplication::arguments().count() > 1) { + fileName = QApplication::arguments().at(1); + } + QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_stack); + AbstractLayer *l = new TimeLayer(m_map); + l->setVisible(false); + m_map->addLayer(Time, l); + + l = new BatteryLayer(m_map); + l->setVisible(false); + m_map->addLayer(System, l); + + l = new GpxLayer(m_map); + if (fileName.endsWith(".gpx")) { + l->load(fileName); + } + m_map->addLayer(Tracks, l); + + l = new MarkerLayer(m_map); + connect(l, SIGNAL(markerAdded(QString)), m_markerList, SLOT(addMarker(QString))); + connect(m_markerList, SIGNAL(centerOnMarker(int)), l, SLOT(centerOnMarker(int))); + connect(m_markerList, SIGNAL(removeMarker(int)), l, SLOT(removeMarker(int))); + connect(m_markerList, SIGNAL(markerRenamed(int, QString)), l, SLOT(renameMarker(int, QString))); + l->load(QDir::homePath()+"/Maps/marker.list"); + m_map->addLayer(Marker, l); + connect(m_map, SIGNAL(showMarkerList()), this, SLOT(showList())); - connect(m_map, SIGNAL(markerAdded(QString)), this, SLOT(markerAdded(QString))); connect(m_map, SIGNAL(downloadArea(int, QRectF)), this, SLOT(downloadArea(int, QRectF))); m_stack->insertWidget(0, m_map); connect(m_markerList, SIGNAL(back()), this, SLOT(showMap())); - connect(m_markerList, SIGNAL(centerOnMarker(int)), this, SLOT(centerOnMarker(int))); - connect(m_markerList, SIGNAL(removeMarker(int)), this, SLOT(removeMarker(int))); - connect(m_markerList, SIGNAL(markerRenamed(int, QString)), this, SLOT(markerRenamed(int, QString))); + connect(m_markerList, SIGNAL(centerOnMarker(int)), this, SLOT(showMap())); m_stack->insertWidget(1, m_markerList); connect(m_dlWidget, SIGNAL(back()), this, SLOT(showMap())); @@ -72,22 +103,6 @@ void MainWidget::showMap() m_stack->setCurrentIndex(0); } -void MainWidget::centerOnMarker(int row) -{ - m_map->centerOnMarker(row); - m_stack->setCurrentIndex(0); -} - -void MainWidget::removeMarker(int row) -{ - m_map->removeMarker(row); -} - -void MainWidget::markerRenamed(int index, const QString &name) -{ - m_map->renameMarker(index, name); -} - void MainWidget::downloadArea(int level, const QRectF &rect) { m_dlWidget->setStartLevel(level); diff --git a/mainwidget.h b/mainwidget.h index 32067ba..a1cf8e2 100644 --- a/mainwidget.h +++ b/mainwidget.h @@ -39,9 +39,6 @@ private slots: void showList(); void markerAdded(const QString &name); void showMap(); - void centerOnMarker(int row); - void removeMarker(int row); - void markerRenamed(int index, const QString &name); void downloadArea(int level, const QRectF &rect); private: diff --git a/mapwidget.cpp b/mapwidget.cpp index c0de5b6..0bc53a4 100644 --- a/mapwidget.cpp +++ b/mapwidget.cpp @@ -19,9 +19,10 @@ #include "mapwidget.h" +#include "projection.h" + #include -#include #include #include #include @@ -36,12 +37,11 @@ #include #include #include -#include MapWidget::MapWidget(QWidget *parent) : QWidget(parent), m_usage(false), - m_infos(true), + m_ui(true), m_zoomable(false), m_baseName(), m_xPadding(0), @@ -69,12 +69,7 @@ MapWidget::MapWidget(QWidget *parent) m_manager(new QNetworkAccessManager(this)), m_networkMode(false), m_copyright(), - m_markerPos(), - m_markerName(), - m_drawMarker(true), - m_track(), - m_trackOnScreen(), - m_trackOffset() + m_layer() { for (int x = 0; x < 100; ++x) { for (int y = 0; y < 100; ++y) { @@ -115,9 +110,6 @@ MapWidget::MapWidget(QWidget *parent) m_minIndexYList << 0; m_maxIndexYList << (1 << i) - 1; } - if (fileName.endsWith(".gpx")) { - loadGpx(fileName); - } m_baseName = QDir::homePath()+"/Maps/OSM/%z/%x/%y.png"; QTimer::singleShot(100, this, SLOT(loadConfig())); } @@ -139,30 +131,9 @@ MapWidget::~MapWidget() } } -void MapWidget::removeMarker(int index) +void MapWidget::addLayer(Layer l, AbstractLayer *layer) { - if (index >= 0 && m_markerPos.count() > index) { - m_markerPos.removeAt(index); - m_markerName.removeAt(index); - update(); - } -} - -void MapWidget::renameMarker(int index, const QString &name) -{ - if (index >= 0 && m_markerName.count() > index) { - m_markerName.replace(index, name); - } -} - -void MapWidget::centerOnMarker(int index) -{ - if (index >= 0 && m_markerPos.count() > index) { - qreal lon = m_markerPos.at(index).x(); - qreal lat = m_markerPos.at(index).y(); - - centerOnGeoPos(lon, lat); - } + m_layer.insert(l, layer); } void MapWidget::resizeEvent(QResizeEvent *event) @@ -190,7 +161,9 @@ void MapWidget::resizeEvent(QResizeEvent *event) void MapWidget::mouseMoveEvent(QMouseEvent *event) { if (m_isMoving) { - m_trackOffset += (event->pos() - m_startPos) - m_pos; + foreach (AbstractLayer *l, m_layer) { + l->pan((event->pos() - m_startPos) - m_pos); + } m_pos = event->pos() - m_startPos; updatePos(); } @@ -198,19 +171,17 @@ void MapWidget::mouseMoveEvent(QMouseEvent *event) void MapWidget::mousePressEvent(QMouseEvent *event) { - if (QRect(9, 14, 13, 13).contains(event->pos())) { + if (m_ui && QRect(9, 14, 13, 13).contains(event->pos())) { changeZoomLevel(1); - updateTrack(); reloadPixmaps(); updatePos(); m_isMoving = false; - } else if (QRect(9, 214, 13, 13).contains(event->pos())) { + } else if (m_ui && QRect(9, 214, 13, 13).contains(event->pos())) { changeZoomLevel(-1); - updateTrack(); reloadPixmaps(); updatePos(); m_isMoving = false; - } else if (!QRect(5, 10, 20, 220).contains(event->pos())) { + } else if (!m_ui || !QRect(5, 10, 20, 220).contains(event->pos())) { m_startPos = event->pos() - m_pos; m_isMoving = true; } @@ -227,11 +198,9 @@ void MapWidget::wheelEvent(QWheelEvent *event) { if (event->delta() < 0) { changeZoomLevel(-1); - updateTrack(); reloadPixmaps(); } else { changeZoomLevel(1); - updateTrack(); reloadPixmaps(); } updatePos(); @@ -243,6 +212,8 @@ void MapWidget::keyPressEvent(QKeyEvent *event) int width = 10; if (event->modifiers() & Qt::AltModifier) { width = 100; + } else if (event->modifiers() & Qt::ShiftModifier) { + width = 1; } switch (event->key()) { case Qt::Key_Tab: @@ -252,15 +223,13 @@ void MapWidget::keyPressEvent(QKeyEvent *event) } case Qt::Key_M: { - if (event->modifiers() & Qt::AltModifier) { - m_drawMarker = !m_drawMarker; - } else if (event->modifiers() == Qt::NoModifier) { - int n = 0; - if (!m_markerName.isEmpty()) { - n = m_markerName.last().toInt(); + AbstractLayer *l = m_layer.value(Marker); + if (l) { + if (event->modifiers() & Qt::AltModifier) { + l->toggleVisibility(); + } else if (event->modifiers() == Qt::NoModifier) { + l->triggerAction(); } - QString newName = QString::number(n+1); - addMarker(geoPos(), newName); } break; } @@ -296,14 +265,12 @@ void MapWidget::keyPressEvent(QKeyEvent *event) case Qt::Key_O: { changeZoomLevel(-1); - updateTrack(); reloadPixmaps(); break; } case Qt::Key_I: { changeZoomLevel(1); - updateTrack(); reloadPixmaps(); break; } @@ -314,7 +281,23 @@ void MapWidget::keyPressEvent(QKeyEvent *event) } case Qt::Key_U: { - m_infos = !m_infos; + m_ui = !m_ui; + break; + } + case Qt::Key_T: + { + AbstractLayer *l = m_layer.value(Time); + if (l) { + l->toggleVisibility(); + } + break; + } + case Qt::Key_B: + { + AbstractLayer *l = m_layer.value(System); + if (l) { + l->toggleVisibility(); + } break; } case Qt::Key_Q: @@ -331,7 +314,9 @@ void MapWidget::keyPressEvent(QKeyEvent *event) } } m_pos += move; - m_trackOffset += move; + foreach (AbstractLayer *l, m_layer) { + l->pan(move); + } updatePos(); } @@ -339,63 +324,48 @@ void MapWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event) + AbstractLayer *l = 0; + QPainter painter(this); - bool empty = true; for (int x = 0; x < m_cols; ++x) { for (int y = 0; y < m_rows; ++y) { QPixmap *pix = m_pix[x][y]; if (pix) { - empty = false; QRect rect(m_pos+QPoint(m_pixWidth*x, m_pixHeight*y), pix->size()); painter.drawPixmap(rect, *pix); } } } - if (empty) { - painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "No Map Loaded"); + + l = m_layer.value(Tracks); + if (l) { + l->paintLayer(&painter); } - 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); - if (!p1.isNull()) { - painter.drawLine(p1 + m_trackOffset, p2 + m_trackOffset); - p2 = p1; - } - } + + l = m_layer.value(Marker); + if (l) { + l->paintLayer(&painter); } - if (m_drawMarker) { - int i = 0; - painter.setBrush(QBrush(QColor(255, 237, 60))); - QFontMetrics fm(painter.font()); - int h = fm.height() / 2; - foreach (const QPointF &m, m_markerPos) { - QPoint pos = geo2screen(m.x(), m.y()); - int w = fm.width(m_markerName.at(i)) / 2; - QRect rect(pos.x() - w - 2, pos.y() - h - 11, 2*w + 4, 2*h); - QPolygon polygon; - polygon << pos; - polygon << pos + QPoint(-2, -5); - polygon << rect.bottomLeft(); - polygon << rect.topLeft(); - polygon << rect.topRight(); - polygon << rect.bottomRight(); - polygon << pos + QPoint(2, -5); - polygon << pos; - painter.drawPolygon(polygon); - painter.drawText(rect, Qt::AlignCenter, m_markerName.at(i)); - ++i; - } + + l = m_layer.value(Time); + if (l) { + l->paintLayer(&painter); } - if (m_infos) { + + l = m_layer.value(System); + if (l) { + l->paintLayer(&painter); + } + + if (m_ui) { painter.setBrush(QBrush(QColor(255, 255, 255, 210))); if (m_networkMode) { - painter.drawRoundedRect(30, height() - 20, width() - 35, 19, 10, 10); + painter.drawRoundedRect(30, height() - 17, width() - 145, 16, 5, 5); QPointF geo = geoPos(); QString lon = geo.x() > 0 ? QString("E %1").arg(geo.x()) : QString("W %1").arg(-geo.x()); QString lat = geo.y() > 0 ? QString("N %1").arg(geo.y()) : QString("S %1").arg(-geo.y()); - painter.drawText(35, height() - 18, width() - 45, 15, Qt::AlignCenter, lat+" "+lon); + painter.drawText(35, height() - 15, width() - 155, 14, Qt::AlignCenter, lat+" "+lon); } if (m_zoomable) { painter.drawRoundedRect(5, 10, 20, 220, 10, 10); @@ -416,6 +386,7 @@ void MapWidget::paintEvent(QPaintEvent *event) painter.drawLine(midX - 5, midY, midX + 5, midY); painter.drawLine(midX, midY - 5, midX, midY + 5); } + if (m_usage) { painter.setBrush(QBrush(QColor(255, 255, 255, 210))); painter.drawRoundedRect(20, 5, 280, 215, 10, 10); @@ -423,9 +394,8 @@ void MapWidget::paintEvent(QPaintEvent *event) QStringList usage; usage << "Esc: Quit application"; usage << "h: Show/hide this message"; - usage << "Arrows: Move map by 10 pixel"; - usage << "Alt+Arrows: Move map by 100 pixel"; - usage << "c: Move to the center of the map"; + usage << "Arrows: Move the map"; + //usage << "c: Move to the center of the map"; if (m_zoomable) { usage << "i: Zoom in"; usage << "o: Zoom out"; @@ -577,31 +547,6 @@ void MapWidget::reloadPixmaps() } } -void MapWidget::updateTrack() -{ - if (m_track.count() > 1) { - int scale = 1 << m_level; - m_trackOnScreen.clear(); - m_trackOffset = 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); - if (!p.isNull()) { - m_trackOnScreen << raw2screen(p.x(), p.y(), scale) - m_trackOffset; - } else { - m_trackOnScreen << QPoint(); - } - } - } -} - -void MapWidget::addMarker(const QPointF &pos, const QString &name) -{ - m_markerPos << pos; - m_markerName << name; - emit markerAdded(name); -} - QString MapWidget::filename(int x, int y) { QString result; @@ -696,77 +641,6 @@ void MapWidget::loadMapFile(const QString &filename) } } -void MapWidget::loadGpx(const QString &filename) -{ - QFile file(filename); - if (file.open(QIODevice::ReadOnly)) { - QXmlStreamReader xml(&file); - - QPolygonF points; - QList elev; - QList time; - - QString tag, tag2; - QString name; - QPointF pos; - while (!xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement()) { - if (xml.name() == "trkpt") { - tag = "trkpt"; - float lat = xml.attributes().value("lat").toString().toFloat(); - float lon = xml.attributes().value("lon").toString().toFloat(); - - points << QPointF(lon2rawx(lon), lat2rawy(lat)); - } else if (xml.name() == "ele") { - tag2 = "ele"; - } else if (xml.name() == "time") { - tag2 = "time"; - } else if (xml.name() == "wpt") { - tag = "wpt"; - float lat = xml.attributes().value("lat").toString().toFloat(); - float lon = xml.attributes().value("lon").toString().toFloat(); - - pos = QPointF(lon, lat); - } else if (xml.name() == "name") { - tag2 = "name"; - } else if (xml.name() == "trk" || - xml.name() == "trkseg") { - } else { - tag2.clear(); - } - } else if (xml.isEndElement()) { - if (xml.name() == "trkseg") { - if (!points.isEmpty()) { - m_track << points; - m_track << QPointF(); - } - points.clear(); - elev.clear(); - time.clear(); - } else if (xml.name() == "wpt") { - //addMarker(pos, name); - name.clear(); - } - } else if (xml.isCharacters() && !xml.isWhitespace()) { - if (tag == "trkpt") { - if (tag2 == "ele") { - elev << xml.text().toString().toFloat(); - } else if (tag2 == "time") { - QDateTime dt = QDateTime::fromString(xml.text().toString(), Qt::ISODate); - time << dt.toTime_t(); - } - } else if (tag == "wpt") { - if (tag2 == "name") { - name = xml.text().toString(); - } - } - } - } - updateTrack(); - } -} - void MapWidget::loadConfig() { QSettings set(QDir::homePath()+"/Maps/nanomap.conf", QSettings::NativeFormat); @@ -778,15 +652,6 @@ void MapWidget::loadConfig() m_usage = set.value("usage", true).toBool(); changeZoomLevel(level - m_level); centerOnGeoPos(lon, lat); - updateTrack(); - set.endGroup(); - - set.beginGroup("marker"); - QStringList m = set.childKeys(); - foreach (const QString &marker, m) { - QPointF pos = set.value(marker).toPointF(); - addMarker(pos, marker); - } set.endGroup(); } @@ -801,13 +666,6 @@ void MapWidget::saveConfig() set.setValue("level", m_level); set.setValue("usage", m_usage); set.endGroup(); - - set.beginGroup("marker"); - set.remove(""); - for (int i = 0; i < m_markerPos.count(); ++i) { - set.setValue(m_markerName.at(i), m_markerPos.at(i)); - } - set.endGroup(); } void MapWidget::downloadTile(int x, int y, int level) @@ -844,22 +702,35 @@ void MapWidget::changeZoomLevel(int diff) m_indexY = (int) floor(y); m_pos.setX(((m_indexX-x) * m_pixWidth) + w); m_pos.setY(((m_indexY-y) * m_pixHeight) + h); + + foreach (AbstractLayer *l, m_layer) { + l->zoom(m_level); + } } void MapWidget::centerOnGeoPos(qreal lon, qreal lat) { + QPoint oldPos = QPoint(m_pixWidth * m_indexX, m_pixHeight * m_indexY) - m_pos; + qreal w = width() / 2.0; qreal h = height() / 2.0; - qreal x = lon2tilex(lon, m_level); - qreal y = lat2tiley(lat, m_level); + qreal x = Projection::lon2tilex(lon, m_level); + qreal y = Projection::lat2tiley(lat, m_level); m_indexX = (int) floor(x); m_indexY = (int) floor(y); m_pos.setX(((m_indexX-x) * m_pixWidth) + w); m_pos.setY(((m_indexY-y) * m_pixHeight) + h); + QPoint newPos = QPoint(m_pixWidth * m_indexX, m_pixHeight * m_indexY) - m_pos; + reloadPixmaps(); + + foreach (AbstractLayer *l, m_layer) { + l->pan(oldPos - newPos); + } + updatePos(); } @@ -867,13 +738,13 @@ QRectF MapWidget::geoRect() const { qreal partX = (-m_pos.x()) / 256.0; qreal partY = (height() - m_pos.y()) / 256.0; - qreal minLon = tilex2lon(m_indexX + partX, m_level); - qreal minLat = tiley2lat(m_indexY + partY, m_level); + qreal minLon = Projection::tilex2lon(m_indexX + partX, m_level); + qreal minLat = Projection::tiley2lat(m_indexY + partY, m_level); partX = (width() - m_pos.x()) / 256.0; partY = (-m_pos.y()) / 256.0; - qreal maxLon = tilex2lon(m_indexX + partX, m_level); - qreal maxLat = tiley2lat(m_indexY + partY, m_level); + qreal maxLon = Projection::tilex2lon(m_indexX + partX, m_level); + qreal maxLat = Projection::tiley2lat(m_indexY + partY, m_level); return QRectF(QPointF(minLon, minLat), QPointF(maxLon, maxLat)); } @@ -884,16 +755,16 @@ QPointF MapWidget::geoPos() const qreal h = height() / 2.0; qreal partX = (w - m_pos.x()) / 256.0; qreal partY = (h - m_pos.y()) / 256.0; - qreal lon = tilex2lon(m_indexX + partX, m_level); - qreal lat = tiley2lat(m_indexY + partY, m_level); + qreal lon = Projection::tilex2lon(m_indexX + partX, m_level); + qreal lat = Projection::tiley2lat(m_indexY + partY, m_level); return QPointF(lon, lat); } QPoint MapWidget::geo2screen(qreal lon, qreal lat) const { - qreal tx = lon2tilex(lon, m_level); - qreal ty = lat2tiley(lat, m_level); + qreal tx = Projection::lon2tilex(lon, m_level); + qreal ty = Projection::lat2tiley(lat, m_level); int x = (tx * m_pixWidth) - ((m_indexX * m_pixWidth) - m_pos.x()); int y = (ty * m_pixHeight) - ((m_indexY * m_pixHeight) - m_pos.y()); @@ -912,34 +783,3 @@ QPoint MapWidget::raw2screen(qreal x, qreal y, int scale) const return QPoint(sx, sy); } -qreal MapWidget::lon2rawx(qreal lon) const -{ - return (lon + 180.0) / 360.0; -} - -qreal MapWidget::lat2rawy(qreal lat) const -{ - return (1.0 - log(tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0; -} - -qreal MapWidget::lon2tilex(qreal lon, int z) const -{ - return (lon + 180.0) / 360.0 * (1 << z); -} - -qreal MapWidget::lat2tiley(qreal lat, int z) const -{ - return (1.0 - log(tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * (1 << z); -} - -qreal MapWidget::tilex2lon(qreal x, int z) const -{ - return x / (1 << z) * 360.0 - 180; -} - -qreal MapWidget::tiley2lat(qreal y, int z) const -{ - qreal n = M_PI - 2.0 * M_PI * y / (1 << z); - return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); -} - diff --git a/mapwidget.h b/mapwidget.h index be63f95..55beef9 100644 --- a/mapwidget.h +++ b/mapwidget.h @@ -20,8 +20,11 @@ #ifndef MAPWIDGET_H #define MAPWIDGET_H -#include +#include "abstractlayer.h" + +#include #include +#include #include class MapWidget : public QWidget @@ -31,14 +34,17 @@ public: MapWidget(QWidget *parent = 0); ~MapWidget(); - void removeMarker(int index); - void renameMarker(int index, const QString &name); + void addLayer(Layer l, AbstractLayer *layer); + + QRectF geoRect() const; + QPointF geoPos() const; + QPoint geo2screen(qreal lon, qreal lat) const; + QPoint raw2screen(qreal x, qreal y, int scale) const; public slots: - void centerOnMarker(int index); + void centerOnGeoPos(qreal lon, qreal lat); signals: - void markerAdded(const QString &name); void showMarkerList(); void downloadArea(int level, const QRectF &rect); @@ -58,28 +64,14 @@ private slots: private: void updatePos(); void reloadPixmaps(); - void updateTrack(); - void addMarker(const QPointF &pos, const QString &name); QString filename(int x, int y); QPixmap *loadPixmap(int x, int y); void loadMapFile(const QString &filename); - void loadGpx(const QString &filename); void saveConfig(); void downloadTile(int x, int y, int level); void changeZoomLevel(int diff); - void centerOnGeoPos(qreal lon, qreal lat); - QRectF geoRect() const; - QPointF geoPos() const; - QPoint geo2screen(qreal lon, qreal lat) const; - QPoint raw2screen(qreal x, qreal y, int scale) const; - qreal lon2rawx(qreal lon) const; - qreal lat2rawy(qreal lat) const; - qreal lon2tilex(qreal lon, int z) const; - qreal lat2tiley(qreal lat, int z) const; - qreal tilex2lon(qreal x, int z) const; - qreal tiley2lat(qreal y, int z) const; - bool m_usage, m_infos, m_zoomable; + bool m_usage, m_ui, m_zoomable; QString m_baseName; int m_xPadding, m_yPadding; QPoint m_pos, m_startPos; @@ -97,12 +89,7 @@ private: QNetworkAccessManager *m_manager; bool m_networkMode; QString m_copyright; - QList m_markerPos; - QStringList m_markerName; - bool m_drawMarker; - QPolygonF m_track; - QList m_trackOnScreen; - QPoint m_trackOffset; + QHash m_layer; }; diff --git a/markerlayer.cpp b/markerlayer.cpp new file mode 100644 index 0000000..cea7e04 --- /dev/null +++ b/markerlayer.cpp @@ -0,0 +1,126 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "markerlayer.h" + +#include "mapwidget.h" + +#include + +MarkerLayer::MarkerLayer(MapWidget *map) : + AbstractLayer(map), + m_markerPos(), + m_markerName(), + m_filename() +{ +} + +MarkerLayer::~MarkerLayer() +{ + QSettings set(m_filename, QSettings::NativeFormat); + + set.beginGroup("marker"); + set.remove(""); + for (int i = 0; i < m_markerPos.count(); ++i) { + set.setValue(m_markerName.at(i), m_markerPos.at(i)); + } + set.endGroup(); +} + +void MarkerLayer::load(const QString &filename) +{ + m_filename = filename; + + QSettings set(filename, QSettings::NativeFormat); + + set.beginGroup("marker"); + QStringList m = set.childKeys(); + foreach (const QString &marker, m) { + QPointF pos = set.value(marker).toPointF(); + m_markerPos << pos; + m_markerName << marker; + emit markerAdded(marker); + } + set.endGroup(); +} + +void MarkerLayer::triggerAction() +{ + int n = 0; + if (!m_markerName.isEmpty()) { + n = m_markerName.last().toInt(); + } + QString newName = QString::number(n+1); + + m_markerPos << map()->geoPos(); + m_markerName << newName; + emit markerAdded(newName); +} + +void MarkerLayer::paint(QPainter *painter) +{ + int i = 0; + painter->setBrush(QBrush(QColor(255, 237, 60))); + QFontMetrics fm(painter->font()); + int h = fm.height() / 2; + foreach (const QPointF &m, m_markerPos) { + QPoint pos = map()->geo2screen(m.x(), m.y()); + int w = fm.width(m_markerName.at(i)) / 2; + QRect rect(pos.x() - w - 2, pos.y() - h - 11, 2*w + 4, 2*h); + QPolygon polygon; + polygon << pos; + polygon << pos + QPoint(-2, -5); + polygon << rect.bottomLeft(); + polygon << rect.topLeft(); + polygon << rect.topRight(); + polygon << rect.bottomRight(); + polygon << pos + QPoint(2, -5); + polygon << pos; + painter->drawPolygon(polygon); + painter->drawText(rect, Qt::AlignCenter, m_markerName.at(i)); + ++i; + } +} + +void MarkerLayer::removeMarker(int index) +{ + if (index >= 0 && m_markerPos.count() > index) { + m_markerPos.removeAt(index); + m_markerName.removeAt(index); + map()->update(); + } +} + +void MarkerLayer::renameMarker(int index, const QString &name) +{ + if (index >= 0 && m_markerName.count() > index) { + m_markerName.replace(index, name); + } +} + +void MarkerLayer::centerOnMarker(int index) +{ + if (index >= 0 && m_markerPos.count() > index) { + qreal lon = m_markerPos.at(index).x(); + qreal lat = m_markerPos.at(index).y(); + + map()->centerOnGeoPos(lon, lat); + } +} + diff --git a/markerlayer.h b/markerlayer.h new file mode 100644 index 0000000..3e64224 --- /dev/null +++ b/markerlayer.h @@ -0,0 +1,55 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef MARKER_LAYER_H +#define MARKER_LAYER_H + +#include "abstractlayer.h" + +#include + +class MarkerLayer : public AbstractLayer +{ + Q_OBJECT +public: + MarkerLayer(MapWidget *map); + ~MarkerLayer(); + + virtual void load(const QString &filename); + virtual void triggerAction(); + +protected: + virtual void paint(QPainter *painter); + +public slots: + void removeMarker(int index); + void renameMarker(int index, const QString &name); + void centerOnMarker(int index); + +signals: + void markerAdded(const QString &name); + +private: + QList m_markerPos; + QStringList m_markerName; + QString m_filename; + +}; + +#endif // MARKER_LAYER_H diff --git a/markerlist.h b/markerlist.h index 83b0e28..cc819d5 100644 --- a/markerlist.h +++ b/markerlist.h @@ -30,6 +30,7 @@ public: MarkerList(QWidget *parent = 0); ~MarkerList(); +public slots: void addMarker(const QString &name); signals: diff --git a/nanomap.pro b/nanomap.pro index 9b2e553..e5f6efa 100644 --- a/nanomap.pro +++ b/nanomap.pro @@ -5,12 +5,24 @@ QT += network SOURCES += main.cpp \ mainwidget.cpp \ + projection.cpp \ + abstractlayer.cpp \ + markerlayer.cpp \ + gpxlayer.cpp \ + timelayer.cpp \ + batterylayer.cpp \ mapwidget.cpp \ markerlist.cpp \ downloadwidget.cpp \ gpsclient.cpp HEADERS += mainwidget.h \ + projection.h \ + abstractlayer.h \ + markerlayer.h \ + gpxlayer.h \ + timelayer.h \ + batterylayer.h \ mapwidget.h \ markerlist.h \ downloadwidget.h \ diff --git a/projection.cpp b/projection.cpp new file mode 100644 index 0000000..c982c35 --- /dev/null +++ b/projection.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "projection.h" + +#include + +qreal Projection::lon2rawx(qreal lon) +{ + return (lon + 180.0) / 360.0; +} + +qreal Projection::lat2rawy(qreal lat) +{ + return (1.0 - log(tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0; +} + +qreal Projection::lon2tilex(qreal lon, int z) +{ + return (lon + 180.0) / 360.0 * (1 << z); +} + +qreal Projection::lat2tiley(qreal lat, int z) +{ + return (1.0 - log(tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * (1 << z); +} + +qreal Projection::tilex2lon(qreal x, int z) +{ + return x / (1 << z) * 360.0 - 180; +} + +qreal Projection::tiley2lat(qreal y, int z) +{ + qreal n = M_PI - 2.0 * M_PI * y / (1 << z); + return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); +} + diff --git a/projection.h b/projection.h new file mode 100644 index 0000000..79bee69 --- /dev/null +++ b/projection.h @@ -0,0 +1,35 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef PROJECTION_H +#define PROJECTION_H + +#include + +namespace Projection +{ + qreal lon2rawx(qreal lon); + qreal lat2rawy(qreal lat); + qreal lon2tilex(qreal lon, int z); + qreal lat2tiley(qreal lat, int z); + qreal tilex2lon(qreal x, int z); + qreal tiley2lat(qreal y, int z); +}; + +#endif // PROJECTION_H diff --git a/timelayer.cpp b/timelayer.cpp new file mode 100644 index 0000000..20b8112 --- /dev/null +++ b/timelayer.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 "timelayer.h" + +#include "mapwidget.h" + +#include + +TimeLayer::TimeLayer(MapWidget *map) : + AbstractLayer(map), + m_updateTimer(new QTimer(this)) +{ + m_updateTimer->setInterval(60 * 1000); + connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(repaint())); + int time = (60 - QTime::currentTime().second()) * 1000; + QTimer::singleShot(time, this, SLOT(repaint())); + QTimer::singleShot(time, m_updateTimer, SLOT(start())); +} + +void TimeLayer::paint(QPainter *painter) +{ + int w = map()->width(); + + painter->setBrush(QBrush(QColor(255, 255, 255, 210))); + painter->drawRoundedRect(w - 82, 1, 80, 16, 5, 5); + painter->drawText(w - 77, 3, 70, 14, Qt::AlignCenter, + QTime::currentTime().toString("h:mm")); +} + +void TimeLayer::repaint() +{ + if (isVisible()) { + map()->update(); + } +} + diff --git a/timelayer.h b/timelayer.h new file mode 100644 index 0000000..b9fbf9c --- /dev/null +++ b/timelayer.h @@ -0,0 +1,45 @@ +/* + * Copyright 2010 Niels Kummerfeldt + * + * 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 + */ + +#ifndef TIME_LAYER_H +#define TIME_LAYER_H + +#include "abstractlayer.h" + +#include +#include + +class TimeLayer : public AbstractLayer +{ + Q_OBJECT +public: + TimeLayer(MapWidget *map); + +protected: + virtual void paint(QPainter *painter); + +private slots: + void repaint(); + +private: + QTimer *m_updateTimer; + +}; + +#endif // TIME_LAYER_H