mirror of
git://projects.qi-hardware.com/nanomap.git
synced 2024-11-22 01:16:14 +02:00
add a widget that downloads the tiles of higher zoom levels of the
currently visible area
This commit is contained in:
parent
f236bb8248
commit
38c7c10bcf
196
downloadwidget.cpp
Normal file
196
downloadwidget.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 "downloadwidget.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
|
||||
DownloadWidget::DownloadWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_manager(new QNetworkAccessManager(this)),
|
||||
m_startLevel(0),
|
||||
m_dlRect(),
|
||||
m_dlList(),
|
||||
m_up(new QLabel("N 0", this)),
|
||||
m_left(new QLabel("E 0", this)),
|
||||
m_right(new QLabel("E 0", this)),
|
||||
m_bottom(new QLabel("N 0", this)),
|
||||
m_levelSpinBox(new QSpinBox(this)),
|
||||
m_dlProgress(new QProgressBar(this))
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setRowStretch(1, 1);
|
||||
|
||||
m_up->setAlignment(Qt::AlignHCenter);
|
||||
m_left->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
m_right->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
m_bottom->setAlignment(Qt::AlignHCenter);
|
||||
layout->addWidget(m_up, 0, 0, 1, 4);
|
||||
layout->addWidget(m_left, 1, 0);
|
||||
layout->addWidget(m_right, 1, 3);
|
||||
layout->addWidget(m_bottom, 2, 0, 1, 4);
|
||||
|
||||
QLabel *label = new QLabel(this);
|
||||
label->setFrameShape(QLabel::Box);
|
||||
layout->addWidget(label, 1, 1, 1, 2);
|
||||
|
||||
label = new QLabel("Download up to level", this);
|
||||
layout->addWidget(label, 3, 0, 1, 2);
|
||||
|
||||
m_levelSpinBox->setRange(0, 18);
|
||||
layout->addWidget(m_levelSpinBox, 3, 2, 1, 2);
|
||||
|
||||
m_dlProgress->setFormat("%v / %m");
|
||||
layout->addWidget(m_dlProgress, 4, 0, 1, 4);
|
||||
|
||||
QPushButton *start = new QPushButton("&Start", this);
|
||||
connect(start, SIGNAL(clicked()), this, SLOT(startDownload()));
|
||||
layout->addWidget(start, 5, 0, 1, 2);
|
||||
|
||||
QPushButton *back = new QPushButton("&Back", this);
|
||||
connect(back, SIGNAL(clicked()), this, SIGNAL(back()));
|
||||
layout->addWidget(back, 5, 2, 1, 2);
|
||||
|
||||
connect(m_manager, SIGNAL(finished(QNetworkReply*)),
|
||||
this, SLOT(replyFinished(QNetworkReply*)));
|
||||
|
||||
resize(320, 240);
|
||||
}
|
||||
|
||||
DownloadWidget::~DownloadWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void DownloadWidget::setStartLevel(int level)
|
||||
{
|
||||
if (level >= 17) {
|
||||
level = 17;
|
||||
}
|
||||
m_startLevel = level + 1;
|
||||
m_levelSpinBox->setMinimum(level + 1);
|
||||
m_levelSpinBox->setValue(level + 1);
|
||||
}
|
||||
|
||||
void DownloadWidget::setDownloadRect(const QRectF &rect)
|
||||
{
|
||||
m_dlRect = rect;
|
||||
m_up->setText(lat2string(rect.bottom()));
|
||||
m_left->setText(lon2string(rect.left()));
|
||||
m_right->setText(lon2string(rect.right()));
|
||||
m_bottom->setText(lat2string(rect.top()));
|
||||
}
|
||||
|
||||
void DownloadWidget::startDownload()
|
||||
{
|
||||
m_dlProgress->setValue(0);
|
||||
for (int level = m_startLevel; level <= m_levelSpinBox->value(); ++level) {
|
||||
int max = pow(2, level) - 1;
|
||||
int minX = qBound(0, lon2tilex(m_dlRect.left(), level), max);
|
||||
int minY = qBound(0, lat2tiley(m_dlRect.bottom(), level), max);
|
||||
int maxX = qBound(0, lon2tilex(m_dlRect.right(), level), max);
|
||||
int maxY = qBound(0, lat2tiley(m_dlRect.top(), level), max);
|
||||
for (int x = minX; x <= maxX; ++x) {
|
||||
for (int y = minY; y <= maxY; ++y) {
|
||||
m_dlList << QString("http://tile.openstreetmap.org/%1/%2/%3.png").arg(level).arg(x).arg(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_dlList.isEmpty()) {
|
||||
m_dlProgress->setRange(0, m_dlList.count());
|
||||
QUrl url(m_dlList.takeFirst());
|
||||
m_manager->get(QNetworkRequest(url));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadWidget::replyFinished(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QString path = reply->url().path();
|
||||
int level = path.section('/', 1, 1).toInt();
|
||||
int x = path.section('/', 2, 2).toInt();
|
||||
|
||||
QDir base(QDir::homePath()+"/Maps/OSM");
|
||||
base.mkpath(QString("%1/%2").arg(level).arg(x));
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
if (!data.isEmpty()) {
|
||||
QFile file(QDir::homePath()+"/Maps/OSM"+path);
|
||||
if (file.open(QFile::WriteOnly)) {
|
||||
file.write(data);
|
||||
}
|
||||
}
|
||||
if (!m_dlList.isEmpty()) {
|
||||
QUrl url(m_dlList.takeFirst());
|
||||
m_manager->get(QNetworkRequest(url));
|
||||
}
|
||||
int n = m_dlProgress->value();
|
||||
m_dlProgress->setValue(n+1);
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
QString DownloadWidget::lon2string(qreal lon)
|
||||
{
|
||||
QString result;
|
||||
|
||||
if (lon < 0) {
|
||||
result = "W ";
|
||||
lon *= -1;
|
||||
} else {
|
||||
result = "E ";
|
||||
}
|
||||
result.append(QString::number(lon));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DownloadWidget::lat2string(qreal lat)
|
||||
{
|
||||
QString result;
|
||||
|
||||
if (lat < 0) {
|
||||
result = "S ";
|
||||
lat *= -1;
|
||||
} else {
|
||||
result = "N ";
|
||||
}
|
||||
result.append(QString::number(lat));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int DownloadWidget::lon2tilex(qreal lon, int z)
|
||||
{
|
||||
return (int)(floor((lon + 180.0) / 360.0 * pow(2.0, z)));
|
||||
}
|
||||
|
||||
int DownloadWidget::lat2tiley(qreal lat, int z)
|
||||
{
|
||||
return (int)(floor((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)));
|
||||
}
|
||||
|
62
downloadwidget.h
Normal file
62
downloadwidget.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOADWIDGET_H
|
||||
#define DOWNLOADWIDGET_H
|
||||
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QProgressBar>
|
||||
#include <QtGui/QSpinBox>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
class DownloadWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DownloadWidget(QWidget *parent = 0);
|
||||
~DownloadWidget();
|
||||
|
||||
void setStartLevel(int level);
|
||||
void setDownloadRect(const QRectF &rect);
|
||||
|
||||
signals:
|
||||
void back();
|
||||
|
||||
private slots:
|
||||
void startDownload();
|
||||
void replyFinished(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
QString lon2string(qreal lon);
|
||||
QString lat2string(qreal lat);
|
||||
int lon2tilex(qreal lon, int z);
|
||||
int lat2tiley(qreal lat, int z);
|
||||
|
||||
QNetworkAccessManager *m_manager;
|
||||
int m_startLevel;
|
||||
QRectF m_dlRect;
|
||||
QStringList m_dlList;
|
||||
QLabel *m_up, *m_left, *m_right, *m_bottom;
|
||||
QSpinBox *m_levelSpinBox;
|
||||
QProgressBar *m_dlProgress;
|
||||
|
||||
};
|
||||
|
||||
#endif // DOWNLOADWIDGET_H
|
3
main.cpp
3
main.cpp
@ -17,9 +17,10 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include "downloadwidget.h"
|
||||
#include "mapwidget.h"
|
||||
#include "markerlist.h"
|
||||
|
||||
@ -28,21 +29,27 @@ MainWidget::MainWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_stack(new QStackedWidget(this)),
|
||||
m_map(new MapWidget(this)),
|
||||
m_markerList(new MarkerList(this))
|
||||
m_markerList(new MarkerList(this)),
|
||||
m_dlWidget(new DownloadWidget(this))
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_stack);
|
||||
|
||||
connect(m_map, SIGNAL(switchView()), this, SLOT(showList()));
|
||||
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)));
|
||||
m_stack->insertWidget(1, m_markerList);
|
||||
|
||||
connect(m_dlWidget, SIGNAL(back()), this, SLOT(showMap()));
|
||||
m_stack->insertWidget(2, m_dlWidget);
|
||||
|
||||
resize(320, 240);
|
||||
}
|
||||
|
||||
@ -81,3 +88,10 @@ 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);
|
||||
m_dlWidget->setDownloadRect(rect);
|
||||
m_stack->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,13 @@
|
||||
#include <QtGui/QStackedWidget>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
class DownloadWidget;
|
||||
class MapWidget;
|
||||
class MarkerList;
|
||||
|
||||
class MainWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWidget(QWidget *parent = 0);
|
||||
~MainWidget();
|
||||
@ -42,11 +42,13 @@ private slots:
|
||||
void centerOnMarker(int row);
|
||||
void removeMarker(int row);
|
||||
void markerRenamed(int index, const QString &name);
|
||||
void downloadArea(int level, const QRectF &rect);
|
||||
|
||||
private:
|
||||
QStackedWidget *m_stack;
|
||||
MapWidget *m_map;
|
||||
MarkerList *m_markerList;
|
||||
DownloadWidget *m_dlWidget;
|
||||
|
||||
};
|
||||
|
||||
|
@ -239,7 +239,7 @@ void MapWidget::keyPressEvent(QKeyEvent *event)
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Tab:
|
||||
{
|
||||
emit switchView();
|
||||
emit showMarkerList();
|
||||
break;
|
||||
}
|
||||
case Qt::Key_M:
|
||||
@ -303,6 +303,11 @@ void MapWidget::keyPressEvent(QKeyEvent *event)
|
||||
reloadPixmaps();
|
||||
break;
|
||||
}
|
||||
case Qt::Key_D:
|
||||
{
|
||||
emit downloadArea(m_level, geoRect());
|
||||
break;
|
||||
}
|
||||
case Qt::Key_U:
|
||||
{
|
||||
m_infos = !m_infos;
|
||||
@ -731,7 +736,22 @@ void MapWidget::centerOnGeoPos(qreal lon, qreal lat)
|
||||
updatePos();
|
||||
}
|
||||
|
||||
QPointF MapWidget::geoPos()
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return QRectF(QPointF(minLon, minLat), QPointF(maxLon, maxLat));
|
||||
}
|
||||
|
||||
QPointF MapWidget::geoPos() const
|
||||
{
|
||||
qreal w = width() / 2.0;
|
||||
qreal h = height() / 2.0;
|
||||
@ -743,7 +763,7 @@ QPointF MapWidget::geoPos()
|
||||
return QPointF(lon, lat);
|
||||
}
|
||||
|
||||
QPoint MapWidget::geo2screen(qreal lon, qreal lat)
|
||||
QPoint MapWidget::geo2screen(qreal lon, qreal lat) const
|
||||
{
|
||||
qreal tx = lon2tilex(lon, m_level);
|
||||
qreal ty = lat2tiley(lat, m_level);
|
||||
@ -754,22 +774,22 @@ QPoint MapWidget::geo2screen(qreal lon, qreal lat)
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
qreal MapWidget::lon2tilex(qreal lon, int z)
|
||||
qreal MapWidget::lon2tilex(qreal lon, int z) const
|
||||
{
|
||||
return (lon + 180.0) / 360.0 * pow(2.0, z);
|
||||
}
|
||||
|
||||
qreal MapWidget::lat2tiley(qreal lat, int 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 * pow(2.0, z);
|
||||
}
|
||||
|
||||
qreal MapWidget::tilex2lon(qreal x, int z)
|
||||
qreal MapWidget::tilex2lon(qreal x, int z) const
|
||||
{
|
||||
return x / pow(2.0, z) * 360.0 - 180;
|
||||
}
|
||||
|
||||
qreal MapWidget::tiley2lat(qreal y, int z)
|
||||
qreal MapWidget::tiley2lat(qreal y, int z) const
|
||||
{
|
||||
qreal n = M_PI - 2.0 * M_PI * y / pow(2.0, z);
|
||||
return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
|
||||
|
17
mapwidget.h
17
mapwidget.h
@ -27,7 +27,6 @@
|
||||
class MapWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MapWidget(QWidget *parent = 0);
|
||||
~MapWidget();
|
||||
@ -40,7 +39,8 @@ public slots:
|
||||
|
||||
signals:
|
||||
void markerAdded(const QString &name);
|
||||
void switchView();
|
||||
void showMarkerList();
|
||||
void downloadArea(int level, const QRectF &rect);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
@ -65,12 +65,13 @@ private:
|
||||
void downloadTile(int x, int y, int level);
|
||||
void changeZoomLevel(int diff);
|
||||
void centerOnGeoPos(qreal lon, qreal lat);
|
||||
QPointF geoPos();
|
||||
QPoint geo2screen(qreal lon, 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);
|
||||
QRectF geoRect() const;
|
||||
QPointF geoPos() const;
|
||||
QPoint geo2screen(qreal lon, 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;
|
||||
QString m_baseName;
|
||||
|
@ -26,7 +26,6 @@
|
||||
class MarkerList : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MarkerList(QWidget *parent = 0);
|
||||
~MarkerList();
|
||||
@ -51,4 +50,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWIDGET_H
|
||||
#endif // MARKERLIST_H
|
||||
|
@ -7,9 +7,11 @@ SOURCES += main.cpp \
|
||||
mainwidget.cpp \
|
||||
mapwidget.cpp \
|
||||
markerlist.cpp \
|
||||
downloadwidget.cpp \
|
||||
gpsclient.cpp
|
||||
|
||||
HEADERS += mainwidget.h \
|
||||
mapwidget.h \
|
||||
markerlist.h \
|
||||
downloadwidget.h \
|
||||
gpsclient.h
|
||||
|
Loading…
Reference in New Issue
Block a user