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

Added coordinates checking to file parsers

Refactoring
This commit is contained in:
Martin Tůma 2016-10-24 00:21:40 +02:00
parent 375ef20592
commit 27194d3d36
28 changed files with 288 additions and 221 deletions

View File

@ -10,7 +10,6 @@ HEADERS += src/config.h \
src/gui.h \ src/gui.h \
src/poi.h \ src/poi.h \
src/rtree.h \ src/rtree.h \
src/ll.h \
src/axisitem.h \ src/axisitem.h \
src/keys.h \ src/keys.h \
src/slideritem.h \ src/slideritem.h \
@ -56,11 +55,14 @@ HEADERS += src/config.h \
src/gpxparser.h \ src/gpxparser.h \
src/tcxparser.h \ src/tcxparser.h \
src/parser.h \ src/parser.h \
src/csvparser.h src/csvparser.h \
src/coordinates.h \
src/tile.h \
src/rd.h \
src/wgs84.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/gui.cpp \ src/gui.cpp \
src/poi.cpp \ src/poi.cpp \
src/ll.cpp \
src/axisitem.cpp \ src/axisitem.cpp \
src/slideritem.cpp \ src/slideritem.cpp \
src/markeritem.cpp \ src/markeritem.cpp \
@ -98,7 +100,8 @@ SOURCES += src/main.cpp \
src/data.cpp \ src/data.cpp \
src/gpxparser.cpp \ src/gpxparser.cpp \
src/tcxparser.cpp \ src/tcxparser.cpp \
src/csvparser.cpp src/csvparser.cpp \
src/coordinates.cpp
RESOURCES += gpxsee.qrc RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts TRANSLATIONS = lang/gpxsee_cs.ts
macx { macx {

42
src/coordinates.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "rd.h"
#include "wgs84.h"
#include "coordinates.h"
bool Coordinates::isValid() const
{
return (_lon >= -180.0 && _lon <= 180.0 && _lat >= -90.0 && _lat <= 90.0)
? true : false;
}
qreal Coordinates::distanceTo(const Coordinates &c) const
{
qreal dLat = deg2rad(c.lat() - _lat);
qreal dLon = deg2rad(c.lon() - _lon);
qreal a = pow(sin(dLat / 2.0), 2.0)
+ cos(deg2rad(_lat)) * cos(deg2rad(c.lat())) * pow(sin(dLon / 2.0), 2.0);
return (WGS84_RADIUS * (2.0 * atan2(sqrt(a), sqrt(1.0 - a))));
}
QPointF Coordinates::toMercator() const
{
return QPointF(_lon, rad2deg(log(tan(M_PI/4.0 + deg2rad(_lat)/2.0))));
}
Coordinates Coordinates::fromMercator(const QPointF &m)
{
return Coordinates(m.x(), rad2deg(2 * atan(exp(deg2rad(m.y()))) - M_PI/2));
}
bool operator==(const Coordinates &c1, const Coordinates &c2)
{
return (c1.lat() == c2.lat() && c1.lon() == c2.lon());
}
QDebug operator<<(QDebug dbg, const Coordinates &coordinates)
{
dbg.nospace() << "Coordinates(" << coordinates.lon() << ", "
<< coordinates.lat() << ")";
return dbg.maybeSpace();
}

35
src/coordinates.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef COORDINATES_H
#define COORDINATES_H
#include <cmath>
#include <QPointF>
#include <QDebug>
class Coordinates
{
public:
Coordinates() {_lon = NAN; _lat = NAN;}
Coordinates(const Coordinates &c) {_lon = c._lon; _lat = c._lat;}
Coordinates(qreal lon, qreal lat) {_lon = lon; _lat = lat;}
qreal &rLon() {return _lon;}
qreal &rLat() {return _lat;}
void setLon(qreal lon) {_lon = lon;}
void setLat(qreal lat) {_lat = lat;}
qreal lon() const {return _lon;}
qreal lat() const {return _lat;}
bool isValid() const;
qreal distanceTo(const Coordinates &c) const;
QPointF toMercator() const;
static Coordinates fromMercator(const QPointF &m);
private:
qreal _lat, _lon;
};
bool operator==(const Coordinates &c1, const Coordinates &c2);
QDebug operator<<(QDebug dbg, const Coordinates &trackpoint);
#endif // COORDINATES_H

View File

@ -29,7 +29,7 @@ bool CSVParser::loadFile(QIODevice *device)
_errorLine = ln; _errorLine = ln;
return false; return false;
} }
Waypoint wp(QPointF(lon, lat)); Waypoint wp(Coordinates(lon, lat));
QByteArray ba = list[2].trimmed(); QByteArray ba = list[2].trimmed();
QString name = QString::fromUtf8(ba.data(), ba.size()); QString name = QString::fromUtf8(ba.data(), ba.size());

