1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 13:41:16 +01:00

Added tile matrix set limits handling

Added axis order setting
This commit is contained in:
Martin Tůma 2018-02-24 01:59:03 +01:00
parent bf6ebdc088
commit d11ffc9ea4
5 changed files with 145 additions and 41 deletions

View File

@ -124,7 +124,8 @@ RectC MapSource::bounds(QXmlStreamReader &reader)
Map *MapSource::map(QXmlStreamReader &reader) Map *MapSource::map(QXmlStreamReader &reader)
{ {
QString name, url, format, layer, style, tileMatrixSet; QString name, url, format, layer, style, set;
bool invert = 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));
@ -150,8 +151,10 @@ Map *MapSource::map(QXmlStreamReader &reader)
layer = reader.readElementText(); layer = reader.readElementText();
else if (reader.name() == "style") else if (reader.name() == "style")
style = reader.readElementText(); style = reader.readElementText();
else if (reader.name() == "tilematrixset") else if (reader.name() == "set")
tileMatrixSet = reader.readElementText(); set = reader.readElementText();
else if (reader.name() == "axis")
invert = (reader.readElementText() == "yx") ? true : false;
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
@ -159,7 +162,7 @@ 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, tileMatrixSet); return new WMTSMap(name, url, format, layer, style, set, invert);
else else
return new OnlineMap(name, url, z, b); return new OnlineMap(name, url, z, b);
} }

View File

