1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Added support for limiting the maximal zoom level of online map sources

This commit is contained in:
Martin Tůma 2017-09-09 12:33:43 +02:00
parent ba856d7eb6
commit cc694971be
8 changed files with 95 additions and 57 deletions

View File

@ -1,5 +1,5 @@
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png
4UMaps http://4umaps.eu/$z/$x/$y.png
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png
USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png 16
4UMaps http://4umaps.eu/$z/$x/$y.png 15
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png 19
USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png 15
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y 15

View File

@ -696,10 +696,11 @@ void GUI::dataSources()
"following file:")
+ "</p><p><code>" + USER_MAP_FILE + "</code></p><p>"
+ tr("The file format is one map entry per line, consisting of the map "
"name and tiles URL delimited by a TAB character. The tile X and Y "
"coordinates are replaced with $x and $y in the URL and the zoom "
"level is replaced with $z. An example map file could look like:")
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png"
"name, tiles URL and an optional maximal zoom level delimited by "
"a TAB character. The tile X and Y coordinates are replaced with $x "
"and $y in the URL and the zoom level is replaced with $z. An example "
"map file could look like:")
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png 15"
"<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>"
+ "<h4>" + tr("Offline maps") + "</h4><p>"

View File

@ -1,24 +1,38 @@
#include <QFileInfo>
#include <QDir>
#include "range.h"
#include "atlas.h"
#include "offlinemap.h"
#include "onlinemap.h"
#include "maplist.h"
#define ZOOM_MAX 18
#define ZOOM_MIN 2
Map *MapList::loadListEntry(const QByteArray &line)
{
int max;
QList<QByteArray> list = line.split('\t');
if (list.size() != 2)
if (list.size() < 2)
return 0;
QByteArray ba1 = list[0].trimmed();
QByteArray ba2 = list[1].trimmed();
QByteArray ba1 = list.at(0).trimmed();
QByteArray ba2 = list.at(1).trimmed();
if (ba1.isEmpty() || ba2.isEmpty())
return 0;
if (list.size() == 3) {
bool ok;
max = QString(list.at(2).trimmed()).toInt(&ok);
if (!ok)
return 0;
} else
max = ZOOM_MAX;
return new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()),
QString::fromLatin1(ba2.data(), ba2.size()), this);
QString::fromLatin1(ba2.data(), ba2.size()), Range(ZOOM_MIN, max), this);
}
bool MapList::loadList(const QString &path)

View File

