1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 03:35:53 +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/cadencegraph.cpp \
src/powergraph.cpp \
src/igcparser.cpp
src/igcparser.cpp \
src/path.cpp
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts
macx {

View File

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

View File

@ -29,7 +29,7 @@ private:
};
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>

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 "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

View File

@ -26,7 +26,6 @@ PathItem::PathItem(QGraphicsItem *parent) : QGraphicsObject(parent)
_pen = QPen(brush, PATH_WIDTH);
_units = Metric;
_distance = 0;
_marker = new MarkerItem(this);
@ -72,13 +71,46 @@ void PathItem::setUnits(enum 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)
{
if (distance > _distance)
if (distance > _distance.last())
_marker->setVisible(false);
else {
_marker->setVisible(true);
_marker->setPos(_path.pointAtPercent(distance / _distance));
_marker->setPos(position(distance));
}
}

View File

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

View File

@ -4,13 +4,16 @@
#include <QVector>
#include "routedata.h"
#include "graph.h"
#include "path.h"
class Route
{
public:
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;
qreal distance() const;

View File

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

View File

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

View File

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