mirror of
git://projects.qi-hardware.com/nanomap.git
synced 2024-12-18 15:25:20 +02:00
load tracks from .gpx files and show them in the map
This commit is contained in:
parent
a76267346b
commit
95c361f90b
178
mapwidget.cpp
178
mapwidget.cpp
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
@ -35,6 +36,7 @@
|
|||||||
#include <QtGui/QPaintEvent>
|
#include <QtGui/QPaintEvent>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
#include <QtNetwork/QNetworkRequest>
|
#include <QtNetwork/QNetworkRequest>
|
||||||
|
#include <QtXml/QXmlStreamReader>
|
||||||
|
|
||||||
MapWidget::MapWidget(QWidget *parent)
|
MapWidget::MapWidget(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
@ -69,15 +71,22 @@ MapWidget::MapWidget(QWidget *parent)
|
|||||||
m_copyright(),
|
m_copyright(),
|
||||||
m_markerPos(),
|
m_markerPos(),
|
||||||
m_markerName(),
|
m_markerName(),
|
||||||
m_drawMarker(true)
|
m_drawMarker(true),
|
||||||
|
m_track(),
|
||||||
|
m_trackOnScreen(),
|
||||||
|
m_trackOffset()
|
||||||
{
|
{
|
||||||
for (int x = 0; x < 100; ++x) {
|
for (int x = 0; x < 100; ++x) {
|
||||||
for (int y = 0; y < 100; ++y) {
|
for (int y = 0; y < 100; ++y) {
|
||||||
m_pix[x][y] = 0;
|
m_pix[x][y] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QString fileName;
|
||||||
if (QApplication::arguments().count() > 1) {
|
if (QApplication::arguments().count() > 1) {
|
||||||
loadMapFile(QApplication::arguments().at(1));
|
fileName = QApplication::arguments().at(1);
|
||||||
|
}
|
||||||
|
if (fileName.endsWith(".map")) {
|
||||||
|
loadMapFile(fileName);
|
||||||
|
|
||||||
m_zoomable = m_zoomLevel.count() > 1 &&
|
m_zoomable = m_zoomLevel.count() > 1 &&
|
||||||
m_zoomLevel.count() == m_minIndexXList.count() &&
|
m_zoomLevel.count() == m_minIndexXList.count() &&
|
||||||
@ -88,18 +97,6 @@ MapWidget::MapWidget(QWidget *parent)
|
|||||||
m_indexX = (m_minIndexX + m_maxIndexX) / 2;
|
m_indexX = (m_minIndexX + m_maxIndexX) / 2;
|
||||||
m_indexY = (m_minIndexY + m_maxIndexY) / 2;
|
m_indexY = (m_minIndexY + m_maxIndexY) / 2;
|
||||||
|
|
||||||
if (QApplication::arguments().count() > 3) {
|
|
||||||
bool ok;
|
|
||||||
int x = QApplication::arguments().at(2).toInt(&ok);
|
|
||||||
if (ok) {
|
|
||||||
m_indexX = x;
|
|
||||||
}
|
|
||||||
int y = QApplication::arguments().at(3).toInt(&ok);
|
|
||||||
if (ok) {
|
|
||||||
m_indexY = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cols = ceil(320.0 / (qreal) m_pixWidth) + 1;
|
m_cols = ceil(320.0 / (qreal) m_pixWidth) + 1;
|
||||||
m_rows = ceil(240.0 / (qreal) m_pixHeight) + 1;
|
m_rows = ceil(240.0 / (qreal) m_pixHeight) + 1;
|
||||||
|
|
||||||
@ -114,9 +111,12 @@ MapWidget::MapWidget(QWidget *parent)
|
|||||||
for (int i = 0; i < 19; ++i) {
|
for (int i = 0; i < 19; ++i) {
|
||||||
m_zoomLevel << QString::number(i);
|
m_zoomLevel << QString::number(i);
|
||||||
m_minIndexXList << 0;
|
m_minIndexXList << 0;
|
||||||
m_maxIndexXList << pow(2, i) - 1;
|
m_maxIndexXList << (1 << i) - 1;
|
||||||
m_minIndexYList << 0;
|
m_minIndexYList << 0;
|
||||||
m_maxIndexYList << pow(2, i) - 1;
|
m_maxIndexYList << (1 << i) - 1;
|
||||||
|
}
|
||||||
|
if (fileName.endsWith(".gpx")) {
|
||||||
|
loadGpx(fileName);
|
||||||
}
|
}
|
||||||
m_baseName = QDir::homePath()+"/Maps/OSM/%z/%x/%y.png";
|
m_baseName = QDir::homePath()+"/Maps/OSM/%z/%x/%y.png";
|
||||||
QTimer::singleShot(100, this, SLOT(loadConfig()));
|
QTimer::singleShot(100, this, SLOT(loadConfig()));
|
||||||
@ -134,7 +134,9 @@ MapWidget::MapWidget(QWidget *parent)
|
|||||||
|
|
||||||
MapWidget::~MapWidget()
|
MapWidget::~MapWidget()
|
||||||
{
|
{
|
||||||
|
if (m_networkMode) {
|
||||||
saveConfig();
|
saveConfig();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::removeMarker(int index)
|
void MapWidget::removeMarker(int index)
|
||||||
@ -188,6 +190,7 @@ void MapWidget::resizeEvent(QResizeEvent *event)
|
|||||||
void MapWidget::mouseMoveEvent(QMouseEvent *event)
|
void MapWidget::mouseMoveEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (m_isMoving) {
|
if (m_isMoving) {
|
||||||
|
m_trackOffset += (event->pos() - m_startPos) - m_pos;
|
||||||
m_pos = event->pos() - m_startPos;
|
m_pos = event->pos() - m_startPos;
|
||||||
updatePos();
|
updatePos();
|
||||||
}
|
}
|
||||||
@ -197,11 +200,13 @@ void MapWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
{
|
{
|
||||||
if (QRect(9, 14, 13, 13).contains(event->pos())) {
|
if (QRect(9, 14, 13, 13).contains(event->pos())) {
|
||||||
changeZoomLevel(1);
|
changeZoomLevel(1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
updatePos();
|
updatePos();
|
||||||
m_isMoving = false;
|
m_isMoving = false;
|
||||||
} else if (QRect(9, 214, 13, 13).contains(event->pos())) {
|
} else if (QRect(9, 214, 13, 13).contains(event->pos())) {
|
||||||
changeZoomLevel(-1);
|
changeZoomLevel(-1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
updatePos();
|
updatePos();
|
||||||
m_isMoving = false;
|
m_isMoving = false;
|
||||||
@ -222,9 +227,11 @@ void MapWidget::wheelEvent(QWheelEvent *event)
|
|||||||
{
|
{
|
||||||
if (event->delta() < 0) {
|
if (event->delta() < 0) {
|
||||||
changeZoomLevel(-1);
|
changeZoomLevel(-1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
} else {
|
} else {
|
||||||
changeZoomLevel(1);
|
changeZoomLevel(1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
}
|
}
|
||||||
updatePos();
|
updatePos();
|
||||||
@ -232,6 +239,7 @@ void MapWidget::wheelEvent(QWheelEvent *event)
|
|||||||
|
|
||||||
void MapWidget::keyPressEvent(QKeyEvent *event)
|
void MapWidget::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
|
QPoint move;
|
||||||
int width = 10;
|
int width = 10;
|
||||||
if (event->modifiers() & Qt::AltModifier) {
|
if (event->modifiers() & Qt::AltModifier) {
|
||||||
width = 100;
|
width = 100;
|
||||||
@ -252,30 +260,28 @@ void MapWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
n = m_markerName.last().toInt();
|
n = m_markerName.last().toInt();
|
||||||
}
|
}
|
||||||
QString newName = QString::number(n+1);
|
QString newName = QString::number(n+1);
|
||||||
m_markerPos << geoPos();
|
addMarker(geoPos(), newName);
|
||||||
m_markerName << newName;
|
|
||||||
emit markerAdded(newName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
{
|
{
|
||||||
m_pos += QPoint(0, width);
|
move = QPoint(0, width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
{
|
{
|
||||||
m_pos += QPoint(0, -width);
|
move = QPoint(0, -width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
{
|
{
|
||||||
m_pos += QPoint(width, 0);
|
move = QPoint(width, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Right:
|
case Qt::Key_Right:
|
||||||
{
|
{
|
||||||
m_pos += QPoint(-width, 0);
|
move = QPoint(-width, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_C:
|
case Qt::Key_C:
|
||||||
@ -290,12 +296,14 @@ void MapWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
case Qt::Key_O:
|
case Qt::Key_O:
|
||||||
{
|
{
|
||||||
changeZoomLevel(-1);
|
changeZoomLevel(-1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_I:
|
case Qt::Key_I:
|
||||||
{
|
{
|
||||||
changeZoomLevel(1);
|
changeZoomLevel(1);
|
||||||
|
updateTrack();
|
||||||
reloadPixmaps();
|
reloadPixmaps();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -322,6 +330,8 @@ void MapWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pos += move;
|
||||||
|
m_trackOffset += move;
|
||||||
updatePos();
|
updatePos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +355,16 @@ void MapWidget::paintEvent(QPaintEvent *event)
|
|||||||
if (empty) {
|
if (empty) {
|
||||||
painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "No Map Loaded");
|
painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "No Map Loaded");
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m_drawMarker) {
|
if (m_drawMarker) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
painter.setBrush(QBrush(QColor(255, 237, 60)));
|
painter.setBrush(QBrush(QColor(255, 237, 60)));
|
||||||
@ -557,6 +577,30 @@ void MapWidget::reloadPixmaps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapWidget::updateTrack()
|
||||||
|
{
|
||||||
|
if (m_track.count() > 1) {
|
||||||
|
m_trackOnScreen.clear();
|
||||||
|
m_trackOffset = geo2screen(m_track.first().x(), m_track.first().y());
|
||||||
|
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 << geo2screen(p.x(), p.y()) - 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 MapWidget::filename(int x, int y)
|
||||||
{
|
{
|
||||||
QString result;
|
QString result;
|
||||||
@ -651,9 +695,81 @@ 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<float> elev;
|
||||||
|
QList<int> 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(lon, 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()
|
void MapWidget::loadConfig()
|
||||||
{
|
{
|
||||||
QSettings set(QDir::homePath()+"/.nanomap.conf", QSettings::NativeFormat);
|
QSettings set(QDir::homePath()+"/.nanomap.conf", QSettings::NativeFormat);
|
||||||
|
|
||||||
set.beginGroup("map");
|
set.beginGroup("map");
|
||||||
qreal lon = set.value("lon", 0).toReal();
|
qreal lon = set.value("lon", 0).toReal();
|
||||||
qreal lat = set.value("lat", 0).toReal();
|
qreal lat = set.value("lat", 0).toReal();
|
||||||
@ -661,14 +777,14 @@ void MapWidget::loadConfig()
|
|||||||
m_usage = set.value("usage", true).toBool();
|
m_usage = set.value("usage", true).toBool();
|
||||||
changeZoomLevel(level - m_level);
|
changeZoomLevel(level - m_level);
|
||||||
centerOnGeoPos(lon, lat);
|
centerOnGeoPos(lon, lat);
|
||||||
|
updateTrack();
|
||||||
set.endGroup();
|
set.endGroup();
|
||||||
|
|
||||||
set.beginGroup("marker");
|
set.beginGroup("marker");
|
||||||
QStringList m = set.childKeys();
|
QStringList m = set.childKeys();
|
||||||
foreach (const QString &marker, m) {
|
foreach (const QString &marker, m) {
|
||||||
QPointF pos = set.value(marker).toPointF();
|
QPointF pos = set.value(marker).toPointF();
|
||||||
m_markerPos << pos;
|
addMarker(pos, marker);
|
||||||
m_markerName << marker;
|
|
||||||
emit markerAdded(marker);
|
|
||||||
}
|
}
|
||||||
set.endGroup();
|
set.endGroup();
|
||||||
}
|
}
|
||||||
@ -676,6 +792,7 @@ void MapWidget::loadConfig()
|
|||||||
void MapWidget::saveConfig()
|
void MapWidget::saveConfig()
|
||||||
{
|
{
|
||||||
QSettings set(QDir::homePath()+"/.nanomap.conf", QSettings::NativeFormat);
|
QSettings set(QDir::homePath()+"/.nanomap.conf", QSettings::NativeFormat);
|
||||||
|
|
||||||
set.beginGroup("map");
|
set.beginGroup("map");
|
||||||
QPointF pos = geoPos();
|
QPointF pos = geoPos();
|
||||||
set.setValue("lon", pos.x());
|
set.setValue("lon", pos.x());
|
||||||
@ -683,6 +800,7 @@ void MapWidget::saveConfig()
|
|||||||
set.setValue("level", m_level);
|
set.setValue("level", m_level);
|
||||||
set.setValue("usage", m_usage);
|
set.setValue("usage", m_usage);
|
||||||
set.endGroup();
|
set.endGroup();
|
||||||
|
|
||||||
set.beginGroup("marker");
|
set.beginGroup("marker");
|
||||||
set.remove("");
|
set.remove("");
|
||||||
for (int i = 0; i < m_markerPos.count(); ++i) {
|
for (int i = 0; i < m_markerPos.count(); ++i) {
|
||||||
@ -784,22 +902,22 @@ QPoint MapWidget::geo2screen(qreal lon, qreal lat) const
|
|||||||
|
|
||||||
qreal MapWidget::lon2tilex(qreal lon, int z) const
|
qreal MapWidget::lon2tilex(qreal lon, int z) const
|
||||||
{
|
{
|
||||||
return (lon + 180.0) / 360.0 * pow(2.0, z);
|
return (lon + 180.0) / 360.0 * (1 << z);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal MapWidget::lat2tiley(qreal lat, int z) const
|
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 * pow(2.0, 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 MapWidget::tilex2lon(qreal x, int z) const
|
qreal MapWidget::tilex2lon(qreal x, int z) const
|
||||||
{
|
{
|
||||||
return x / pow(2.0, z) * 360.0 - 180;
|
return x / (1 << z) * 360.0 - 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal MapWidget::tiley2lat(qreal y, int z) const
|
qreal MapWidget::tiley2lat(qreal y, int z) const
|
||||||
{
|
{
|
||||||
qreal n = M_PI - 2.0 * M_PI * y / pow(2.0, z);
|
qreal n = M_PI - 2.0 * M_PI * y / (1 << z);
|
||||||
return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
|
return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,12 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void updatePos();
|
void updatePos();
|
||||||
void reloadPixmaps();
|
void reloadPixmaps();
|
||||||
|
void updateTrack();
|
||||||
|
void addMarker(const QPointF &pos, const QString &name);
|
||||||
QString filename(int x, int y);
|
QString filename(int x, int y);
|
||||||
QPixmap *loadPixmap(int x, int y);
|
QPixmap *loadPixmap(int x, int y);
|
||||||
void loadMapFile(const QString &filename);
|
void loadMapFile(const QString &filename);
|
||||||
|
void loadGpx(const QString &filename);
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
void downloadTile(int x, int y, int level);
|
void downloadTile(int x, int y, int level);
|
||||||
void changeZoomLevel(int diff);
|
void changeZoomLevel(int diff);
|
||||||
@ -94,6 +97,9 @@ private:
|
|||||||
QList<QPointF> m_markerPos;
|
QList<QPointF> m_markerPos;
|
||||||
QStringList m_markerName;
|
QStringList m_markerName;
|
||||||
bool m_drawMarker;
|
bool m_drawMarker;
|
||||||
|
QPolygonF m_track;
|
||||||
|
QList<QPoint> m_trackOnScreen;
|
||||||
|
QPoint m_trackOffset;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user