@ -12,8 +12,6 @@
#include "onlinemap.h"
#define ZOOM_MAX 18
#define ZOOM_MIN 3
#define TILE_SIZE 256
static QPoint mercator2tile(const QPointF &m, int z)
@ -36,16 +34,33 @@ static int scale2zoom(qreal scale)
return (int)log2(360.0/(scale * (qreal)TILE_SIZE));
}
static void fillTile(Tile &tile)
{
tile.pixmap() = QPixmap(TILE_SIZE, TILE_SIZE);
tile.pixmap().fill();
}
static bool loadTileFile(Tile &tile, const QString &file)
{
if (!tile.pixmap().load(file)) {
qWarning("%s: error loading tile file\n", qPrintable(file));
return false;
}
return true;
}
Downloader *OnlineMap::downloader;
OnlineMap::OnlineMap(const QString &name, const QString &url, QObject *parent)
: Map(parent)
OnlineMap::OnlineMap(const QString &name, const QString &url,
const Range &zooms, QObject *parent) : Map(parent)
{
_name = name;
_url = url;
_block = false;
_zoom = ZOOM_MAX;
_zooms = zooms;
_zoom = zooms.max();
connect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
@ -115,23 +130,7 @@ void OnlineMap::loadTilesSync(QList<Tile> &list)
}
}
void OnlineMap::fillTile(Tile &tile)
{
tile.pixmap() = QPixmap(TILE_SIZE, TILE_SIZE);
tile.pixmap().fill();
}
bool OnlineMap::loadTileFile(Tile &tile, const QString &file)
{
if (!tile.pixmap().load(file)) {
qWarning("%s: error loading tile file\n", qPrintable(file));
return false;
}
return true;
}
QString OnlineMap::tileUrl(const Tile &tile)
QString OnlineMap::tileUrl(const Tile &tile) const
{
QString url(_url);
@ -142,7 +141,7 @@ QString OnlineMap::tileUrl(const Tile &tile)
return url;
}
QString OnlineMap::tileFile(const Tile &tile)
QString OnlineMap::tileFile(const Tile &tile) const
{
QString file = TILES_DIR + QString("/%1/%2-%3-%4").arg(name())
.arg(tile.zoom()).arg(tile.xy().x()).arg(tile.xy().y());
@ -166,20 +165,26 @@ QRectF OnlineMap::bounds() const
1.0/zoom2scale(_zoom));
}
int OnlineMap::limitZoom(int zoom) const
{
if (zoom < _zooms.min())
return _zooms.min();
if (zoom > _zooms.max())
return _zooms.max();
return zoom;
}
qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
{
if (!br.isValid())
_zoom = ZOOM_MAX;
_zoom = _zooms.max();
else {
QRectF tbr(Mercator().ll2xy(br.topLeft()),
Mercator().ll2xy(br.bottomRight()));
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
_zoom = scale2zoom(qMax(sc.x(), sc.y()));
if (_zoom < ZOOM_MIN)
_zoom = ZOOM_MIN;
if (_zoom > ZOOM_MAX)
_zoom = ZOOM_MAX;
_zoom = limitZoom(scale2zoom(qMax(sc.x(), sc.y())));
}
return _zoom;
@ -187,13 +192,8 @@ qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c)
{
_zoom = (int)(log2((WGS84_RADIUS * 2 * M_PI * cos(deg2rad(c.lat())))
/ resolution) - log2(TILE_SIZE));
if (_zoom < ZOOM_MIN)
_zoom = ZOOM_MIN;
if (_zoom > ZOOM_MAX)
_zoom = ZOOM_MAX;
_zoom = limitZoom((int)(log2((WGS84_RADIUS * 2 * M_PI
* cos(deg2rad(c.lat()))) / resolution) - log2(TILE_SIZE)));
return _zoom;
}
@ -208,13 +208,13 @@ qreal OnlineMap::resolution(const QPointF &p) const
qreal OnlineMap::zoomIn()
{
_zoom = qMin(_zoom + 1, ZOOM_MAX);
_zoom = qMin(_zoom + 1, _zooms.max());
return _zoom;
}
qreal OnlineMap::zoomOut()
{
_zoom = qMax(_zoom - 1, ZOOM_MIN);
_zoom = qMax(_zoom - 1, _zooms.min());
return _zoom;
}

View File

@ -3,6 +3,7 @@
#include "map.h"
#include "tile.h"
#include "range.h"
class Downloader;
@ -11,7 +12,8 @@ class OnlineMap : public Map
Q_OBJECT
public:
OnlineMap(const QString &name, const QString &url, QObject *parent = 0);
OnlineMap(const QString &name, const QString &url, const Range &zooms,
QObject *parent = 0);
const QString &name() const {return _name;}
@ -39,13 +41,13 @@ private slots:
void emitLoaded();
private:
QString tileUrl(const Tile &tile);
QString tileFile(const Tile &tile);
bool loadTileFile(Tile &tile, const QString &file);
void fillTile(Tile &tile);
QString tileUrl(const Tile &tile) const;
QString tileFile(const Tile &tile) const;
void loadTilesAsync(QList<Tile> &list);
void loadTilesSync(QList<Tile> &list);
int limitZoom(int zoom) const;
Range _zooms;
int _zoom;
QString _name;
QString _url;

View File

@ -16,7 +16,7 @@
#include "pathview.h"
#define MAX_DIGITAL_ZOOM 1
#define MAX_DIGITAL_ZOOM 2
#define MIN_DIGITAL_ZOOM -3
#define MARGIN 10.0
#define SCALE_OFFSET 7

View File

@ -8,6 +8,12 @@ void RangeF::resize(qreal size)
_max += adj;
}
QDebug operator<<(QDebug dbg, const Range &range)
{
dbg.nospace() << "Range(" << range.min() << ", " << range.max() << ")";
return dbg.space();
}
QDebug operator<<(QDebug dbg, const RangeF &range)
{
dbg.nospace() << "RangeF(" << range.min() << ", " << range.max() << ")";

View File

@ -4,6 +4,20 @@
#include <QtGlobal>
#include <QDebug>
class Range
{
public:
Range() {_min = 0; _max = 0;}
Range(int min, int max) {_min = min, _max = max;}
int min() const {return _min;}
int max() const {return _max;}
int size() const {return (_max - _min);}
private:
int _min, _max;
};
class RangeF
{
public:
@ -20,6 +34,7 @@ private:
qreal _min, _max;
};
QDebug operator<<(QDebug dbg, const Range &range);
QDebug operator<<(QDebug dbg, const RangeF &range);
#endif // RANGE_H