mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Added support for limiting the maximal zoom level of online map sources
This commit is contained in:
parent
ba856d7eb6
commit
cc694971be
10
pkg/maps.txt
10
pkg/maps.txt
@ -1,5 +1,5 @@
|
|||||||
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png
|
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png 16
|
||||||
4UMaps http://4umaps.eu/$z/$x/$y.png
|
4UMaps http://4umaps.eu/$z/$x/$y.png 15
|
||||||
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png
|
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
|
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
|
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y 15
|
||||||
|
@ -696,10 +696,11 @@ void GUI::dataSources()
|
|||||||
"following file:")
|
"following file:")
|
||||||
+ "</p><p><code>" + USER_MAP_FILE + "</code></p><p>"
|
+ "</p><p><code>" + USER_MAP_FILE + "</code></p><p>"
|
||||||
+ tr("The file format is one map entry per line, consisting of the map "
|
+ 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 "
|
"name, tiles URL and an optional maximal zoom level delimited by "
|
||||||
"coordinates are replaced with $x and $y in the URL and the zoom "
|
"a TAB character. The tile X and Y coordinates are replaced with $x "
|
||||||
"level is replaced with $z. An example map file could look like:")
|
"and $y in the URL and the zoom level is replaced with $z. An example "
|
||||||
+ "</p><p><code>Map1 http://tile.server.com/map/$z/$x/$y.png"
|
"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>"
|
"<br/>Map2 http://mapserver.org/map/$z-$x-$y</code></p>"
|
||||||
|
|
||||||
+ "<h4>" + tr("Offline maps") + "</h4><p>"
|
+ "<h4>" + tr("Offline maps") + "</h4><p>"
|
||||||
|
@ -1,24 +1,38 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include "range.h"
|
||||||
#include "atlas.h"
|
#include "atlas.h"
|
||||||
#include "offlinemap.h"
|
#include "offlinemap.h"
|
||||||
#include "onlinemap.h"
|
#include "onlinemap.h"
|
||||||
#include "maplist.h"
|
#include "maplist.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ZOOM_MAX 18
|
||||||
|
#define ZOOM_MIN 2
|
||||||
|
|
||||||
Map *MapList::loadListEntry(const QByteArray &line)
|
Map *MapList::loadListEntry(const QByteArray &line)
|
||||||
{
|
{
|
||||||
|
int max;
|
||||||
|
|
||||||
QList<QByteArray> list = line.split('\t');
|
QList<QByteArray> list = line.split('\t');
|
||||||
if (list.size() != 2)
|
if (list.size() < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QByteArray ba1 = list[0].trimmed();
|
QByteArray ba1 = list.at(0).trimmed();
|
||||||
QByteArray ba2 = list[1].trimmed();
|
QByteArray ba2 = list.at(1).trimmed();
|
||||||
if (ba1.isEmpty() || ba2.isEmpty())
|
if (ba1.isEmpty() || ba2.isEmpty())
|
||||||
return 0;
|
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()),
|
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)
|
bool MapList::loadList(const QString &path)
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
#include "onlinemap.h"
|
#include "onlinemap.h"
|
||||||
|
|
||||||
|
|
||||||
#define ZOOM_MAX 18
|
|
||||||
#define ZOOM_MIN 3
|
|
||||||
#define TILE_SIZE 256
|
#define TILE_SIZE 256
|
||||||
|
|
||||||
static QPoint mercator2tile(const QPointF &m, int z)
|
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));
|
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;
|
Downloader *OnlineMap::downloader;
|
||||||
|
|
||||||
OnlineMap::OnlineMap(const QString &name, const QString &url, QObject *parent)
|
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||||
: Map(parent)
|
const Range &zooms, QObject *parent) : Map(parent)
|
||||||
{
|
{
|
||||||
_name = name;
|
_name = name;
|
||||||
_url = url;
|
_url = url;
|
||||||
_block = false;
|
_block = false;
|
||||||
_zoom = ZOOM_MAX;
|
_zooms = zooms;
|
||||||
|
_zoom = zooms.max();
|
||||||
|
|
||||||
connect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
|
connect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
|
||||||
|
|
||||||
@ -115,23 +130,7 @@ void OnlineMap::loadTilesSync(QList<Tile> &list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnlineMap::fillTile(Tile &tile)
|
QString OnlineMap::tileUrl(const Tile &tile) const
|
||||||
{
|
|
||||||
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 url(_url);
|
QString url(_url);
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ QString OnlineMap::tileUrl(const Tile &tile)
|
|||||||
return url;
|
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())
|
QString file = TILES_DIR + QString("/%1/%2-%3-%4").arg(name())
|
||||||
.arg(tile.zoom()).arg(tile.xy().x()).arg(tile.xy().y());
|
.arg(tile.zoom()).arg(tile.xy().x()).arg(tile.xy().y());
|
||||||
@ -166,20 +165,26 @@ QRectF OnlineMap::bounds() const
|
|||||||
1.0/zoom2scale(_zoom));
|
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)
|
qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
|
||||||
{
|
{
|
||||||
if (!br.isValid())
|
if (!br.isValid())
|
||||||
_zoom = ZOOM_MAX;
|
_zoom = _zooms.max();
|
||||||
else {
|
else {
|
||||||
QRectF tbr(Mercator().ll2xy(br.topLeft()),
|
QRectF tbr(Mercator().ll2xy(br.topLeft()),
|
||||||
Mercator().ll2xy(br.bottomRight()));
|
Mercator().ll2xy(br.bottomRight()));
|
||||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||||
|
|
||||||
_zoom = scale2zoom(qMax(sc.x(), sc.y()));
|
_zoom = limitZoom(scale2zoom(qMax(sc.x(), sc.y())));
|
||||||
if (_zoom < ZOOM_MIN)
|
|
||||||
_zoom = ZOOM_MIN;
|
|
||||||
if (_zoom > ZOOM_MAX)
|
|
||||||
_zoom = ZOOM_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _zoom;
|
return _zoom;
|
||||||
@ -187,13 +192,8 @@ qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
|
|||||||
|
|
||||||
qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c)
|
qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c)
|
||||||
{
|
{
|
||||||
_zoom = (int)(log2((WGS84_RADIUS * 2 * M_PI * cos(deg2rad(c.lat())))
|
_zoom = limitZoom((int)(log2((WGS84_RADIUS * 2 * M_PI
|
||||||
/ resolution) - log2(TILE_SIZE));
|
* cos(deg2rad(c.lat()))) / resolution) - log2(TILE_SIZE)));
|
||||||
|
|
||||||
if (_zoom < ZOOM_MIN)
|
|
||||||
_zoom = ZOOM_MIN;
|
|
||||||
if (_zoom > ZOOM_MAX)
|
|
||||||
_zoom = ZOOM_MAX;
|
|
||||||
|
|
||||||
return _zoom;
|
return _zoom;
|
||||||
}
|
}
|
||||||
@ -208,13 +208,13 @@ qreal OnlineMap::resolution(const QPointF &p) const
|
|||||||
|
|
||||||
qreal OnlineMap::zoomIn()
|
qreal OnlineMap::zoomIn()
|
||||||
{
|
{
|
||||||
_zoom = qMin(_zoom + 1, ZOOM_MAX);
|
_zoom = qMin(_zoom + 1, _zooms.max());
|
||||||
return _zoom;
|
return _zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal OnlineMap::zoomOut()
|
qreal OnlineMap::zoomOut()
|
||||||
{
|
{
|
||||||
_zoom = qMax(_zoom - 1, ZOOM_MIN);
|
_zoom = qMax(_zoom - 1, _zooms.min());
|
||||||
return _zoom;
|
return _zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
#include "range.h"
|
||||||
|
|
||||||
class Downloader;
|
class Downloader;
|
||||||
|
|
||||||
@ -11,7 +12,8 @@ class OnlineMap : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
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;}
|
const QString &name() const {return _name;}
|
||||||
|
|
||||||
@ -39,13 +41,13 @@ private slots:
|
|||||||
void emitLoaded();
|
void emitLoaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString tileUrl(const Tile &tile);
|
QString tileUrl(const Tile &tile) const;
|
||||||
QString tileFile(const Tile &tile);
|
QString tileFile(const Tile &tile) const;
|
||||||
bool loadTileFile(Tile &tile, const QString &file);
|
|
||||||
void fillTile(Tile &tile);
|
|
||||||
void loadTilesAsync(QList<Tile> &list);
|
void loadTilesAsync(QList<Tile> &list);
|
||||||
void loadTilesSync(QList<Tile> &list);
|
void loadTilesSync(QList<Tile> &list);
|
||||||
|
int limitZoom(int zoom) const;
|
||||||
|
|
||||||
|
Range _zooms;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QString _name;
|
QString _name;
|
||||||
QString _url;
|
QString _url;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "pathview.h"
|
#include "pathview.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_DIGITAL_ZOOM 1
|
#define MAX_DIGITAL_ZOOM 2
|
||||||
#define MIN_DIGITAL_ZOOM -3
|
#define MIN_DIGITAL_ZOOM -3
|
||||||
#define MARGIN 10.0
|
#define MARGIN 10.0
|
||||||
#define SCALE_OFFSET 7
|
#define SCALE_OFFSET 7
|
||||||
|
@ -8,6 +8,12 @@ void RangeF::resize(qreal size)
|
|||||||
_max += adj;
|
_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)
|
QDebug operator<<(QDebug dbg, const RangeF &range)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "RangeF(" << range.min() << ", " << range.max() << ")";
|
dbg.nospace() << "RangeF(" << range.min() << ", " << range.max() << ")";
|
||||||
|
15
src/range.h
15
src/range.h
@ -4,6 +4,20 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QDebug>
|
#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
|
class RangeF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -20,6 +34,7 @@ private:
|
|||||||
qreal _min, _max;
|
qreal _min, _max;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const Range &range);
|
||||||
QDebug operator<<(QDebug dbg, const RangeF &range);
|
QDebug operator<<(QDebug dbg, const RangeF &range);
|
||||||
|
|
||||||
#endif // RANGE_H
|
#endif // RANGE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user