mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 13:41:16 +01:00
Properly handle WMTS TileMatrixLimits and default style
This commit is contained in:
parent
8f4ce8d38c
commit
4a612f12bb
149
src/map/wmts.cpp
149
src/map/wmts.cpp
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user