1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 23:03:22 +02:00
GPXSee/src/map/wms.cpp

216 lines
5.2 KiB
C++
Raw Normal View History

#include <QFileInfo>
#include <QEventLoop>
#include <QXmlStreamReader>
#include "downloader.h"
#include "crs.h"
#include "wms.h"
Downloader *WMS::_downloader = 0;
void WMS::getMap(QXmlStreamReader &reader, CTX &ctx)
{
while (reader.readNextStartElement()) {
if (reader.name() == "Format") {
if (reader.readElementText() == ctx.setup.format())
ctx.format = true;
} else
reader.skipCurrentElement();
}
}
void WMS::request(QXmlStreamReader &reader, CTX &ctx)
{
while (reader.readNextStartElement()) {
if (reader.name() == "GetMap")
getMap(reader, ctx);
else
reader.skipCurrentElement();
}
}
QString WMS::style(QXmlStreamReader &reader)
{
QString name;
while (reader.readNextStartElement()) {
if (reader.name() == "Name")
name = reader.readElementText();
else
reader.skipCurrentElement();
}
return name;
}
void WMS::layer(QXmlStreamReader &reader, CTX &ctx,
const QList<QString> &pCRSs, const QList<QString> &pStyles)
{
QString name;
QList<QString> CRSs(pCRSs);
QList<QString> styles(pStyles);
RangeF scaleDenominator(2132.729583849784, 559082264.0287178);
QRectF boundingBox;
while (reader.readNextStartElement()) {
if (reader.name() == "Name")
name = reader.readElementText();
else if (reader.name() == "CRS")
CRSs.append(reader.readElementText());
else if (reader.name() == "Style")
styles.append(style(reader));
else if (reader.name() == "MinScaleDenominator")
scaleDenominator.setMin(reader.readElementText().toDouble());
else if (reader.name() == "MaxScaleDenominator")
scaleDenominator.setMax(reader.readElementText().toDouble());
else if (reader.name() == "BoundingBox") {
QXmlStreamAttributes attr = reader.attributes();
if (attr.value("CRS") == ctx.setup.crs()) {
if (ctx.setup.yx())
boundingBox = QRectF(QPointF(
attr.value("miny").toString().toDouble(),
attr.value("maxx").toString().toDouble()),
QPointF(attr.value("maxy").toString().toDouble(),
attr.value("minx").toString().toDouble()));
else
boundingBox = QRectF(QPointF(
attr.value("minx").toString().toDouble(),
attr.value("maxy").toString().toDouble()),
QPointF(attr.value("maxx").toString().toDouble(),
attr.value("miny").toString().toDouble()));
}
reader.skipCurrentElement();
} else if (reader.name() == "Layer")
layer(reader, ctx, CRSs, styles);
else
reader.skipCurrentElement();
}
if (name == ctx.setup.layer()) {
ctx.scaleDenominator = scaleDenominator;
ctx.boundingBox = boundingBox;
ctx.layer = true;
ctx.style = styles.contains(ctx.setup.style());
ctx.crs = CRSs.contains(ctx.setup.crs());
}
}
void WMS::capability(QXmlStreamReader &reader, CTX &ctx)
{
QList<QString> CRSs;
QList<QString> styles;
while (reader.readNextStartElement()) {
if (reader.name() == "Layer")
layer(reader, ctx, CRSs, styles);
else if (reader.name() == "Request")
request(reader, ctx);
else
reader.skipCurrentElement();
}
}
void WMS::capabilities(QXmlStreamReader &reader, CTX &ctx)
{
while (reader.readNextStartElement()) {
if (reader.name() == "Capability")
capability(reader, ctx);
else
reader.skipCurrentElement();
}
}
bool WMS::parseCapabilities(const QString &path, const Setup &setup)
{
QFile file(path);
CTX ctx(setup);
QXmlStreamReader reader;
if (!file.open(QFile::ReadOnly | QFile::Text)) {
_errorString = file.errorString();
return false;
}
reader.setDevice(&file);
if (reader.readNextStartElement()) {
if (reader.name() == "WMS_Capabilities")
capabilities(reader, ctx);
else
reader.raiseError("Not a WMS_Capabilities XML file");
}
if (reader.error()) {
_errorString = QString("%1:%2: %3").arg(path).arg(reader.lineNumber())
.arg(reader.errorString());
return false;
}
if (!ctx.layer) {
_errorString = ctx.setup.layer() + ": layer not provided";
return false;
}
if (!ctx.style) {
_errorString = ctx.setup.style() + ": style not provided";
return false;
}
if (!ctx.format) {
_errorString = ctx.setup.format() + ": format not provided";
return false;
}
if (!ctx.crs) {
_errorString = ctx.setup.crs() + ": CRS not provided";
return false;
}
_projection = CRS::projection(ctx.setup.crs());
if (_projection.isNull()) {
_errorString = ctx.setup.crs() + ": unknown CRS";
return false;
}
if (!ctx.scaleDenominator.isValid()) {
_errorString = "Invalid scale denominator range";
return false;
}
if (ctx.boundingBox.isNull()) {
_errorString = "Missing bounding box";
return false;
}
_boundingBox = ctx.boundingBox;
_scaleDenominator = ctx.scaleDenominator;
return true;
}
bool WMS::getCapabilities(const QString &url, const QString &file)
{
QList<Download> dl;
dl.append(Download(url, file));
QEventLoop wait;
QObject::connect(_downloader, SIGNAL(finished()), &wait, SLOT(quit()));
if (_downloader->get(dl))
wait.exec();
if (QFileInfo(file).exists())
return true;
else {
_errorString = "Error downloading capabilities XML file";
return false;
}
}
WMS::WMS(const QString &file, const WMS::Setup &setup) : _valid(false)
{
QString capaUrl = QString("%1?service=WMS&request=GetCapabilities")
.arg(setup.url());
if (!QFileInfo(file).exists())
if (!getCapabilities(capaUrl, file))
return;
if (!parseCapabilities(file, setup))
return;
_valid = true;
}