View File

@ -1,6 +1,5 @@
#include <QFile> #include <QFile>
#include <QLineF> #include <QLineF>
#include "ll.h"
#include "gpxparser.h" #include "gpxparser.h"
#include "tcxparser.h" #include "tcxparser.h"
#include "csvparser.h" #include "csvparser.h"

View File

@ -76,25 +76,38 @@ void GPXParser::handleRoutepointData(DataType type, const QString &value)
} }
} }
Coordinates GPXParser::coordinates(const QXmlStreamAttributes &attr)
{
bool res;
qreal lon, lat;
lon = attr.value("lon").toDouble(&res);
if (!res || (lon < -180.0 || lon > 180.0)) {
_reader.raiseError("Invalid longitude.");
return Coordinates();
}
lat = attr.value("lat").toDouble(&res);
if (!res || (lat < -90.0 || lat > 90.0)) {
_reader.raiseError("Invalid latitude.");
return Coordinates();
}
return Coordinates(lon, lat);
}
void GPXParser::handleTrackpointAttributes(const QXmlStreamAttributes &attr) void GPXParser::handleTrackpointAttributes(const QXmlStreamAttributes &attr)
{ {
_track->last().setCoordinates(QPointF( _track->last().setCoordinates(coordinates(attr));
attr.value("lon").toDouble(),
attr.value("lat").toDouble()));
} }
void GPXParser::handleRoutepointAttributes(const QXmlStreamAttributes &attr) void GPXParser::handleRoutepointAttributes(const QXmlStreamAttributes &attr)
{ {
_route->last().setCoordinates(QPointF( _route->last().setCoordinates(coordinates(attr));
attr.value("lon").toDouble(),
attr.value("lat").toDouble()));
} }
void GPXParser::handleWaypointAttributes(const QXmlStreamAttributes &attr) void GPXParser::handleWaypointAttributes(const QXmlStreamAttributes &attr)
{ {
_waypoints.last().setCoordinates(QPointF( _waypoints.last().setCoordinates(coordinates(attr));
attr.value("lon").toDouble(),
attr.value("lat").toDouble()));
} }
void GPXParser::tpExtension() void GPXParser::tpExtension()

View File

@ -36,6 +36,8 @@ private:
void routepointData(); void routepointData();
void waypointData(); void waypointData();
Coordinates coordinates(const QXmlStreamAttributes &attr);
void handleWaypointAttributes(const QXmlStreamAttributes &attr); void handleWaypointAttributes(const QXmlStreamAttributes &attr);
void handleWaypointData(DataType type, const QString &value); void handleWaypointData(DataType type, const QString &value);
void handleTrackpointAttributes(const QXmlStreamAttributes &attr); void handleTrackpointAttributes(const QXmlStreamAttributes &attr);

View File

@ -1,86 +0,0 @@
#include <cmath>
#include "ll.h"
// MSVC workarounds
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif // M_PI
#if defined(_MSC_VER) && (_MSC_VER < 1800)
#define log2(n) (log(n)/log(2.0))
#endif
#define WGS84_RADIUS 6378137.0
#define deg2rad(d) (((d)*M_PI)/180.0)
#define rad2deg(d) (((d)*180.0)/M_PI)
qreal llDistance(const QPointF &p1, const QPointF &p2)
{
qreal dLat = deg2rad(p2.y() - p1.y());
qreal dLon = deg2rad(p2.x() - p1.x());
qreal a = pow(sin(dLat / 2.0), 2.0)
+ cos(deg2rad(p1.y())) * cos(deg2rad(p2.y())) * pow(sin(dLon / 2.0), 2.0);
qreal c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
return (WGS84_RADIUS * c);
}
QPointF ll2mercator(const QPointF &ll)
{
QPointF m;
m.setX(ll.x());
m.setY(rad2deg(log(tan(M_PI/4.0 + deg2rad(ll.y())/2.0))));
return m;
}
QPointF mercator2ll(const QPointF &m)
{
QPointF ll;
ll.setX(m.x());
ll.setY(rad2deg(2 * atan(exp(deg2rad(m.y()))) - M_PI/2));
return ll;
}
QPoint mercator2tile(const QPointF &m, int z)
{
QPoint tile;
tile.setX((int)(floor((m.x() + 180.0) / 360.0 * pow(2.0, z))));
tile.setY((int)(floor((1.0 - (m.y() / 180.0)) / 2.0 * pow(2.0, z))));
return tile;
}
QPointF tile2mercator(const QPoint &tile, int z)
{
QPointF m;
m.setX(tile.x() / pow(2.0, z) * 360.0 - 180);
qreal n = M_PI - 2.0 * M_PI * tile.y() / pow(2.0, z);
m.setY(rad2deg(atan(0.5 * (exp(n) - exp(-n)))));
return ll2mercator(m);
}
int scale2zoom(qreal scale)
{
int zoom;
zoom = (int)log2(360.0/(scale * (qreal)TILE_SIZE));
if (zoom < ZOOM_MIN)
return ZOOM_MIN;
if (zoom > ZOOM_MAX)
return ZOOM_MAX;
return zoom;
}
qreal zoom2resolution(int zoom, qreal y)
{
return (WGS84_RADIUS * 2 * M_PI / 256 * cos(2 * atan(exp(deg2rad(y)))
- M_PI/2)) / pow(2.0, zoom);
}

