1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-27 21:24:47 +01:00

Do not repeatedly compute the areas bounds

This commit is contained in:
Martin Tůma 2021-03-07 11:58:21 +01:00
parent 68f67425c3
commit cdc71e2856
8 changed files with 66 additions and 45 deletions

View File

@ -347,7 +347,6 @@ SOURCES += src/main.cpp \
src/data/locparser.cpp \ src/data/locparser.cpp \
src/data/slfparser.cpp \ src/data/slfparser.cpp \
src/data/dem.cpp \ src/data/dem.cpp \
src/data/polygon.cpp \
src/map/obliquestereographic.cpp \ src/map/obliquestereographic.cpp \
src/GUI/coordinatesitem.cpp \ src/GUI/coordinatesitem.cpp \
src/map/rmap.cpp \ src/map/rmap.cpp \

View File

@ -67,8 +67,8 @@ void AreaItem::updatePainterPath()
{ {
_painterPath = QPainterPath(); _painterPath = QPainterPath();
for (int i = 0; i < _area.size(); i++) for (int i = 0; i < _area.polygons().size(); i++)
_painterPath.addPath(painterPath(_area.at(i))); _painterPath.addPath(painterPath(_area.polygons().at(i)));
} }
void AreaItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void AreaItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,

View File

@ -5,48 +5,58 @@
#include <QList> #include <QList>
#include "polygon.h" #include "polygon.h"
class Area : public QList<Polygon> class Area
{ {
public: public:
Area() {} Area() {}
Area(const RectC &rect) Area(const RectC &rect)
{ {
Polygon polygon;
QVector<Coordinates> v(4); QVector<Coordinates> v(4);
v[0] = Coordinates(rect.left(), rect.top()); v[0] = Coordinates(rect.left(), rect.top());
v[1] = Coordinates(rect.right(), rect.top()); v[1] = Coordinates(rect.right(), rect.top());
v[2] = Coordinates(rect.right(), rect.bottom()); v[2] = Coordinates(rect.right(), rect.bottom());
v[3] = Coordinates(rect.left(), 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 &name() const {return _name;}
const QString& description() const {return _desc;} const QString &description() const {return _desc;}
void setName(const QString &name) {_name = name;} const QList<Polygon> &polygons() const {return _polygons;}
void setDescription(const QString &desc) {_desc = desc;} const RectC &boundingRect() const {return _boundingRect;}
bool isValid() const bool isValid() const
{ {
if (isEmpty()) if (_polygons.isEmpty())
return false; return false;
for (int i = 0; i < size(); i++) for (int i = 0; i < _polygons.size(); i++)
if (!at(i).isValid()) if (!_polygons.at(i).isValid())
return false; return false;
return true; return true;
} }
RectC boundingRect() const void append(const Polygon &polygon)
{ {
RectC ret; _polygons.append(polygon);
for (int i = 0; i < size(); i++) _boundingRect |= polygon.boundingRect();
ret |= at(i).boundingRect();
return ret;
} }
void setName(const QString &name) {_name = name;}
void setDescription(const QString &desc) {_desc = desc;}
private: private:
QList<Polygon> _polygons;
QString _name; QString _name;
QString _desc; QString _desc;
RectC _boundingRect;
}; };
#endif // AREA_H #endif // AREA_H

View File

@ -172,8 +172,12 @@ bool GeoJSONParser::polygon(const QJsonArray &coordinates, Area &area,
&& properties["description"].isString()) && properties["description"].isString())
area.setDescription(properties["description"].toString()); area.setDescription(properties["description"].toString());
area.append(::Polygon()); ::Polygon p;
return polygon(coordinates, area.last()); if (!polygon(coordinates, p))
return false;
area.append(p);
return true;
} }
bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates, bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates,
@ -192,9 +196,10 @@ bool GeoJSONParser::multiPolygon(const QJsonArray &coordinates,
_errorString = "Invalid MultiPolygon coordinates"; _errorString = "Invalid MultiPolygon coordinates";
return false; return false;
} else { } else {
area.append(::Polygon()); ::Polygon p;
if (!polygon(coordinates.at(i).toArray(), area.last())) if (!polygon(coordinates.at(i).toArray(), p))
return false; return false;
area.append(p);
} }
} }

View File

@ -293,9 +293,7 @@ void GPXParser::track(TrackData &track)
void GPXParser::area(Area &area) void GPXParser::area(Area &area)
{ {
area.append(Polygon()); QVector<Coordinates> points;
area.last().append(QVector<Coordinates>());
QVector<Coordinates> &points = area.last().last();
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("point")) { if (_reader.name() == QLatin1String("point")) {
@ -312,6 +310,8 @@ void GPXParser::area(Area &area)
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
area.append(points);
} }
void GPXParser::gpxExtensions(QList<Area> &areas) void GPXParser::gpxExtensions(QList<Area> &areas)

View File

@ -263,8 +263,7 @@ void KMLParser::boundary(QVector<Coordinates> &coordinates)
void KMLParser::polygon(Area &area) void KMLParser::polygon(Area &area)
{ {
area.append(Polygon()); Polygon polygon;
Polygon &polygon = area.last();
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("outerBoundaryIs")) { if (_reader.name() == QLatin1String("outerBoundaryIs")) {
@ -284,6 +283,8 @@ void KMLParser::polygon(Area &area)
} else } else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
area.append(polygon);
} }
void KMLParser::point(Waypoint &waypoint) void KMLParser::point(Waypoint &waypoint)

View File

@ -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;
}

View File

@ -9,9 +9,30 @@
class Polygon : public QList<QVector<Coordinates> > class Polygon : public QList<QVector<Coordinates> >
{ {
public: public:
bool isValid() const {return !isEmpty() && first().size() >= 3;} Polygon() {}
Polygon(const QVector<Coordinates> &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 #endif // POLYGON_H