From cdc71e2856b060a390ae1c4d953bd1ffbda629fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sun, 7 Mar 2021 11:58:21 +0100 Subject: [PATCH] Do not repeatedly compute the areas bounds --- gpxsee.pro | 1 - src/GUI/areaitem.cpp | 4 ++-- src/data/area.h | 42 +++++++++++++++++++++++--------------- src/data/geojsonparser.cpp | 13 ++++++++---- src/data/gpxparser.cpp | 6 +++--- src/data/kmlparser.cpp | 5 +++-- src/data/polygon.cpp | 15 -------------- src/data/polygon.h | 25 +++++++++++++++++++++-- 8 files changed, 66 insertions(+), 45 deletions(-) delete mode 100644 src/data/polygon.cpp diff --git a/gpxsee.pro b/gpxsee.pro index 87d7e6f4..c0fd7ab4 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -347,7 +347,6 @@ SOURCES += src/main.cpp \ src/data/locparser.cpp \ src/data/slfparser.cpp \ src/data/dem.cpp \ - src/data/polygon.cpp \ src/map/obliquestereographic.cpp \ src/GUI/coordinatesitem.cpp \ src/map/rmap.cpp \ diff --git a/src/GUI/areaitem.cpp b/src/GUI/areaitem.cpp index 0ae9e90b..8f61e105 100644 --- a/src/GUI/areaitem.cpp +++ b/src/GUI/areaitem.cpp @@ -67,8 +67,8 @@ void AreaItem::updatePainterPath() { _painterPath = QPainterPath(); - for (int i = 0; i < _area.size(); i++) - _painterPath.addPath(painterPath(_area.at(i))); + for (int i = 0; i < _area.polygons().size(); i++) + _painterPath.addPath(painterPath(_area.polygons().at(i))); } void AreaItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, diff --git a/src/data/area.h b/src/data/area.h index ecd01f9a..731cd2e1 100644 --- a/src/data/area.h +++ b/src/data/area.h @@ -5,48 +5,58 @@ #include #include "polygon.h" -class Area : public QList +class Area { public: Area() {} Area(const RectC &rect) { - Polygon polygon; QVector v(4); v[0] = Coordinates(rect.left(), rect.top()); v[1] = Coordinates(rect.right(), rect.top()); v[2] = Coordinates(rect.right(), rect.bottom()); v[3] = Coordinates(rect.left(), rect.bottom()); - polygon.append(v); - append(polygon); + + _polygons.reserve(1); + _polygons.append(v); + _boundingRect = RectC(v.at(0), v.at(2)); + } + Area(const Polygon &polygon) + { + _polygons.reserve(1); + _polygons.append(polygon); + _boundingRect = polygon.boundingRect(); } - const QString& name() const {return _name;} - const QString& description() const {return _desc;} - void setName(const QString &name) {_name = name;} - void setDescription(const QString &desc) {_desc = desc;} + const QString &name() const {return _name;} + const QString &description() const {return _desc;} + const QList &polygons() const {return _polygons;} + const RectC &boundingRect() const {return _boundingRect;} bool isValid() const { - if (isEmpty()) + if (_polygons.isEmpty()) return false; - for (int i = 0; i < size(); i++) - if (!at(i).isValid()) + for (int i = 0; i < _polygons.size(); i++) + if (!_polygons.at(i).isValid()) return false; return true; } - RectC boundingRect() const + void append(const Polygon &polygon) { - RectC ret; - for (int i = 0; i < size(); i++) - ret |= at(i).boundingRect(); - return ret; + _polygons.append(polygon); + _boundingRect |= polygon.boundingRect(); } + void setName(const QString &name) {_name = name;} + void setDescription(const QString &desc) {_desc = desc;} + private: + QList _polygons; QString _name; QString _desc; + RectC _boundingRect; }; #endif // AREA_H diff --git a/src/data/geojsonparser.cpp b/src/data/geojsonparser.cpp index c0086831..aab365c6 100644 --- a/src/data/geojsonparser.cpp +++ b/src/data/geojsonparser.cpp @@ -172,8 +172,12 @@ bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area, && properties["description"].isString()) area.setDescription(properties["description"].toString()); - area.append(::Polygon()); - return polygon(coordinates, area.last()); + ::Polygon p; + if (!polygon(coordinates, p)) + return false; + area.append(p); + + return true; } bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates, @@ -192,9 +196,10 @@ bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates, _errorString = "Invalid MultiPolygon coordinates"; return false; } else { - area.append(::Polygon()); - if (!polygon(coordinates.at(i).toArray(), area.last())) + ::Polygon p; + if (!polygon(coordinates.at(i).toArray(), p)) return false; + area.append(p); } } diff --git a/src/data/gpxparser.cpp b/src/data/gpxparser.cpp index 2d7f6e71..30a9c645 100644 --- a/src/data/gpxparser.cpp +++ b/src/data/gpxparser.cpp @@ -293,9 +293,7 @@ void GPXParser::track(TrackData &track) void GPXParser::area(Area &area) { - area.append(Polygon()); - area.last().append(QVector()); - QVector &points = area.last().last(); + QVector points; while (_reader.readNextStartElement()) { if (_reader.name() == QLatin1String("point")) { @@ -312,6 +310,8 @@ void GPXParser::area(Area &area) else _reader.skipCurrentElement(); } + + area.append(points); } void GPXParser::gpxExtensions(QList &areas) diff --git a/src/data/kmlparser.cpp b/src/data/kmlparser.cpp index a49a9263..56eb0cd2 100644 --- a/src/data/kmlparser.cpp +++ b/src/data/kmlparser.cpp @@ -263,8 +263,7 @@ void KMLParser::boundary(QVector &coordinates) void KMLParser::polygon(Area &area) { - area.append(Polygon()); - Polygon &polygon = area.last(); + Polygon polygon; while (_reader.readNextStartElement()) { if (_reader.name() == QLatin1String("outerBoundaryIs")) { @@ -284,6 +283,8 @@ void KMLParser::polygon(Area &area) } else _reader.skipCurrentElement(); } + + area.append(polygon); } void KMLParser::point(Waypoint &waypoint) diff --git a/src/data/polygon.cpp b/src/data/polygon.cpp deleted file mode 100644 index d6235c1f..00000000 --- a/src/data/polygon.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "polygon.h" - -RectC Polygon::boundingRect() const -{ - if (isEmpty()) - return RectC(); - if (first().size() < 3) - return RectC(); - - RectC rect; - for (int i = 0; i < first().size(); i++) - rect = rect.united(first().at(i)); - - return rect; -} diff --git a/src/data/polygon.h b/src/data/polygon.h index c9885aaa..3a9b100b 100644 --- a/src/data/polygon.h +++ b/src/data/polygon.h @@ -9,9 +9,30 @@ class Polygon : public QList > { public: - bool isValid() const {return !isEmpty() && first().size() >= 3;} + Polygon() {} + Polygon(const QVector &c) + { + reserve(1); + append(c); + } - RectC boundingRect() const; + bool isValid() const + { + return !isEmpty() && first().size() >= 3; + } + + RectC boundingRect() const + { + RectC rect; + + if (isEmpty() || first().size() < 3) + return rect; + + for (int i = 0; i < first().size(); i++) + rect = rect.united(first().at(i)); + + return rect; + } }; #endif // POLYGON_H