1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Fixed path marker inaccuracy issue.

This commit is contained in:
Martin Tůma 2016-11-14 22:12:43 +01:00
parent 367427b26a
commit eb5692a0ab
11 changed files with 86 additions and 20 deletions

View File

@ -118,7 +118,8 @@ SOURCES += src/main.cpp \
src/graph.cpp \ src/graph.cpp \
src/cadencegraph.cpp \ src/cadencegraph.cpp \
src/powergraph.cpp \ src/powergraph.cpp \
src/igcparser.cpp src/igcparser.cpp \
src/path.cpp
RESOURCES += gpxsee.qrc RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts TRANSLATIONS = lang/gpxsee_cs.ts
macx { macx {

View File

@ -1,9 +1,9 @@
#include "graph.h" #include "graph.h"
QDebug operator<<(QDebug dbg, const GraphPoint &graphpoint) QDebug operator<<(QDebug dbg, const GraphPoint &point)
{ {
dbg.nospace() << "GraphPoint(" << graphpoint.s() << ", " dbg.nospace() << "GraphPoint(" << point.s() << ", " << point.t() << ", "
<< graphpoint.t() << ", " << graphpoint.y() << ")"; << point.y() << ")";
return dbg.maybeSpace(); return dbg.maybeSpace();
} }

View File

@ -29,7 +29,7 @@ private:
}; };
Q_DECLARE_TYPEINFO(GraphPoint, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(GraphPoint, Q_PRIMITIVE_TYPE);
QDebug operator<<(QDebug dbg, const GraphPoint &graphpoint); QDebug operator<<(QDebug dbg, const GraphPoint &point);
class Graph : public QVector<GraphPoint> class Graph : public QVector<GraphPoint>

9
src/path.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "path.h"
QDebug operator<<(QDebug dbg, const PathPoint &point)
{
dbg.nospace() << "PathPoint(" << point.distance() << ", "
<< point.coordinates() << ")";
return dbg.maybeSpace();
}

View File

@ -4,6 +4,25 @@
#include <QVector> #include <QVector>
#include "coordinates.h" #include "coordinates.h"
typedef QVector<Coordinates> Path; class PathPoint
{
public:
PathPoint() :
_coordinates(Coordinates()), _distance(NAN) {}
PathPoint(const Coordinates &coordinates, qreal distance)
: _coordinates(coordinates), _distance(distance) {}
const Coordinates &coordinates() const {return _coordinates;}
qreal distance() const {return _distance;}
private:
Coordinates _coordinates;
qreal _distance;
};
Q_DECLARE_TYPEINFO(PathPoint, Q_PRIMITIVE_TYPE);
QDebug operator<<(QDebug dbg, const PathPoint &point);
typedef QVector<PathPoint> Path;
#endif // PATH_H #endif // PATH_H

View File

@ -26,7 +26,6 @@ PathItem::PathItem(QGraphicsItem *parent) : QGraphicsObject(parent)
_pen = QPen(brush, PATH_WIDTH); _pen = QPen(brush, PATH_WIDTH);
_units = Metric; _units = Metric;
_distance = 0;
_marker = new MarkerItem(this); _marker = new MarkerItem(this);
@ -72,13 +71,46 @@ void PathItem::setUnits(enum Units units)
_units = units; _units = units;
} }
QPointF PathItem::position(qreal x) const
{
int low = 0;
int high = _distance.count() - 1;
int mid = 0;
Q_ASSERT(high > low);
Q_ASSERT(x >= _distance.at(low) && x <= _distance.at(high));
while (low <= high) {
mid = low + ((high - low) / 2);
qreal val = _distance.at(mid);
if (val > x)
high = mid - 1;
else if (val < x)
low = mid + 1;
else
return _path.elementAt(mid);
}
QLineF l;
qreal p1, p2;
if (_distance.at(mid) < x) {
l = QLineF(_path.elementAt(mid), _path.elementAt(mid+1));
p1 = _distance.at(mid); p2 = _distance.at(mid+1);
} else {
l = QLineF(_path.elementAt(mid-1), _path.elementAt(mid));
p1 = _distance.at(mid-1); p2 = _distance.at(mid);
}
return l.pointAt((x - p1) / (p2 - p1));
}
void PathItem::moveMarker(qreal distance) void PathItem::moveMarker(qreal distance)
{ {
if (distance > _distance) if (distance > _distance.last())
_marker->setVisible(false); _marker->setVisible(false);
else { else {
_marker->setVisible(true); _marker->setVisible(true);
_marker->setPos(_path.pointAtPercent(distance / _distance)); _marker->setPos(position(distance));
} }
} }

View File

@ -34,6 +34,7 @@ signals:
protected: protected:
void updateShape(); void updateShape();
QVector<qreal> _distance;
QPainterPath _path; QPainterPath _path;
QPainterPath _shape; QPainterPath _shape;
QPen _pen; QPen _pen;
@ -41,9 +42,10 @@ protected:
MarkerItem *_marker; MarkerItem *_marker;
Units _units; Units _units;
qreal _distance;
private: private:
QPointF position(qreal distance) const;
void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
}; };

