1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +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)
{
QString name, url, format, layer, style, tileMatrixSet;
QString name, url, format, layer, style, set;
bool invert = false;
Range z(ZOOM_MIN, ZOOM_MAX);
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
@ -150,8 +151,10 @@ Map *MapSource::map(QXmlStreamReader &reader)
layer = reader.readElementText();
else if (reader.name() == "style")
style = reader.readElementText();
else if (reader.name() == "tilematrixset")
tileMatrixSet = reader.readElementText();
else if (reader.name() == "set")
set = reader.readElementText();
else if (reader.name() == "axis")
invert = (reader.readElementText() == "yx") ? true : false;
else
reader.skipCurrentElement();
}
@ -159,7 +162,7 @@ Map *MapSource::map(QXmlStreamReader &reader)
if (reader.error())
return 0;
else if (wmts)
return new WMTSMap(name, url, format, layer, style, tileMatrixSet);
return new WMTSMap(name, url, format, layer, style, set, invert);
else
return new OnlineMap(name, url, z, b);
}

View File

@ -52,10 +52,13 @@ bool WMTS::createProjection(const QString &crs)
void WMTS::tileMatrix(QXmlStreamReader &reader)
{
int id;
Zoom zoom;
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();
else if (reader.name() == "TopLeftCorner") {
QString str = reader.readElementText();
@ -72,7 +75,11 @@ void WMTS::tileMatrix(QXmlStreamReader &reader)
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)
@ -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()) {
if (reader.name() == "TileMatrixSet")
tileMatrixSet(reader, set);
else if (reader.name() == "Layer")
WMTS::layer(reader, layer, set);
else
reader.skipCurrentElement();
}
}
void WMTS::capabilities(QXmlStreamReader &reader, const QString &set)
void WMTS::capabilities(QXmlStreamReader &reader, const QString &layer,
const QString &set)
{
while (reader.readNextStartElement()) {
if (reader.name() == "Contents")
contents(reader, set);
contents(reader, layer, set);
else
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);
QXmlStreamReader reader;
@ -126,7 +200,7 @@ bool WMTS::parseCapabilities(const QString &path, const QString &tileMatrixSet)
if (reader.readNextStartElement()) {
if (reader.name() == "Capabilities")
capabilities(reader, tileMatrixSet);
capabilities(reader, layer, set);
else
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,
const QString &tileMatrixSet)
bool WMTS::load(const QString &file, const QString &url, const QString &layer,
const QString &set)
{
if (!QFileInfo(file).exists())
if (!getCapabilities(url, file))
return false;
if (!parseCapabilities(file, tileMatrixSet))
if (!parseCapabilities(file, layer, set))
return false;
if (_projection.isNull()) {
@ -178,3 +252,12 @@ bool WMTS::load(const QString &file, const QString &url,
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
#include <QSize>
#include <QList>
#include <QMap>
#include "projection.h"
class QXmlStreamReader;
@ -16,14 +16,15 @@ public:
QPointF topLeft;
QSize tile;
QSize matrix;
QRect limits;
};
bool load(const QString &path, const QString &url,
const QString &tileMatrixSet);
bool load(const QString &path, const QString &url, const QString &layer,
const QString &set);
const QString &errorString() const {return _errorString;}
const QList<Zoom> &zooms() {return _zooms;}
const Projection &projection() {return _projection;}
const QList<Zoom> zooms() const {return _zooms.values();}
const Projection &projection() const {return _projection;}
static Downloader *downloader() {return _downloader;}
static void setDownloader(Downloader *downloader)
@ -32,14 +33,22 @@ public:
private:
bool createProjection(const QString &crs);
void tileMatrixLimits(QXmlStreamReader &reader);
void tileMatrix(QXmlStreamReader &reader);
void tileMatrixSetLimits(QXmlStreamReader &reader);
void tileMatrixSet(QXmlStreamReader &reader, const QString &set);
void contents(QXmlStreamReader &reader, const QString &set);
void capabilities(QXmlStreamReader &reader, const QString &set);
bool parseCapabilities(const QString &path, const QString &tileMatrixSet);
void tileMatrixSetLink(QXmlStreamReader &reader, const QString &set);
void layer(QXmlStreamReader &reader, const QString &layer,
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);
QList<Zoom> _zooms;
QMap<int, Zoom> _zooms;
Projection _projection;
QString _errorString;
@ -47,4 +56,8 @@ private:
static Downloader *_downloader;
};
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const WMTS::Zoom &zoom);
#endif // QT_NO_DEBUG
#endif // WMTS_H

View File

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

View File

@ -14,8 +14,8 @@ class WMTSMap : public Map
public:
WMTSMap(const QString &name, const QString &url, const QString &format,
const QString &layer, const QString &style, const QString &tileMatrixSet,
QObject *parent = 0);
const QString &layer, const QString &style, const QString &set,
bool invertAxis, QObject *parent = 0);
const QString &name() const {return _name;}
@ -54,9 +54,10 @@ private:
QPointF ll2xy(const Coordinates &c) const;
Coordinates xy2ll(const QPointF &p) const;
QString _name, _url, _tileMatrixSet;
QString _name, _url, _layer, _set;
TileLoader _tileLoader;
QList<WMTS::Zoom> _zooms;
bool _invertAxis;
Projection _projection;
QTransform _transform, _inverted;
int _zoom;