mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Added support for WMS multi-layer maps
This commit is contained in:
parent
60cc869ade
commit
e845e216bd
@ -8,6 +8,15 @@ void RangeF::resize(qreal size)
|
||||
_max += adj;
|
||||
}
|
||||
|
||||
RangeF RangeF::operator|(const RangeF &r) const
|
||||
{
|
||||
if (isNull())
|
||||
return r;
|
||||
if (r.isNull())
|
||||
return *this;
|
||||
return RangeF(qMax(this->_min, r._min), qMin(this->_max, r._max));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Range &range)
|
||||
{
|
||||
|
@ -29,10 +29,14 @@ public:
|
||||
RangeF() {_min = 0; _max = 0;}
|
||||
RangeF(qreal min, qreal max) {_min = min, _max = max;}
|
||||
|
||||
RangeF operator|(const RangeF &r) const;
|
||||
RangeF &operator|=(const RangeF &r) {*this = *this | r; return *this;}
|
||||
|
||||
qreal min() const {return _min;}
|
||||
qreal max() const {return _max;}
|
||||
qreal size() const {return (_max - _min);}
|
||||
|
||||
bool isNull() const {return _min == 0 && _max == 0;}
|
||||
bool isValid() const {return size() >= 0;}
|
||||
|
||||
void setMin(qreal min) {_min = min;}
|
||||
|
@ -8,12 +8,27 @@
|
||||
|
||||
Downloader *WMS::_downloader = 0;
|
||||
|
||||
WMS::CTX::CTX(const Setup &setup) : setup(setup), formatSupported(false)
|
||||
{
|
||||
QStringList ll = setup.layer().split(',');
|
||||
QStringList sl = setup.style().split(',');
|
||||
|
||||
if (ll.size() != sl.size())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < ll.size(); i++) {
|
||||
layers.append(Layer(ll.at(i), sl.at(i)));
|
||||
if (sl.at(i) == "default")
|
||||
layers[i].hasStyle = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WMS::getMap(QXmlStreamReader &reader, CTX &ctx)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Format") {
|
||||
if (reader.readElementText() == ctx.setup.format())
|
||||
ctx.format = true;
|
||||
ctx.formatSupported = true;
|
||||
} else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
@ -72,6 +87,7 @@ void WMS::layer(QXmlStreamReader &reader, CTX &ctx,
|
||||
QList<QString> styles(pStyles);
|
||||
RangeF scaleDenominator(pScaleDenominator);
|
||||
RectC boundingBox(pBoundingBox);
|
||||
int index;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "Name")
|
||||
@ -100,12 +116,13 @@ void WMS::layer(QXmlStreamReader &reader, CTX &ctx,
|
||||
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());
|
||||
if ((index = ctx.layers.indexOf(name)) >= 0) {
|
||||
Layer &layer = ctx.layers[index];
|
||||
layer.scaleDenominator = scaleDenominator;
|
||||
layer.boundingBox = boundingBox;
|
||||
layer.isDefined = true;
|
||||
layer.hasStyle = styles.contains(layer.style);
|
||||
layer.hasCRS = CRSs.contains(ctx.setup.crs());
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +161,12 @@ bool WMS::parseCapabilities(const QString &path, const Setup &setup)
|
||||
CTX ctx(setup);
|
||||
QXmlStreamReader reader;
|
||||
|
||||
|
||||
if (ctx.layers.isEmpty()) {
|
||||
_errorString = "Invalid layers definition";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
_errorString = file.errorString();
|
||||
return false;
|
||||
@ -163,38 +186,50 @@ bool WMS::parseCapabilities(const QString &path, const Setup &setup)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctx.layer) {
|
||||
_errorString = ctx.setup.layer() + ": layer not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.style && ctx.setup.style() != "default") {
|
||||
_errorString = ctx.setup.style() + ": style not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.format) {
|
||||
if (!ctx.formatSupported) {
|
||||
_errorString = ctx.setup.format() + ": format not provided";
|
||||
return false;
|
||||
}
|
||||
if (!ctx.crs) {
|
||||
_errorString = ctx.setup.crs() + ": CRS not provided";
|
||||
|
||||
for (int i = 0; i < ctx.layers.size(); i++) {
|
||||
const Layer &layer = ctx.layers.at(i);
|
||||
|
||||
if (!layer.isDefined) {
|
||||
_errorString = ctx.setup.layer() + ": layer not provided";
|
||||
return false;
|
||||
}
|
||||
if (!layer.hasStyle) {
|
||||
_errorString = ctx.setup.style() + ": style not provided for layer "
|
||||
+ layer.name;
|
||||
return false;
|
||||
}
|
||||
if (!layer.hasCRS) {
|
||||
_errorString = ctx.setup.crs() + ": CRS not provided for layer "
|
||||
+ layer.name;
|
||||
return false;
|
||||
}
|
||||
if (!layer.scaleDenominator.isValid()) {
|
||||
_errorString = "Invalid scale denominator range for layer"
|
||||
+ layer.name;
|
||||
return false;
|
||||
}
|
||||
if (!layer.boundingBox.isValid()) {
|
||||
_errorString = "Invalid/missing bounding box for layer"
|
||||
+ layer.name;
|
||||
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;
|
||||
for (int i = 0; i < ctx.layers.size(); i++)
|
||||
_boundingBox |= ctx.layers.at(i).boundingBox;
|
||||
for (int i = 0; i < ctx.layers.size(); i++)
|
||||
_scaleDenominator |= ctx.layers.first().scaleDenominator;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -55,17 +55,28 @@ public:
|
||||
{_downloader = downloader;}
|
||||
|
||||
private:
|
||||
struct CTX {
|
||||
const Setup &setup;
|
||||
struct Layer {
|
||||
QString name;
|
||||
QString style;
|
||||
RangeF scaleDenominator;
|
||||
RectC boundingBox;
|
||||
bool layer;
|
||||
bool style;
|
||||
bool format;
|
||||
bool crs;
|
||||
bool isDefined;
|
||||
bool hasStyle;
|
||||
bool hasCRS;
|
||||
|
||||
CTX(const Setup &setup) : setup(setup), layer(false), style(false),
|
||||
format(false), crs(false) {}
|
||||
Layer(const QString &name, const QString &style = "default")
|
||||
: name(name), style(style), isDefined(false), hasStyle(false),
|
||||
hasCRS(false) {}
|
||||
bool operator==(const Layer &other) const
|
||||
{return this->name == other.name;}
|
||||
};
|
||||
|
||||
struct CTX {
|
||||
const Setup &setup;
|
||||
QList<Layer> layers;
|
||||
bool formatSupported;
|
||||
|
||||
CTX(const Setup &setup);
|
||||
};
|
||||
|
||||
RectC geographicBoundingBox(QXmlStreamReader &reader);
|
||||
|
Loading…
Reference in New Issue
Block a user