@ -52,10 +52,13 @@ bool WMTS::createProjection(const QString &crs)
void WMTS::tileMatrix(QXmlStreamReader &reader) void WMTS::tileMatrix(QXmlStreamReader &reader)
{ {
int id;
Zoom zoom; Zoom zoom;
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "ScaleDenominator") if (reader.name() == "Identifier")
id = reader.readElementText().toInt();
else if (reader.name() == "ScaleDenominator")
zoom.scaleDenominator = reader.readElementText().toDouble(); zoom.scaleDenominator = reader.readElementText().toDouble();
else if (reader.name() == "TopLeftCorner") { else if (reader.name() == "TopLeftCorner") {
QString str = reader.readElementText(); QString str = reader.readElementText();
@ -72,7 +75,11 @@ void WMTS::tileMatrix(QXmlStreamReader &reader)
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
_zooms.append(zoom); Zoom &z = _zooms[id];
z.matrix = zoom.matrix;
z.scaleDenominator = zoom.scaleDenominator;
z.tile = zoom.tile;
z.topLeft = zoom.topLeft;
} }
void WMTS::tileMatrixSet(QXmlStreamReader &reader, const QString &set) void WMTS::tileMatrixSet(QXmlStreamReader &reader, const QString &set)
@ -92,27 +99,94 @@ void WMTS::tileMatrixSet(QXmlStreamReader &reader, const QString &set)
} }
} }
void WMTS::contents(QXmlStreamReader &reader, const QString &set) void WMTS::tileMatrixLimits(QXmlStreamReader &reader)
{
int id;
QRect limits;
while (reader.readNextStartElement()) {
if (reader.name() == "TileMatrix")
id = reader.readElementText().toInt();
else if (reader.name() == "MinTileRow")
limits.setTop(reader.readElementText().toInt());
else if (reader.name() == "MaxTileRow")
limits.setBottom(reader.readElementText().toInt());
else if (reader.name() == "MinTileCol")
limits.setLeft(reader.readElementText().toInt());
else if (reader.name() == "MaxTileCol")
limits.setRight(reader.readElementText().toInt());
else
reader.skipCurrentElement();
}
_zooms[id].limits = limits;
}
void WMTS::tileMatrixSetLimits(QXmlStreamReader &reader)
{
while (reader.readNextStartElement()) {
if (reader.name() == "TileMatrixLimits")
tileMatrixLimits(reader);
else
reader.skipCurrentElement();
}
}
void WMTS::tileMatrixSetLink(QXmlStreamReader &reader, const QString &set)
{
QString id;
while (reader.readNextStartElement()) {
if (reader.name() == "TileMatrixSet")
id = reader.readElementText();
else if (reader.name() == "TileMatrixSetLimits" && id == set)
tileMatrixSetLimits(reader);
else
reader.skipCurrentElement();
}
}
void WMTS::layer(QXmlStreamReader &reader, const QString &layer,
const QString &set)
{
QString id;
while (reader.readNextStartElement()) {
if (reader.name() == "Identifier")
id = reader.readElementText();
else if (reader.name() == "TileMatrixSetLink" && id == layer)
tileMatrixSetLink(reader, set);
else
reader.skipCurrentElement();
}
}
void WMTS::contents(QXmlStreamReader &reader, const QString &layer,
const QString &set)
{ {
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "TileMatrixSet") if (reader.name() == "TileMatrixSet")
tileMatrixSet(reader, set); tileMatrixSet(reader, set);
else if (reader.name() == "Layer")
WMTS::layer(reader, layer, set);
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
} }
void WMTS::capabilities(QXmlStreamReader &reader, const QString &set) void WMTS::capabilities(QXmlStreamReader &reader, const QString &layer,
const QString &set)
{ {
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == "Contents") if (reader.name() == "Contents")
contents(reader, set); contents(reader, layer, set);
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
} }
bool WMTS::parseCapabilities(const QString &path, const QString &tileMatrixSet) bool WMTS::parseCapabilities(const QString &path, const QString &layer,
const QString &set)
{ {
QFile file(path); QFile file(path);
QXmlStreamReader reader; QXmlStreamReader reader;
@ -126,7 +200,7 @@ bool WMTS::parseCapabilities(const QString &path, const QString &tileMatrixSet)
if (reader.readNextStartElement()) { if (reader.readNextStartElement()) {
if (reader.name() == "Capabilities") if (reader.name() == "Capabilities")
capabilities(reader, tileMatrixSet); capabilities(reader, layer, set);
else else
reader.raiseError("Not a Capabilities XML file"); reader.raiseError("Not a Capabilities XML file");
} }
@ -158,13 +232,13 @@ bool WMTS::getCapabilities(const QString &url, const QString &file)
} }
} }
bool WMTS::load(const QString &file, const QString &url, bool WMTS::load(const QString &file, const QString &url, const QString &layer,
const QString &tileMatrixSet) const QString &set)
{ {
if (!QFileInfo(file).exists()) if (!QFileInfo(file).exists())
if (!getCapabilities(url, file)) if (!getCapabilities(url, file))
return false; return false;
if (!parseCapabilities(file, tileMatrixSet)) if (!parseCapabilities(file, layer, set))
return false; return false;
if (_projection.isNull()) { if (_projection.isNull()) {
@ -178,3 +252,12 @@ bool WMTS::load(const QString &file, const QString &url,
return true; return true;
} }
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom)
{
dbg.nospace() << "Zoom(" << zoom.scaleDenominator << ", " << zoom.topLeft
<< ", " << zoom.tile << ", " << zoom.matrix << ", " << zoom.limits << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG

View File

@ -2,7 +2,7 @@
#define WMTS_H #define WMTS_H
#include <QSize> #include <QSize>
#include <QList> #include <QMap>
#include "projection.h" #include "projection.h"
class QXmlStreamReader; class QXmlStreamReader;
@ -16,14 +16,15 @@ public:
QPointF topLeft; QPointF topLeft;
QSize tile; QSize tile;
QSize matrix; QSize matrix;
QRect limits;
}; };
bool load(const QString &path, const QString &url, bool load(const QString &path, const QString &url, const QString &layer,
const QString &tileMatrixSet); const QString &set);
const QString &errorString() const {return _errorString;} const QString &errorString() const {return _errorString;}
const QList<Zoom> &zooms() {return _zooms;} const QList<Zoom> zooms() const {return _zooms.values();}
const Projection &projection() {return _projection;} const Projection &projection() const {return _projection;}
static Downloader *downloader() {return _downloader;} static Downloader *downloader() {return _downloader;}
static void setDownloader(Downloader *downloader) static void setDownloader(Downloader *downloader)
@ -32,14 +33,22 @@ public:
private: private:
bool createProjection(const QString &crs); bool createProjection(const QString &crs);
void tileMatrixLimits(QXmlStreamReader &reader);
void tileMatrix(QXmlStreamReader &reader); void tileMatrix(QXmlStreamReader &reader);
void tileMatrixSetLimits(QXmlStreamReader &reader);
void tileMatrixSet(QXmlStreamReader &reader, const QString &set); void tileMatrixSet(QXmlStreamReader &reader, const QString &set);
void contents(QXmlStreamReader &reader, const QString &set); void tileMatrixSetLink(QXmlStreamReader &reader, const QString &set);
void capabilities(QXmlStreamReader &reader, const QString &set); void layer(QXmlStreamReader &reader, const QString &layer,
bool parseCapabilities(const QString &path, const QString &tileMatrixSet); const QString &set);
void contents(QXmlStreamReader &reader, const QString &layer,
const QString &set);
void capabilities(QXmlStreamReader &reader, const QString &layer,
const QString &set);
bool parseCapabilities(const QString &path, const QString &layer,
const QString &set);
bool getCapabilities(const QString &url, const QString &file); bool getCapabilities(const QString &url, const QString &file);
QList<Zoom> _zooms; QMap<int, Zoom> _zooms;
Projection _projection; Projection _projection;
QString _errorString; QString _errorString;
@ -47,4 +56,8 @@ private:
static Downloader *_downloader; static Downloader *_downloader;
}; };
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom);
#endif // QT_NO_DEBUG
#endif // WMTS_H #endif // WMTS_H

