From b8815ca9f52366feaaa9a75902c7904cfb491a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 2 Apr 2018 23:27:42 +0200 Subject: [PATCH] Fixed layer bounding box & scale denominator range joining --- src/common/range.cpp | 12 +++++------ src/common/range.h | 4 ++-- src/common/rectc.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/common/rectc.h | 2 ++ src/map/wms.cpp | 40 +++++++++++++++++++++++++----------- 5 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/common/range.cpp b/src/common/range.cpp index 484df700..9d13be19 100644 --- a/src/common/range.cpp +++ b/src/common/range.cpp @@ -8,13 +8,13 @@ void RangeF::resize(qreal size) _max += adj; } -RangeF RangeF::operator|(const RangeF &r) const +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)); + if (isNull() || r.isNull()) + return RangeF(); + + RangeF tmp(qMax(this->_min, r._min), qMin(this->_max, r._max)); + return tmp.isValid() ? tmp : RangeF(); } #ifndef QT_NO_DEBUG diff --git a/src/common/range.h b/src/common/range.h index b4d2f771..ed06958f 100644 --- a/src/common/range.h +++ b/src/common/range.h @@ -29,8 +29,8 @@ 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;} + 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;} diff --git a/src/common/rectc.cpp b/src/common/rectc.cpp index d9f2d5a1..f6093d89 100644 --- a/src/common/rectc.cpp +++ b/src/common/rectc.cpp @@ -44,6 +44,54 @@ RectC RectC::operator|(const RectC &r) const return tmp; } +RectC RectC::operator&(const RectC &r) const +{ + if (isNull() || r.isNull()) + return RectC(); + + qreal l1 = _tl.lon(); + qreal r1 = _tl.lon(); + if (_br.lon() - _tl.lon() < 0) + l1 = _br.lon(); + else + r1 = _br.lon(); + + qreal l2 = r._tl.lon(); + qreal r2 = r._tl.lon(); + if (r._br.lon() - r._tl.lon() < 0) + l2 = r._br.lon(); + else + r2 = r._br.lon(); + + if (l1 > r2 || l2 > r1) + return RectC(); + + qreal t1 = _tl.lat(); + qreal b1 = _tl.lat(); + if (_br.lat() - _tl.lat() < 0) + t1 = _br.lat(); + else + b1 = _br.lat(); + + qreal t2 = r._tl.lat(); + qreal b2 = r._tl.lat(); + if (r._br.lat() - r._tl.lat() < 0) + t2 = r._br.lat(); + else + b2 = r._br.lat(); + + if (t1 > b2 || t2 > b1) + return RectC(); + + RectC tmp; + tmp._tl.setLon(qMax(l1, l2)); + tmp._br.setLon(qMin(r1, r2)); + tmp._tl.setLat(qMax(t1, t2)); + tmp._br.setLat(qMin(b1, b2)); + + return tmp; +} + void RectC::unite(const Coordinates &c) { if (isNull()) { diff --git a/src/common/rectc.h b/src/common/rectc.h index 53d0f235..ffc3b08c 100644 --- a/src/common/rectc.h +++ b/src/common/rectc.h @@ -30,6 +30,8 @@ public: RectC operator|(const RectC &r) const; RectC &operator|=(const RectC &r) {*this = *this | r; return *this;} + RectC operator&(const RectC &r) const; + RectC &operator&=(const RectC &r) {*this = *this & r; return *this;} void unite(const Coordinates &c); diff --git a/src/map/wms.cpp b/src/map/wms.cpp index b8e9dab6..23cf848c 100644 --- a/src/map/wms.cpp +++ b/src/map/wms.cpp @@ -96,11 +96,15 @@ void WMS::layer(QXmlStreamReader &reader, CTX &ctx, 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() == "LatLonBoundingBox") { + else if (reader.name() == "MinScaleDenominator") { + double sd = reader.readElementText().toDouble(); + if (!std::isnan(sd)) + scaleDenominator.setMin(sd); + } else if (reader.name() == "MaxScaleDenominator") { + double sd = reader.readElementText().toDouble(); + if (!std::isnan(sd)) + scaleDenominator.setMax(sd); + } else if (reader.name() == "LatLonBoundingBox") { QXmlStreamAttributes attr = reader.attributes(); boundingBox = RectC(Coordinates( attr.value("minx").toString().toDouble(), @@ -208,13 +212,14 @@ bool WMS::parseCapabilities(const QString &path, const Setup &setup) + layer.name; return false; } - if (!layer.scaleDenominator.isValid()) { - _errorString = "Invalid scale denominator range for layer" + if (!layer.scaleDenominator.isValid() + || layer.scaleDenominator.isNull()) { + _errorString = "Invalid scale denominator range for layer " + layer.name; return false; } if (!layer.boundingBox.isValid()) { - _errorString = "Invalid/missing bounding box for layer" + _errorString = "Invalid/missing bounding box for layer " + layer.name; return false; } @@ -226,10 +231,21 @@ bool WMS::parseCapabilities(const QString &path, const Setup &setup) return false; } - 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; + _boundingBox = ctx.layers.first().boundingBox; + for (int i = 1; i < ctx.layers.size(); i++) + _boundingBox &= ctx.layers.at(i).boundingBox; + if (_boundingBox.isNull()) { + _errorString = "Empty layers bounding box join"; + return false; + } + + _scaleDenominator = ctx.layers.first().scaleDenominator; + for (int i = 1; i < ctx.layers.size(); i++) + _scaleDenominator &= ctx.layers.at(i).scaleDenominator; + if (_scaleDenominator.isNull()) { + _errorString = "Empty layers scale denominator range join"; + return false; + } return true; }