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

Properly handle WMTS TileMatrixLimits and default style

This commit is contained in:
Martin Tůma 2018-10-15 00:20:20 +02:00
parent 8f4ce8d38c
commit 4a612f12bb
2 changed files with 81 additions and 81 deletions

View File

@ -12,6 +12,12 @@
#include "wmts.h" #include "wmts.h"
static void skipParentElement(QXmlStreamReader &reader)
{
while (reader.readNextStartElement())
reader.skipCurrentElement();
}
WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader) WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader)
{ {
TileMatrix matrix; TileMatrix matrix;
@ -45,24 +51,19 @@ WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader)
void WMTS::tileMatrixSet(QXmlStreamReader &reader, CTX &ctx) void WMTS::tileMatrixSet(QXmlStreamReader &reader, CTX &ctx)
{ {
QString id, crs;
QSet<TileMatrix> matrixes;
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "Identifier") if (reader.name() == "Identifier") {
id = reader.readElementText(); if (reader.readElementText() != ctx.setup.set()) {
else if (reader.name() == "SupportedCRS") skipParentElement(reader);
crs = reader.readElementText(); return;
}
} else if (reader.name() == "SupportedCRS")
ctx.crs = reader.readElementText();
else if (reader.name() == "TileMatrix") else if (reader.name() == "TileMatrix")
matrixes.insert(tileMatrix(reader)); ctx.matrixes.insert(tileMatrix(reader));
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
if (id == ctx.setup.set()) {
ctx.crs = crs;
_matrixes = matrixes;
}
} }
WMTS::MatrixLimits WMTS::tileMatrixLimits(QXmlStreamReader &reader) WMTS::MatrixLimits WMTS::tileMatrixLimits(QXmlStreamReader &reader)
@ -106,22 +107,19 @@ QSet<WMTS::MatrixLimits> WMTS::tileMatrixSetLimits(QXmlStreamReader &reader)
void WMTS::tileMatrixSetLink(QXmlStreamReader &reader, CTX &ctx) void WMTS::tileMatrixSetLink(QXmlStreamReader &reader, CTX &ctx)
{ {
QString id;
QSet<MatrixLimits> limits;
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "TileMatrixSet") if (reader.name() == "TileMatrixSet") {
id = reader.readElementText(); if (reader.readElementText() == ctx.setup.set())
else if (reader.name() == "TileMatrixSetLimits") ctx.hasSet = true;
limits = tileMatrixSetLimits(reader); else {
skipParentElement(reader);
return;
}
} else if (reader.name() == "TileMatrixSetLimits")
ctx.limits = tileMatrixSetLimits(reader);
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
if (id == ctx.setup.set()) {
ctx.hasSet = true;
_limits = limits;
}
} }
RectC WMTS::wgs84BoundingBox(QXmlStreamReader &reader) RectC WMTS::wgs84BoundingBox(QXmlStreamReader &reader)
@ -158,39 +156,36 @@ QString WMTS::style(QXmlStreamReader &reader)
void WMTS::layer(QXmlStreamReader &reader, CTX &ctx) void WMTS::layer(QXmlStreamReader &reader, CTX &ctx)
{ {
QString id, tpl;
RectC bounds;
QStringList formats, styles;
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "Identifier") if (reader.name() == "Identifier") {
id = reader.readElementText(); if (reader.readElementText() == ctx.setup.layer())
else if (reader.name() == "TileMatrixSetLink") ctx.hasLayer = true;
else {
skipParentElement(reader);
return;
}
} else if (reader.name() == "TileMatrixSetLink")
tileMatrixSetLink(reader, ctx); tileMatrixSetLink(reader, ctx);
else if (reader.name() == "WGS84BoundingBox") else if (reader.name() == "WGS84BoundingBox")
bounds = wgs84BoundingBox(reader); _bounds = wgs84BoundingBox(reader);
else if (reader.name() == "ResourceURL") { else if (reader.name() == "ResourceURL") {
const QXmlStreamAttributes &attr = reader.attributes(); const QXmlStreamAttributes &attr = reader.attributes();
if (attr.value("resourceType") == "tile") if (attr.value("resourceType") == "tile" && ctx.setup.rest())
tpl = attr.value("template").toString(); _tileUrl = attr.value("template").toString();
reader.skipCurrentElement(); reader.skipCurrentElement();
} else if (reader.name() == "Style") } else if (reader.name() == "Style") {
styles.append(style(reader)); const QXmlStreamAttributes &attr = reader.attributes();
else if (reader.name() == "Format") bool isDefault = (attr.value("isDefault") == "true");
formats.append(reader.readElementText()); QString s = style(reader);
else if (isDefault)
reader.skipCurrentElement(); ctx.defaultStyle = s;
} if (!s.isEmpty() && s == ctx.setup.style())
if (id == ctx.setup.layer()) {
ctx.hasLayer = true;
_bounds = bounds;
if (ctx.setup.rest())
_tileUrl = tpl;
if (styles.contains(ctx.setup.style()) || ctx.setup.style().isEmpty())
ctx.hasStyle = true; ctx.hasStyle = true;
if (formats.contains(ctx.setup.format())) } else if (reader.name() == "Format") {
if (reader.readElementText() == ctx.setup.format())
ctx.hasFormat = true; ctx.hasFormat = true;
} else
reader.skipCurrentElement();
} }
} }
@ -216,10 +211,24 @@ void WMTS::capabilities(QXmlStreamReader &reader, CTX &ctx)
} }
} }
bool WMTS::parseCapabilities(const QString &path, const Setup &setup) void WMTS::createZooms(const CTX &ctx)
{
for (QSet<TileMatrix>::const_iterator mi = ctx.matrixes.constBegin();
mi != ctx.matrixes.constEnd(); ++mi) {
QSet<MatrixLimits>::const_iterator li = ctx.limits.find(
MatrixLimits(mi->id));
if (!ctx.limits.isEmpty() && li == ctx.limits.constEnd())
continue;
_zooms.append(Zoom(mi->id, mi->scaleDenominator, mi->topLeft, mi->tile,
mi->matrix, li == ctx.limits.constEnd() ? QRect() : li->rect));
}
qSort(_zooms);
}
bool WMTS::parseCapabilities(const QString &path, CTX &ctx)
{ {
QFile file(path); QFile file(path);
CTX ctx(setup);
QXmlStreamReader reader; QXmlStreamReader reader;
if (!file.open(QFile::ReadOnly | QFile::Text)) { if (!file.open(QFile::ReadOnly | QFile::Text)) {
@ -240,14 +249,20 @@ bool WMTS::parseCapabilities(const QString &path, const Setup &setup)
return false; return false;
} }
createZooms(ctx);
if (!ctx.hasLayer) { if (!ctx.hasLayer) {
_errorString = ctx.setup.layer() + ": layer not provided"; _errorString = ctx.setup.layer() + ": layer not provided";
return false; return false;
} }
if (!ctx.hasStyle) { if (!ctx.hasStyle && !ctx.setup.style().isEmpty()) {
_errorString = ctx.setup.style() + ": style not provided"; _errorString = ctx.setup.style() + ": style not provided";
return false; return false;
} }
if (ctx.setup.style().isEmpty() && ctx.defaultStyle.isEmpty()) {
_errorString = "Default style not provided";
return false;
}
if (!ctx.setup.rest() && !ctx.hasFormat) { if (!ctx.setup.rest() && !ctx.hasFormat) {
_errorString = ctx.setup.format() + ": format not provided"; _errorString = ctx.setup.format() + ": format not provided";
return false; return false;
@ -265,7 +280,7 @@ bool WMTS::parseCapabilities(const QString &path, const Setup &setup)
_errorString = ctx.crs + ": unknown CRS"; _errorString = ctx.crs + ": unknown CRS";
return false; return false;
} }
if (_matrixes.isEmpty()) { if (ctx.matrixes.isEmpty()) {
_errorString = "No usable tile matrix found"; _errorString = "No usable tile matrix found";
return false; return false;
} }
@ -307,10 +322,12 @@ WMTS::WMTS(const QString &file, const WMTS::Setup &setup) : _valid(false)
if (!url.isLocalFile() && !QFileInfo(file).exists()) if (!url.isLocalFile() && !QFileInfo(file).exists())
if (!downloadCapabilities(url.toString(), file, setup.authorization())) if (!downloadCapabilities(url.toString(), file, setup.authorization()))
return; return;
if (!parseCapabilities(url.isLocalFile() ? url.toLocalFile() : file, setup))
CTX ctx(setup);
if (!parseCapabilities(url.isLocalFile() ? url.toLocalFile() : file, ctx))
return; return;
QString style = setup.style().isEmpty() ? "default" : setup.style(); QString style = setup.style().isEmpty() ? ctx.defaultStyle : setup.style();
if (!setup.rest()) { if (!setup.rest()) {
_tileUrl = QString("%1%2service=WMTS&Version=1.0.0&request=GetTile" _tileUrl = QString("%1%2service=WMTS&Version=1.0.0&request=GetTile"
"&Format=%3&Layer=%4&Style=%5&TileMatrixSet=%6&TileMatrix=$z" "&Format=%3&Layer=%4&Style=%5&TileMatrixSet=%6&TileMatrix=$z"
@ -337,26 +354,6 @@ WMTS::WMTS(const QString &file, const WMTS::Setup &setup) : _valid(false)
_valid = true; _valid = true;
} }
QList<WMTS::Zoom> WMTS::zooms() const
{
QList<Zoom> zooms;
QSet<TileMatrix>::const_iterator mi;
QSet<MatrixLimits>::const_iterator li;
for (mi = _matrixes.constBegin(); mi != _matrixes.constEnd(); ++mi) {
if ((li = _limits.find(MatrixLimits(mi->id))) == _limits.constEnd())
zooms.append(Zoom(mi->id, mi->scaleDenominator, mi->topLeft,
mi->tile, mi->matrix, QRect()));
else
zooms.append(Zoom(mi->id, mi->scaleDenominator, mi->topLeft,
mi->tile, mi->matrix, li->rect));
}
qSort(zooms);
return zooms;
}
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const WMTS::Setup &setup) QDebug operator<<(QDebug dbg, const WMTS::Setup &setup)
{ {

View File

@ -80,7 +80,7 @@ public:
WMTS(const QString &path, const Setup &setup); WMTS(const QString &path, const Setup &setup);
const RectC &bounds() const {return _bounds;} const RectC &bounds() const {return _bounds;}
QList<Zoom> zooms() const; const QList<Zoom> &zooms() const {return _zooms;}
const Projection &projection() const {return _projection;} const Projection &projection() const {return _projection;}
const QString &tileUrl() const {return _tileUrl;} const QString &tileUrl() const {return _tileUrl;}
@ -117,7 +117,10 @@ private:
struct CTX { struct CTX {
const Setup &setup; const Setup &setup;
QSet<TileMatrix> matrixes;
QSet<MatrixLimits> limits;
QString crs; QString crs;
QString defaultStyle;
bool hasLayer; bool hasLayer;
bool hasStyle; bool hasStyle;
bool hasFormat; bool hasFormat;
@ -137,12 +140,12 @@ private:
void layer(QXmlStreamReader &reader, CTX &ctx); void layer(QXmlStreamReader &reader, CTX &ctx);
void contents(QXmlStreamReader &reader, CTX &ctx); void contents(QXmlStreamReader &reader, CTX &ctx);
void capabilities(QXmlStreamReader &reader, CTX &ctx); void capabilities(QXmlStreamReader &reader, CTX &ctx);
bool parseCapabilities(const QString &path, const Setup &setup); bool parseCapabilities(const QString &path, CTX &ctx);
bool downloadCapabilities(const QString &url, const QString &file, bool downloadCapabilities(const QString &url, const QString &file,
const Authorization &authorization); const Authorization &authorization);
void createZooms(const CTX &ctx);
QSet<TileMatrix> _matrixes; QList<Zoom> _zooms;
QSet<MatrixLimits> _limits;
RectC _bounds; RectC _bounds;
Projection _projection; Projection _projection;
QString _tileUrl; QString _tileUrl;