View File

@ -1,18 +0,0 @@
#ifndef LL_H
#define LL_H
#include <QPointF>
#define TILE_SIZE 256
#define ZOOM_MAX 18
#define ZOOM_MIN 3
QPointF ll2mercator(const QPointF &ll);
QPointF mercator2ll(const QPointF &m);
qreal llDistance(const QPointF &p1, const QPointF &p2);
QPoint mercator2tile(const QPointF &m, int zoom);
QPointF tile2mercator(const QPoint &tile, int zoom);
int scale2zoom(qreal scale);
qreal zoom2resolution(int zoom, qreal y);
#endif // LL_H

View File

@ -1,7 +1,6 @@
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
#include "downloader.h" #include "downloader.h"
#include "ll.h"
#include "config.h" #include "config.h"
#include "map.h" #include "map.h"
@ -91,7 +90,7 @@ void Map::loadTilesSync(QList<Tile> &list)
void Map::fillTile(Tile &tile) void Map::fillTile(Tile &tile)
{ {
tile.pixmap() = QPixmap(TILE_SIZE, TILE_SIZE); tile.pixmap() = QPixmap(Tile::size(), Tile::size());
tile.pixmap().fill(); tile.pixmap().fill();
} }

View File

@ -1,24 +1,7 @@
#ifndef MAP_H #ifndef MAP_H
#define MAP_H #define MAP_H
#include <QPixmap> #include "tile.h"
class Tile
{
public:
Tile(const QPoint &xy, int zoom)
{_xy = xy; _zoom = zoom;}
int zoom() const {return _zoom;}
const QPoint& xy() const {return _xy;}
QPixmap& pixmap() {return _pixmap;}
private:
int _zoom;
QPoint _xy;
QPixmap _pixmap;
};
class Map : public QObject class Map : public QObject
{ {

View File

@ -76,11 +76,11 @@ QString elevation(qreal value, Units units)
+ qApp->translate("Misc", "ft"); + qApp->translate("Misc", "ft");
} }
QString coordinates(const QPointF &value) QString coordinates(const Coordinates &value)
{ {
QChar yH = (value.y() < 0) ? 'S' : 'N'; QChar yH = (value.lat() < 0) ? 'S' : 'N';
QChar xH = (value.x() < 0) ? 'W' : 'E'; QChar xH = (value.lon() < 0) ? 'W' : 'E';
return QString::number(qAbs(value.y()), 'f', 5) + yH + "," + QChar(0x00A0) return QString::number(qAbs(value.lat()), 'f', 5) + yH + "," + QChar(0x00A0)
+ QString::number(qAbs(value.x()), 'f', 5) + xH; + QString::number(qAbs(value.lon()), 'f', 5) + xH;
} }

View File

@ -3,6 +3,7 @@
#include <QString> #include <QString>
#include <QPoint> #include <QPoint>
#include "coordinates.h"
#include "units.h" #include "units.h"
double niceNum(double x, int round); double niceNum(double x, int round);
@ -10,6 +11,6 @@ double niceNum(double x, int round);
QString timeSpan(qreal time); QString timeSpan(qreal time);
QString distance(qreal value, Units units); QString distance(qreal value, Units units);
QString elevation(qreal value, Units units); QString elevation(qreal value, Units units);
QString coordinates(const QPointF &value); QString coordinates(const Coordinates &value);
#endif // MISC_H #endif // MISC_H