View File

@ -4,13 +4,16 @@
#include <QVector> #include <QVector>
#include "routedata.h" #include "routedata.h"
#include "graph.h" #include "graph.h"
#include "path.h"
class Route class Route
{ {
public: public:
Route(const RouteData &data); Route(const RouteData &data);
const RouteData &route() const {return _data;} const RouteData &routeData() const {return _data;}
const QVector<qreal> &distanceData() const {return _distance;}
Graph elevation() const; Graph elevation() const;
qreal distance() const; qreal distance() const;

View File

@ -16,7 +16,7 @@ QString RouteItem::toolTip()
if (!_desc.isEmpty()) if (!_desc.isEmpty())
tt.insert(qApp->translate("RouteItem", "Description"), _desc); tt.insert(qApp->translate("RouteItem", "Description"), _desc);
tt.insert(qApp->translate("RouteItem", "Distance"), tt.insert(qApp->translate("RouteItem", "Distance"),
Format::distance(_distance, _units)); Format::distance(_distance.last(), _units));
return tt.toString(); return tt.toString();
} }
@ -24,12 +24,13 @@ QString RouteItem::toolTip()
RouteItem::RouteItem(const Route &route, QGraphicsItem *parent) RouteItem::RouteItem(const Route &route, QGraphicsItem *parent)
: PathItem(parent) : PathItem(parent)
{ {
const RouteData &r = route.route(); const RouteData &r = route.routeData();
Q_ASSERT(r.count() >= 2); Q_ASSERT(r.count() >= 2);
QPointF p; QPointF p;
_name = r.name(); _name = r.name();
_desc = r.description(); _desc = r.description();
_distance = route.distanceData();
new WaypointItem(r.at(0), this); new WaypointItem(r.at(0), this);
p = r.at(0).coordinates().toMercator(); p = r.at(0).coordinates().toMercator();
@ -42,8 +43,6 @@ RouteItem::RouteItem(const Route &route, QGraphicsItem *parent)
updateShape(); updateShape();
_distance = route.distance();
_marker->setPos(_path.pointAtPercent(0)); _marker->setPos(_path.pointAtPercent(0));
_pen.setStyle(Qt::DotLine); _pen.setStyle(Qt::DotLine);

View File

@ -219,7 +219,7 @@ Path Track::path() const
for (int i = 0; i < _data.size(); i++) for (int i = 0; i < _data.size(); i++)
if (!_outliers.contains(i)) if (!_outliers.contains(i))
ret.append(_data.at(i).coordinates()); ret.append(PathPoint(_data.at(i).coordinates(), _distance.at(i)));
return ret; return ret;
} }

View File

@ -15,7 +15,7 @@ QString TrackItem::toolTip()
if (!_desc.isEmpty()) if (!_desc.isEmpty())
tt.insert(qApp->translate("TrackItem", "Description"), _desc); tt.insert(qApp->translate("TrackItem", "Description"), _desc);
tt.insert(qApp->translate("TrackItem", "Distance"), tt.insert(qApp->translate("TrackItem", "Distance"),
Format::distance(_distance, _units)); Format::distance(_distance.last(), _units));
if (_time > 0) if (_time > 0)
tt.insert(qApp->translate("TrackItem", "Time"), tt.insert(qApp->translate("TrackItem", "Time"),
Format::timeSpan(_time)); Format::timeSpan(_time));
@ -33,11 +33,13 @@ TrackItem::TrackItem(const Track &track, QGraphicsItem *parent)
const Path &path = track.path(); const Path &path = track.path();
Q_ASSERT(path.count() >= 2); Q_ASSERT(path.count() >= 2);
p = path.first().toMercator(); p = path.first().coordinates().toMercator();
_path.moveTo(QPointF(p.x(), -p.y())); _path.moveTo(QPointF(p.x(), -p.y()));
_distance.append(path.first().distance());
for (int i = 1; i < path.size(); i++) { for (int i = 1; i < path.size(); i++) {
p = path.at(i).toMercator(); p = path.at(i).coordinates().toMercator();
_path.lineTo(QPointF(p.x(), -p.y())); _path.lineTo(QPointF(p.x(), -p.y()));
_distance.append(path.at(i).distance());
} }
updateShape(); updateShape();
@ -45,7 +47,6 @@ TrackItem::TrackItem(const Track &track, QGraphicsItem *parent)
_name = track.name(); _name = track.name();
_desc = track.description(); _desc = track.description();
_date = track.date(); _date = track.date();
_distance = track.distance();
_time = track.time(); _time = track.time();
_marker->setPos(_path.pointAtPercent(0)); _marker->setPos(_path.pointAtPercent(0));