mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 13:41:16 +01:00
Added support for REST WMTS maps
This commit is contained in:
parent
55e967673c
commit
5e5ff6d96f
@ -126,21 +126,20 @@ Map *MapSource::map(QXmlStreamReader &reader)
|
|||||||
{
|
{
|
||||||
QString name, url, layer, style, set;
|
QString name, url, layer, style, set;
|
||||||
QString format("image/png");
|
QString format("image/png");
|
||||||
bool invert = false;
|
bool wmts, rest = false, invertAxis = false;
|
||||||
Range z(ZOOM_MIN, ZOOM_MAX);
|
Range z(ZOOM_MIN, ZOOM_MAX);
|
||||||
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
||||||
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
|
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
|
||||||
|
|
||||||
const QXmlStreamAttributes &attr = reader.attributes();
|
wmts = (reader.attributes().value("type") == "WMTS") ? true : false;
|
||||||
bool wmts = (attr.hasAttribute("type") && attr.value("type") == "WMTS")
|
|
||||||
? true : false;
|
|
||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == "name")
|
if (reader.name() == "name")
|
||||||
name = reader.readElementText();
|
name = reader.readElementText();
|
||||||
else if (reader.name() == "url")
|
else if (reader.name() == "url") {
|
||||||
|
rest = (reader.attributes().value("type") == "REST") ? true : false;
|
||||||
url = reader.readElementText();
|
url = reader.readElementText();
|
||||||
else if (reader.name() == "zoom") {
|
} else if (reader.name() == "zoom") {
|
||||||
z = zooms(reader);
|
z = zooms(reader);
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
} else if (reader.name() == "bounds") {
|
} else if (reader.name() == "bounds") {
|
||||||
@ -155,7 +154,7 @@ Map *MapSource::map(QXmlStreamReader &reader)
|
|||||||
else if (reader.name() == "set")
|
else if (reader.name() == "set")
|
||||||
set = reader.readElementText();
|
set = reader.readElementText();
|
||||||
else if (reader.name() == "axis")
|
else if (reader.name() == "axis")
|
||||||
invert = (reader.readElementText() == "yx") ? true : false;
|
invertAxis = (reader.readElementText() == "yx") ? true : false;
|
||||||
else
|
else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
@ -163,7 +162,8 @@ Map *MapSource::map(QXmlStreamReader &reader)
|
|||||||
if (reader.error())
|
if (reader.error())
|
||||||
return 0;
|
return 0;
|
||||||
else if (wmts)
|
else if (wmts)
|
||||||
return new WMTSMap(name, url, format, layer, style, set, invert);
|
return new WMTSMap(name, WMTS::Setup(url, layer, set, style, format,
|
||||||
|
rest), invertAxis);
|
||||||
else
|
else
|
||||||
return new OnlineMap(name, url, z, b);
|
return new OnlineMap(name, url, z, b);
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,21 @@ static int scale2zoom(qreal scale)
|
|||||||
|
|
||||||
|
|
||||||
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||||
const Range &zooms, const RectC &bounds, QObject *parent)
|
const Range &zooms, const RectC &bounds, QObject *parent) :
|
||||||
: Map(parent), _name(name), _zooms(zooms), _bounds(bounds)
|
Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
|
||||||
|
_block(false), _valid(false)
|
||||||
{
|
{
|
||||||
_block = false;
|
QString dir(TILES_DIR + "/" + _name);
|
||||||
|
|
||||||
_zoom = _zooms.max();
|
_zoom = _zooms.max();
|
||||||
_tileLoader = TileLoader(url, TILES_DIR + "/" + name);
|
_tileLoader = TileLoader(url, dir);
|
||||||
|
|
||||||
|
if (!QDir().mkpath(dir)) {
|
||||||
|
_errorString = "Error creating tiles dir";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnlineMap::load()
|
void OnlineMap::load()
|
||||||
|
@ -39,6 +39,9 @@ public:
|
|||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
|
bool isValid() const {return _valid;}
|
||||||
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void emitLoaded();
|
void emitLoaded();
|
||||||
|
|
||||||
@ -53,6 +56,9 @@ private:
|
|||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
bool _block;
|
bool _block;
|
||||||
|
|
||||||
|
bool _valid;
|
||||||
|
QString _errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ONLINEMAP_H
|
#endif // ONLINEMAP_H
|
||||||
|
@ -17,13 +17,6 @@ static bool loadTileFile(Tile &tile, const QString &file)
|
|||||||
|
|
||||||
Downloader *TileLoader::_downloader = 0;
|
Downloader *TileLoader::_downloader = 0;
|
||||||
|
|
||||||
TileLoader::TileLoader(const QString &url, const QString &dir)
|
|
||||||
: _url(url), _dir(dir)
|
|
||||||
{
|
|
||||||
if (!QDir().mkpath(_dir))
|
|
||||||
qWarning("Error creating tiles dir: %s\n", qPrintable(_dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileLoader::loadTilesAsync(QList<Tile> &list)
|
void TileLoader::loadTilesAsync(QList<Tile> &list)
|
||||||
{
|
{
|
||||||
QList<Download> dl;
|
QList<Download> dl;
|
||||||
|
@ -9,7 +9,8 @@ class TileLoader
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TileLoader() {}
|
TileLoader() {}
|
||||||
TileLoader(const QString &url, const QString &dir);
|
TileLoader(const QString &url, const QString &dir)
|
||||||
|
: _url(url), _dir(dir) {}
|
||||||
|
|
||||||
void loadTilesAsync(QList<Tile> &list);
|
void loadTilesAsync(QList<Tile> &list);
|
||||||
void loadTilesSync(QList<Tile> &list);
|
void loadTilesSync(QList<Tile> &list);
|
||||||
|
@ -194,6 +194,7 @@ void WMTS::layer(QXmlStreamReader &reader, const QString &layer,
|
|||||||
{
|
{
|
||||||
QString id;
|
QString id;
|
||||||
RectC bounds;
|
RectC bounds;
|
||||||
|
QString tpl;
|
||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == "Identifier")
|
if (reader.name() == "Identifier")
|
||||||
@ -202,12 +203,19 @@ void WMTS::layer(QXmlStreamReader &reader, const QString &layer,
|
|||||||
tileMatrixSetLink(reader, set);
|
tileMatrixSetLink(reader, set);
|
||||||
else if (reader.name() == "WGS84BoundingBox")
|
else if (reader.name() == "WGS84BoundingBox")
|
||||||
bounds = wgs84BoundingBox(reader);
|
bounds = wgs84BoundingBox(reader);
|
||||||
else
|
else if (reader.name() == "ResourceURL") {
|
||||||
|
const QXmlStreamAttributes &attr = reader.attributes();
|
||||||
|
if (attr.value("resourceType") == "tile")
|
||||||
|
tpl = attr.value("template").toString();
|
||||||
|
reader.skipCurrentElement();
|
||||||
|
} else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == layer)
|
if (id == layer) {
|
||||||
_bounds = bounds;
|
_bounds = bounds;
|
||||||
|
_tileUrl = tpl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WMTS::contents(QXmlStreamReader &reader, const QString &layer,
|
void WMTS::contents(QXmlStreamReader &reader, const QString &layer,
|
||||||
@ -264,9 +272,7 @@ bool WMTS::getCapabilities(const QString &url, const QString &file)
|
|||||||
{
|
{
|
||||||
QList<Download> dl;
|
QList<Download> dl;
|
||||||
|
|
||||||
QString capabilitiesUrl = QString("%1?service=WMTS&Version=1.0.0"
|
dl.append(Download(url, file));
|
||||||
"&request=GetCapabilities").arg(url);
|
|
||||||
dl.append(Download(capabilitiesUrl, file));
|
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit()));
|
QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit()));
|
||||||
@ -281,17 +287,31 @@ bool WMTS::getCapabilities(const QString &url, const QString &file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WMTS::load(const QString &file, const QString &url, const QString &layer,
|
bool WMTS::load(const QString &file, const WMTS::Setup &setup)
|
||||||
const QString &set)
|
|
||||||
{
|
{
|
||||||
QMap<QString, Zoom>::const_iterator it;
|
QString capaUrl = setup.rest ? setup.url :
|
||||||
|
QString("%1?service=WMTS&Version=1.0.0&request=GetCapabilities")
|
||||||
|
.arg(setup.url);
|
||||||
|
|
||||||
if (!QFileInfo(file).exists())
|
if (!QFileInfo(file).exists())
|
||||||
if (!getCapabilities(url, file))
|
if (!getCapabilities(capaUrl, file))
|
||||||
return false;
|
return false;
|
||||||
if (!parseCapabilities(file, layer, set))
|
if (!parseCapabilities(file, setup.layer, setup.set))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!setup.rest)
|
||||||
|
_tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile"
|
||||||
|
"&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z"
|
||||||
|
"&TileRow=$y&TileCol=$x").arg(setup.url).arg(setup.format)
|
||||||
|
.arg(setup.layer).arg(setup.style).arg(setup.set);
|
||||||
|
else {
|
||||||
|
_tileUrl.replace("{Style}", setup.style);
|
||||||
|
_tileUrl.replace("{TileMatrixSet}", setup.set);
|
||||||
|
_tileUrl.replace("{TileMatrix}", "$z");
|
||||||
|
_tileUrl.replace("{TileRow}", "$y");
|
||||||
|
_tileUrl.replace("{TileCol}", "$x");
|
||||||
|
}
|
||||||
|
|
||||||
if (_matrixes.isEmpty()) {
|
if (_matrixes.isEmpty()) {
|
||||||
_errorString = "No usable tile matrix found";
|
_errorString = "No usable tile matrix found";
|
||||||
return false;
|
return false;
|
||||||
@ -300,6 +320,10 @@ bool WMTS::load(const QString &file, const QString &url, const QString &layer,
|
|||||||
_errorString = "Missing CRS definition";
|
_errorString = "Missing CRS definition";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (_tileUrl.isNull()) {
|
||||||
|
_errorString = "Missing tile URL";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -325,6 +349,14 @@ QList<WMTS::Zoom> WMTS::zooms() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const WMTS::Setup &setup)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Setup(" << setup.url << ", " << setup.layer << ", "
|
||||||
|
<< setup.set << ", " << setup.style << ", " << setup.format << ", "
|
||||||
|
<< setup.rest << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom)
|
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "Zoom(" << zoom.id << ", " << zoom.scaleDenominator << ", "
|
dbg.nospace() << "Zoom(" << zoom.id << ", " << zoom.scaleDenominator << ", "
|
||||||
|
@ -15,6 +15,20 @@ class Downloader;
|
|||||||
class WMTS
|
class WMTS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Setup {
|
||||||
|
QString url;
|
||||||
|
QString layer;
|
||||||
|
QString set;
|
||||||
|
QString style;
|
||||||
|
QString format;
|
||||||
|
bool rest;
|
||||||
|
|
||||||
|
Setup(const QString &url, const QString &layer, const QString &set,
|
||||||
|
const QString &style, const QString &format, bool rest) :
|
||||||
|
url(url), layer(layer), set(set), style(style), format(format),
|
||||||
|
rest(rest) {}
|
||||||
|
};
|
||||||
|
|
||||||
struct Zoom {
|
struct Zoom {
|
||||||
QString id;
|
QString id;
|
||||||
qreal scaleDenominator;
|
qreal scaleDenominator;
|
||||||
@ -32,13 +46,13 @@ public:
|
|||||||
{return scaleDenominator > other.scaleDenominator;}
|
{return scaleDenominator > other.scaleDenominator;}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool load(const QString &path, const QString &url, const QString &layer,
|
bool load(const QString &path, const Setup &setup);
|
||||||
const QString &set);
|
|
||||||
const QString &errorString() const {return _errorString;}
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
const RectC &bounds() const {return _bounds;}
|
const RectC &bounds() const {return _bounds;}
|
||||||
QList<Zoom> zooms() const;
|
QList<Zoom> zooms() const;
|
||||||
const Projection &projection() const {return _projection;}
|
const Projection &projection() const {return _projection;}
|
||||||
|
QString tileUrl() const {return _tileUrl;}
|
||||||
|
|
||||||
static Downloader *downloader() {return _downloader;}
|
static Downloader *downloader() {return _downloader;}
|
||||||
static void setDownloader(Downloader *downloader)
|
static void setDownloader(Downloader *downloader)
|
||||||
@ -94,6 +108,7 @@ private:
|
|||||||
QSet<MatrixLimits> _limits;
|
QSet<MatrixLimits> _limits;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
Projection _projection;
|
Projection _projection;
|
||||||
|
QString _tileUrl;
|
||||||
|
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
|
||||||
@ -114,6 +129,7 @@ inline uint qHash(const WMTS::MatrixLimits &key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const WMTS::Setup &setup);
|
||||||
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom);
|
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom);
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
|
@ -9,30 +9,27 @@
|
|||||||
|
|
||||||
#define CAPABILITIES_FILE "capabilities.xml"
|
#define CAPABILITIES_FILE "capabilities.xml"
|
||||||
|
|
||||||
WMTSMap::WMTSMap(const QString &name, const QString &url, const QString &format,
|
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, bool invertAxis,
|
||||||
const QString &layer, const QString &style, const QString &set,
|
QObject *parent) : Map(parent), _name(name), _setup(setup),
|
||||||
bool invertAxis, QObject *parent) :
|
_invertAxis(invertAxis), _zoom(0), _valid(false)
|
||||||
Map(parent), _name(name), _url(url), _layer(layer), _set(set),
|
|
||||||
_invertAxis(invertAxis), _zoom(0), _valid(false)
|
|
||||||
{
|
{
|
||||||
QString dir(TILES_DIR + "/" + _name);
|
QString dir(TILES_DIR + "/" + _name);
|
||||||
QString file = dir + "/" + CAPABILITIES_FILE;
|
QString file = dir + "/" + CAPABILITIES_FILE;
|
||||||
|
|
||||||
QString tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile"
|
if (!QDir().mkpath(dir)) {
|
||||||
"&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z&TileRow=$y"
|
_errorString = "Error creating tiles dir";
|
||||||
"&TileCol=$x").arg(_url).arg(format).arg(layer).arg(style)
|
return;
|
||||||
.arg(_set);
|
}
|
||||||
_tileLoader = TileLoader(tileUrl, dir);
|
|
||||||
|
|
||||||
WMTS wmts;
|
WMTS wmts;
|
||||||
if (!wmts.load(file, _url, _layer, _set)) {
|
if (!wmts.load(file, _setup)) {
|
||||||
_errorString = wmts.errorString();
|
_errorString = wmts.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_bounds = wmts.bounds();
|
_bounds = wmts.bounds();
|
||||||
_zooms = wmts.zooms();
|
_zooms = wmts.zooms();
|
||||||
_projection = wmts.projection();
|
_projection = wmts.projection();
|
||||||
|
_tileLoader = TileLoader(wmts.tileUrl(), dir);
|
||||||
updateTransform();
|
updateTransform();
|
||||||
|
|
||||||
_block = false;
|
_block = false;
|
||||||
@ -91,10 +88,12 @@ void WMTSMap::clearCache()
|
|||||||
_tileLoader.clearCache();
|
_tileLoader.clearCache();
|
||||||
|
|
||||||
WMTS wmts;
|
WMTS wmts;
|
||||||
if (!wmts.load(file, _url, _layer, _set))
|
if (!wmts.load(file, _setup))
|
||||||
return;
|
return;
|
||||||
|
_bounds = wmts.bounds();
|
||||||
_zooms = wmts.zooms();
|
_zooms = wmts.zooms();
|
||||||
_projection = wmts.projection();
|
_projection = wmts.projection();
|
||||||
|
_tileLoader = TileLoader(wmts.tileUrl(), dir);
|
||||||
|
|
||||||
if (_zoom >= _zooms.size())
|
if (_zoom >= _zooms.size())
|
||||||
_zoom = _zooms.size() - 1;
|
_zoom = _zooms.size() - 1;
|
||||||
|
@ -13,9 +13,8 @@ class WMTSMap : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WMTSMap(const QString &name, const QString &url, const QString &format,
|
WMTSMap(const QString &name, const WMTS::Setup &setup, bool invertAxis,
|
||||||
const QString &layer, const QString &style, const QString &set,
|
QObject *parent = 0);
|
||||||
bool invertAxis, QObject *parent = 0);
|
|
||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
|
|
||||||
@ -54,7 +53,8 @@ private:
|
|||||||
QPointF ll2xy(const Coordinates &c) const;
|
QPointF ll2xy(const Coordinates &c) const;
|
||||||
Coordinates xy2ll(const QPointF &p) const;
|
Coordinates xy2ll(const QPointF &p) const;
|
||||||
|
|
||||||
QString _name, _url, _layer, _set;
|
QString _name;
|
||||||
|
WMTS::Setup _setup;
|
||||||
TileLoader _tileLoader;
|
TileLoader _tileLoader;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
QList<WMTS::Zoom> _zooms;
|
QList<WMTS::Zoom> _zooms;
|
||||||
|
Loading…
Reference in New Issue
Block a user