View File

@ -10,9 +10,10 @@
#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 QString &url, const QString &format,
const QString &layer, const QString &style, const QString &tileMatrixSet, const QString &layer, const QString &style, const QString &set,
QObject *parent) : Map(parent), _name(name), _url(url), bool invertAxis, QObject *parent) :
_tileMatrixSet(tileMatrixSet), _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;
@ -20,11 +21,11 @@ WMTSMap::WMTSMap(const QString &name, const QString &url, const QString &format,
QString tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile" QString tileUrl = QString("%1?service=WMTS&Version=1.0.0&request=GetTile"
"&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z&TileRow=$y" "&Format=%2&Layer=%3&Style=%4&TileMatrixSet=%5&TileMatrix=$z&TileRow=$y"
"&TileCol=$x").arg(_url).arg(format).arg(layer).arg(style) "&TileCol=$x").arg(_url).arg(format).arg(layer).arg(style)
.arg(_tileMatrixSet); .arg(_set);
_tileLoader = TileLoader(tileUrl, dir); _tileLoader = TileLoader(tileUrl, dir);
WMTS wmts; WMTS wmts;
if (!wmts.load(file, _url, _tileMatrixSet)) { if (!wmts.load(file, _url, _layer, _set)) {
_errorString = wmts.errorString(); _errorString = wmts.errorString();
return; return;
} }
@ -51,11 +52,13 @@ void WMTSMap::updateTransform()
if (_projection.isGeographic()) if (_projection.isGeographic())
pixelSpan /= deg2rad(WGS84_RADIUS); pixelSpan /= deg2rad(WGS84_RADIUS);
QPointF tileSpan(z.tile.width() * pixelSpan, z.tile.height() * pixelSpan); QPointF tileSpan(z.tile.width() * pixelSpan, z.tile.height() * pixelSpan);
QPointF bottomRight(z.topLeft.x() + tileSpan.x() * z.matrix.width(), QPointF topLeft = _invertAxis
z.topLeft.y() - tileSpan.y() * z.matrix.height()); ? QPointF(z.topLeft.y(), z.topLeft.x()) : z.topLeft;
QPointF bottomRight(topLeft.x() + tileSpan.x() * z.matrix.width(),
topLeft.y() - tileSpan.y() * z.matrix.height());
tl.xy = QPoint(0, 0); tl.xy = QPoint(0, 0);
tl.pp = z.topLeft; tl.pp = topLeft;
br.xy = QPoint(z.tile.width() * z.matrix.width(), br.xy = QPoint(z.tile.width() * z.matrix.width(),
z.tile.height() * z.matrix.height()); z.tile.height() * z.matrix.height());
br.pp = bottomRight; br.pp = bottomRight;
@ -87,7 +90,7 @@ void WMTSMap::clearCache()
_tileLoader.clearCache(); _tileLoader.clearCache();
WMTS wmts; WMTS wmts;
if (!wmts.load(file, _url, _tileMatrixSet)) if (!wmts.load(file, _url, _layer, _set))
return; return;
_zooms = wmts.zooms(); _zooms = wmts.zooms();
_projection = wmts.projection(); _projection = wmts.projection();
@ -105,8 +108,9 @@ void WMTSMap::emitLoaded()
QRectF WMTSMap::bounds() const QRectF WMTSMap::bounds() const
{ {
const WMTS::Zoom &z = _zooms.at(_zoom); const WMTS::Zoom &z = _zooms.at(_zoom);
return QRectF(QPointF(0, 0), QSize(z.tile.width() * z.matrix.width(), return QRectF(QPointF(z.limits.left() * z.tile.width(), z.limits.top()
z.tile.height() * z.matrix.height())); * z.tile.height()), QSize(z.tile.width() * z.limits.width(),
z.tile.height() * z.limits.height()));
} }
qreal WMTSMap::zoomFit(const QSize &size, const RectC &br) qreal WMTSMap::zoomFit(const QSize &size, const RectC &br)
@ -174,12 +178,12 @@ void WMTSMap::draw(QPainter *painter, const QRectF &rect)
const WMTS::Zoom &z = _zooms.at(_zoom); const WMTS::Zoom &z = _zooms.at(_zoom);
QPoint tl = QPoint((int)floor(rect.left() / (qreal)z.tile.width()), QPoint tl = QPoint((int)floor(rect.left() / (qreal)z.tile.width()),
(int)floor(rect.top() / (qreal)z.tile.height())); (int)floor(rect.top() / (qreal)z.tile.height()));
QPoint br = QPoint((int)floor(rect.right() / (qreal)z.tile.width()), QPoint br = QPoint((int)ceil(rect.right() / (qreal)z.tile.width()),
(int)floor(rect.bottom() / (qreal)z.tile.height())); (int)ceil(rect.bottom() / (qreal)z.tile.height()));
QList<Tile> tiles; QList<Tile> tiles;
for (int i = tl.x(); i <= br.x(); i++) for (int i = tl.x(); i < br.x(); i++)
for (int j = tl.y(); j <= br.y(); j++) for (int j = tl.y(); j < br.y(); j++)
tiles.append(Tile(QPoint(i, j), _zoom)); tiles.append(Tile(QPoint(i, j), _zoom));
if (_block) if (_block)

View File

@ -14,8 +14,8 @@ class WMTSMap : public Map
public: public:
WMTSMap(const QString &name, const QString &url, const QString &format, WMTSMap(const QString &name, const QString &url, const QString &format,
const QString &layer, const QString &style, const QString &tileMatrixSet, 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,9 +54,10 @@ 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, _tileMatrixSet; QString _name, _url, _layer, _set;
TileLoader _tileLoader; TileLoader _tileLoader;
QList<WMTS::Zoom> _zooms; QList<WMTS::Zoom> _zooms;
bool _invertAxis;
Projection _projection; Projection _projection;
QTransform _transform, _inverted; QTransform _transform, _inverted;
int _zoom; int _zoom;