View File

@ -1,7 +1,7 @@
#include <QGraphicsView> #include <QGraphicsView>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QWheelEvent> #include <QWheelEvent>
#include "ll.h" #include "rd.h"
#include "poi.h" #include "poi.h"
#include "data.h" #include "data.h"
#include "map.h" #include "map.h"
@ -12,8 +12,43 @@
#include "pathview.h" #include "pathview.h"
#define MARGIN 10.0 #define ZOOM_MAX 18
#define SCALE_OFFSET 7 #define ZOOM_MIN 3
#define MARGIN 10.0
#define SCALE_OFFSET 7
static QPoint mercator2tile(const QPointF &m, int z)
{
QPoint tile;
tile.setX((int)(floor((m.x() + 180.0) / 360.0 * pow(2.0, z))));
tile.setY((int)(floor((1.0 - (m.y() / 180.0)) / 2.0 * pow(2.0, z))));
return tile;
}
static QPointF tile2mercator(const QPoint &tile, int z)
{
Coordinates m;
m.setLon(tile.x() / pow(2.0, z) * 360.0 - 180);
qreal n = M_PI - 2.0 * M_PI * tile.y() / pow(2.0, z);
m.setLat(rad2deg(atan(0.5 * (exp(n) - exp(-n)))));
return m.toMercator();
}
static int scale2zoom(qreal scale)
{
int zoom = (int)log2(360.0/(scale * (qreal)Tile::size()));
if (zoom < ZOOM_MIN)
return ZOOM_MIN;
if (zoom > ZOOM_MAX)
return ZOOM_MAX;
return zoom;
}
PathView::PathView(QWidget *parent) PathView::PathView(QWidget *parent)
: QGraphicsView(parent) : QGraphicsView(parent)
@ -147,7 +182,8 @@ QList<PathItem *> PathView::loadData(const Data &data)
QRectF br = trackBoundingRect() | routeBoundingRect() QRectF br = trackBoundingRect() | routeBoundingRect()
| waypointBoundingRect(); | waypointBoundingRect();
QRectF ba = br.adjusted(-TILE_SIZE, -TILE_SIZE, TILE_SIZE, TILE_SIZE); QRectF ba = br.adjusted(-Tile::size(), -Tile::size(), Tile::size(),
Tile::size());
_scene->setSceneRect(ba); _scene->setSceneRect(ba);
centerOn(ba.center()); centerOn(ba.center());
@ -268,7 +304,7 @@ qreal PathView::waypointScale() const
qreal PathView::mapScale(int zoom) const qreal PathView::mapScale(int zoom) const
{ {
return ((360.0/(qreal)(1<<zoom))/(qreal)TILE_SIZE); return ((360.0/(qreal)(1<<zoom))/(qreal)Tile::size());
} }
void PathView::updatePOIVisibility() void PathView::updatePOIVisibility()
@ -422,7 +458,8 @@ void PathView::zoom(int z, const QPointF &pos)
rescale(mapScale(_zoom)); rescale(mapScale(_zoom));
QRectF br = trackBoundingRect() | routeBoundingRect() QRectF br = trackBoundingRect() | routeBoundingRect()
| waypointBoundingRect(); | waypointBoundingRect();
QRectF ba = br.adjusted(-TILE_SIZE, -TILE_SIZE, TILE_SIZE, TILE_SIZE); QRectF ba = br.adjusted(-Tile::size(), -Tile::size(), Tile::size(),
Tile::size());
_scene->setSceneRect(ba); _scene->setSceneRect(ba);
if (br.width() < viewport()->size().width() if (br.width() < viewport()->size().width()
@ -603,8 +640,8 @@ void PathView::drawBackground(QPainter *painter, const QRectF &rect)
-tm.y() / _scale))).toPoint(); -tm.y() / _scale))).toPoint();
QList<Tile> tiles; QList<Tile> tiles;
for (int i = 0; i <= rr.size().width() / TILE_SIZE + 1; i++) { for (int i = 0; i <= rr.size().width() / Tile::size() + 1; i++) {
for (int j = 0; j <= rr.size().height() / TILE_SIZE + 1; j++) { for (int j = 0; j <= rr.size().height() / Tile::size() + 1; j++) {
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom)); tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
} }
} }
@ -613,8 +650,8 @@ void PathView::drawBackground(QPainter *painter, const QRectF &rect)
for (int i = 0; i < tiles.count(); i++) { for (int i = 0; i < tiles.count(); i++) {
Tile &t = tiles[i]; Tile &t = tiles[i];
QPoint tp(tl.x() + (t.xy().x() - tile.x()) * TILE_SIZE, QPoint tp(tl.x() + (t.xy().x() - tile.x()) * Tile::size(),
tl.y() + (t.xy().y() - tile.y()) * TILE_SIZE); tl.y() + (t.xy().y() - tile.y()) * Tile::size());
painter->drawPixmap(tp, t.pixmap()); painter->drawPixmap(tp, t.pixmap());
} }
} }
@ -628,7 +665,8 @@ void PathView::resizeEvent(QResizeEvent *e)
QRectF br = trackBoundingRect() | routeBoundingRect() QRectF br = trackBoundingRect() | routeBoundingRect()
| waypointBoundingRect(); | waypointBoundingRect();
QRectF ba = br.adjusted(-TILE_SIZE, -TILE_SIZE, TILE_SIZE, TILE_SIZE); QRectF ba = br.adjusted(-Tile::size(), -Tile::size(), Tile::size(),
Tile::size());
if (ba.width() < e->size().width()) { if (ba.width() < e->size().width()) {
qreal diff = e->size().width() - ba.width(); qreal diff = e->size().width() - ba.width();

View File

@ -3,7 +3,6 @@
#include <QList> #include <QList>
#include "pathitem.h" #include "pathitem.h"
#include "waypointitem.h" #include "waypointitem.h"
#include "ll.h"
#include "data.h" #include "data.h"
#include "poi.h" #include "poi.h"
@ -36,10 +35,10 @@ bool POI::loadFile(const QString &fileName)
index.end = _data.size() - 1; index.end = _data.size() - 1;
for (int i = index.start; i <= index.end; i++) { for (int i = index.start; i <= index.end; i++) {
const QPointF &p = _data.at(i).coordinates(); const Coordinates &p = _data.at(i).coordinates();
qreal c[2]; qreal c[2];
c[0] = p.x(); c[0] = p.lon();
c[1] = p.y(); c[1] = p.lat();
_tree.Insert(c, c, i); _tree.Insert(c, c, i);
} }
@ -67,11 +66,11 @@ QVector<Waypoint> POI::points(const PathItem *path) const
const QPainterPath &pp = path->path(); const QPainterPath &pp = path->path();
for (int i = 0; i < pp.elementCount(); i++) { for (int i = 0; i < pp.elementCount(); i++) {
QPointF p = mercator2ll(pp.elementAt(i)); Coordinates p = Coordinates::fromMercator(pp.elementAt(i));
min[0] = p.x() - _radius; min[0] = p.lon() - _radius;
min[1] = -p.y() - _radius; min[1] = -p.lat() - _radius;
max[0] = p.x() + _radius; max[0] = p.lon() + _radius;
max[1] = -p.y() + _radius; max[1] = -p.lat() + _radius;
_tree.Search(min, max, cb, &set); _tree.Search(min, max, cb, &set);
} }
@ -92,11 +91,11 @@ QVector<Waypoint> POI::points(const QList<WaypointItem*> &list)
qreal min[2], max[2]; qreal min[2], max[2];
for (int i = 0; i < list.count(); i++) { for (int i = 0; i < list.count(); i++) {
const QPointF &p = list.at(i)->waypoint().coordinates(); const Coordinates &p = list.at(i)->waypoint().coordinates();
min[0] = p.x() - _radius; min[0] = p.lon() - _radius;
min[1] = p.y() - _radius; min[1] = p.lat() - _radius;
max[0] = p.x() + _radius; max[0] = p.lon() + _radius;
max[1] = p.y() + _radius; max[1] = p.lat() + _radius;
_tree.Search(min, max, cb, &set); _tree.Search(min, max, cb, &set);
} }
@ -116,11 +115,11 @@ QVector<Waypoint> POI::points(const QList<Waypoint> &list) const
qreal min[2], max[2]; qreal min[2], max[2];
for (int i = 0; i < list.count(); i++) { for (int i = 0; i < list.count(); i++) {
const QPointF &p = list.at(i).coordinates(); const Coordinates &p = list.at(i).coordinates();
min[0] = p.x() - _radius; min[0] = p.lon() - _radius;
min[1] = p.y() - _radius; min[1] = p.lat() - _radius;
max[0] = p.x() + _radius; max[0] = p.lon() + _radius;
max[1] = p.y() + _radius; max[1] = p.lat() + _radius;
_tree.Search(min, max, cb, &set); _tree.Search(min, max, cb, &set);
} }
@ -148,10 +147,10 @@ void POI::enableFile(const QString &fileName, bool enable)
continue; continue;
for (int j = idx.start; j <= idx.end; j++) { for (int j = idx.start; j <= idx.end; j++) {
const QPointF &p = _data.at(j).coordinates(); const Coordinates &p = _data.at(j).coordinates();
qreal c[2]; qreal c[2];
c[0] = p.x(); c[0] = p.lon();
c[1] = p.y(); c[1] = p.lat();
_tree.Insert(c, c, j); _tree.Insert(c, c, j);
} }
} }

13
src/rd.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef RD_H
#define RD_H
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif // M_PI
#define deg2rad(d) (((d)*M_PI)/180.0)
#define rad2deg(d) (((d)*180.0)/M_PI)
#endif // RD_H

View File

@ -1,4 +1,3 @@
#include "ll.h"
#include "route.h" #include "route.h"
Route::Route(const QVector<Waypoint> &data) : _data(data) Route::Route(const QVector<Waypoint> &data) : _data(data)
@ -7,7 +6,7 @@ Route::Route(const QVector<Waypoint> &data) : _data(data)
_distance.append(dist); _distance.append(dist);
for (int i = 1; i < data.count(); i++) { for (int i = 1; i < data.count(); i++) {
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates()); dist += data.at(i).coordinates().distanceTo(data.at(i-1).coordinates());
_distance.append(dist); _distance.append(dist);
} }
} }

View File

@ -1,6 +1,5 @@
#include <QApplication> #include <QApplication>
#include <QPainter> #include <QPainter>
#include "ll.h"
#include "misc.h" #include "misc.h"
#include "waypoint.h" #include "waypoint.h"
#include "waypointitem.h" #include "waypointitem.h"
@ -23,13 +22,14 @@ RouteItem::RouteItem(const Route &route, QGraphicsItem *parent)
{ {
QVector<Waypoint> r = route.route(); QVector<Waypoint> r = route.route();
Q_ASSERT(r.count() >= 2); Q_ASSERT(r.count() >= 2);
QPointF p;
new WaypointItem(r.at(0), this); new WaypointItem(r.at(0), this);
const QPointF &p = r.at(0).coordinates(); p = r.at(0).coordinates().toMercator();
_path.moveTo(ll2mercator(QPointF(p.x(), -p.y()))); _path.moveTo(QPointF(p.x(), -p.y()));
for (int i = 1; i < r.size(); i++) { for (int i = 1; i < r.size(); i++) {
const QPointF &p = r.at(i).coordinates(); p = r.at(i).coordinates().toMercator();
_path.lineTo(ll2mercator(QPointF(p.x(), -p.y()))); _path.lineTo(QPointF(p.x(), -p.y()));
new WaypointItem(r.at(i), this); new WaypointItem(r.at(i), this);
} }

View File

@ -1,22 +1,28 @@
#include <QPainter> #include <QPainter>
#include "config.h" #include "config.h"
#include "ll.h" #include "rd.h"
#include "wgs84.h"
#include "tile.h"
#include "misc.h" #include "misc.h"
#include "scaleitem.h" #include "scaleitem.h"
#define BORDER_WIDTH 1 #define BORDER_WIDTH 1
#define SCALE_WIDTH 132 #define SCALE_WIDTH 132
#define SCALE_HEIGHT 5 #define SCALE_HEIGHT 5
#define SEGMENTS 3 #define SEGMENTS 3
#define PADDING 4
#define PADDING 4
static qreal zoom2resolution(int zoom, qreal y)
{
return (WGS84_RADIUS * 2 * M_PI / Tile::size()
* cos(2 * atan(exp(deg2rad(y))) - M_PI/2)) / pow(2.0, zoom);
}
ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent) ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{ {
_units = Metric; _units = Metric;
_zoom = ZOOM_MIN; _zoom = 0;
_lat = 0; _lat = 0;
#ifndef Q_OS_MAC #ifndef Q_OS_MAC

View File

@ -1,16 +1,26 @@
#include "tcxparser.h" #include "tcxparser.h"
QPointF TCXParser::position() Coordinates TCXParser::position()
{ {
QPointF pos; Coordinates pos;
qreal val;
bool res;
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "LatitudeDegrees") if (_reader.name() == "LatitudeDegrees") {
pos.setY(_reader.readElementText().toDouble()); val = _reader.readElementText().toDouble(&res);
else if (_reader.name() == "LongitudeDegrees") if (!res || (val < -90.0 || val > 90.0))
pos.setX(_reader.readElementText().toDouble()); _reader.raiseError("Invalid latitude.");
else else
pos.setLat(_reader.readElementText().toDouble(&res));
} else if (_reader.name() == "LongitudeDegrees") {
val = _reader.readElementText().toDouble(&res);
if (!res || (val < -180.0 || val > 180.0))
_reader.raiseError("Invalid longitude.");
else
pos.setLon(_reader.readElementText().toDouble(&res));
} else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }

View File

@ -32,7 +32,7 @@ private:
void trackpointData(); void trackpointData();
void routepointData(); void routepointData();
void waypointData(); void waypointData();
QPointF position(); Coordinates position();
QXmlStreamReader _reader; QXmlStreamReader _reader;
QVector<Trackpoint> *_track; QVector<Trackpoint> *_track;

25
src/tile.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef TILE_H
#define TILE_H
#include <QPixmap>
#include <QPoint>
class Tile
{
public:
Tile(const QPoint &xy, int zoom)
{_xy = xy; _zoom = zoom;}
int zoom() const {return _zoom;}
const QPoint& xy() const {return _xy;}
QPixmap& pixmap() {return _pixmap;}
static int size() {return 256;}
private:
int _zoom;
QPoint _xy;
QPixmap _pixmap;
};
#endif // TILE_H

View File

@ -1,4 +1,3 @@
#include "ll.h"
#include "track.h" #include "track.h"
@ -87,7 +86,7 @@ Track::Track(const QVector<Trackpoint> &data) : _data(data)
_distance.append(0); _distance.append(0);
_time.append(0); _time.append(0);
for (int i = 1; i < data.count(); i++) { for (int i = 1; i < data.count(); i++) {
dist += llDistance(data.at(i).coordinates(), data.at(i-1).coordinates()); dist += data.at(i).coordinates().distanceTo(data.at(i-1).coordinates());
_distance.append(dist); _distance.append(dist);
if (data.first().hasTimestamp() && data.at(i).hasTimestamp()) if (data.first().hasTimestamp() && data.at(i).hasTimestamp())

View File

@ -1,7 +1,6 @@
#include <QApplication> #include <QApplication>
#include <QCursor> #include <QCursor>
#include <QPainter> #include <QPainter>
#include "ll.h"
#include "misc.h" #include "misc.h"
#include "tooltip.h" #include "tooltip.h"
#include "trackitem.h" #include "trackitem.h"
@ -25,14 +24,15 @@ QString TrackItem::toolTip()
TrackItem::TrackItem(const Track &track, QGraphicsItem *parent) TrackItem::TrackItem(const Track &track, QGraphicsItem *parent)
: PathItem(parent) : PathItem(parent)
{ {
QPointF p;
const QVector<Trackpoint> &t = track.track(); const QVector<Trackpoint> &t = track.track();
Q_ASSERT(t.count() >= 2); Q_ASSERT(t.count() >= 2);
const QPointF &p = t.at(0).coordinates(); p = t.first().coordinates().toMercator();
_path.moveTo(ll2mercator(QPointF(p.x(), -p.y()))); _path.moveTo(QPointF(p.x(), -p.y()));
for (int i = 1; i < t.size(); i++) { for (int i = 1; i < t.size(); i++) {
const QPointF &p = t.at(i).coordinates(); p = t.at(i).coordinates().toMercator();
_path.lineTo(ll2mercator(QPointF(p.x(), -p.y()))); _path.lineTo(QPointF(p.x(), -p.y()));
} }
updateShape(); updateShape();

View File

@ -1,10 +1,10 @@
#ifndef TRACKPOINT_H #ifndef TRACKPOINT_H
#define TRACKPOINT_H #define TRACKPOINT_H
#include <QPointF>
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <cmath> #include <cmath>
#include "coordinates.h"
class Trackpoint class Trackpoint
{ {
@ -13,9 +13,9 @@ public:
_elevation = NAN; _geoidHeight = 0; _speed = NAN; _heartRate = NAN; _elevation = NAN; _geoidHeight = 0; _speed = NAN; _heartRate = NAN;
_temperature = NAN; _temperature = NAN;
} }
Trackpoint(const QPointF &coordinates) {_coordinates = coordinates;} Trackpoint(const Coordinates &coordinates) {_coordinates = coordinates;}
const QPointF &coordinates() const {return _coordinates;} const Coordinates &coordinates() const {return _coordinates;}
const QDateTime &timestamp() const {return _timestamp;} const QDateTime &timestamp() const {return _timestamp;}
qreal elevation() const {return _elevation;} qreal elevation() const {return _elevation;}
qreal geoidHeight() const {return _geoidHeight;} qreal geoidHeight() const {return _geoidHeight;}
@ -23,7 +23,7 @@ public:
qreal heartRate() const {return _heartRate;} qreal heartRate() const {return _heartRate;}
qreal temperature() const {return _temperature;} qreal temperature() const {return _temperature;}
void setCoordinates(const QPointF &coordinates) void setCoordinates(const Coordinates &coordinates)
{_coordinates = coordinates;} {_coordinates = coordinates;}
void setTimestamp(const QDateTime &timestamp) {_timestamp = timestamp;} void setTimestamp(const QDateTime &timestamp) {_timestamp = timestamp;}
void setElevation(qreal elevation) {_elevation = elevation;} void setElevation(qreal elevation) {_elevation = elevation;}
@ -39,7 +39,7 @@ public:
bool hasTemperature() const {return !std::isnan(_temperature);} bool hasTemperature() const {return !std::isnan(_temperature);}
private: private:
QPointF _coordinates; Coordinates _coordinates;
QDateTime _timestamp; QDateTime _timestamp;
qreal _elevation; qreal _elevation;
qreal _geoidHeight; qreal _geoidHeight;

View File

@ -1,28 +1,28 @@
#ifndef WAYPOINT_H #ifndef WAYPOINT_H
#define WAYPOINT_H #define WAYPOINT_H
#include <QPointF>
#include <QString> #include <QString>
#include <QDateTime> #include <QDateTime>
#include <QHash> #include <QHash>
#include <QDebug> #include <QDebug>
#include <cmath> #include <cmath>
#include "coordinates.h"
class Waypoint class Waypoint
{ {
public: public:
Waypoint() {_elevation = NAN; _geoidHeight = 0;} Waypoint() {_elevation = NAN; _geoidHeight = 0;}
Waypoint(const QPointF &coordinates) Waypoint(const Coordinates &coordinates)
: _coordinates(coordinates) {_elevation = NAN; _geoidHeight = 0;} : _coordinates(coordinates) {_elevation = NAN; _geoidHeight = 0;}
const QPointF &coordinates() const {return _coordinates;} const Coordinates &coordinates() const {return _coordinates;}
const QString &name() const {return _name;} const QString &name() const {return _name;}
const QString &description() const {return _description;} const QString &description() const {return _description;}
const QDateTime &timestamp() const {return _timestamp;} const QDateTime &timestamp() const {return _timestamp;}
qreal elevation() const {return _elevation;} qreal elevation() const {return _elevation;}
qreal geoidHeight() const {return _geoidHeight;} qreal geoidHeight() const {return _geoidHeight;}
void setCoordinates(const QPointF &coordinates) void setCoordinates(const Coordinates &coordinates)
{_coordinates = coordinates;} {_coordinates = coordinates;}
void setName(const QString &name) {_name = name;} void setName(const QString &name) {_name = name;}
void setDescription(const QString &description) void setDescription(const QString &description)
@ -38,7 +38,7 @@ public:
&& this->_coordinates == other._coordinates;} && this->_coordinates == other._coordinates;}
private: private:
QPointF _coordinates; Coordinates _coordinates;
QString _name; QString _name;
QString _description; QString _description;
QDateTime _timestamp; QDateTime _timestamp;

View File

@ -1,7 +1,6 @@
#include <QApplication> #include <QApplication>
#include <QPainter> #include <QPainter>
#include "config.h" #include "config.h"
#include "ll.h"
#include "misc.h" #include "misc.h"
#include "tooltip.h" #include "tooltip.h"
#include "waypointitem.h" #include "waypointitem.h"
@ -39,8 +38,8 @@ WaypointItem::WaypointItem(const Waypoint &waypoint, QGraphicsItem *parent)
_hover = false; _hover = false;
_waypoint = waypoint; _waypoint = waypoint;
_coordinates = ll2mercator(QPointF(waypoint.coordinates().x(), QPointF p = waypoint.coordinates().toMercator();
-waypoint.coordinates().y())); _coordinates = QPointF(p.x(), -p.y());
updateShape(); updateShape();

6
src/wgs84.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef WGS84_H
#define WGS84_H
#define WGS84_RADIUS 6378137.0
#endif // WGS84_H