1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-06-27 03:29:16 +02:00

Fixed POI crash on vector reallocation

Improved error reporting
This commit is contained in:
2015-11-26 19:13:59 +01:00
parent d1bf74f43b
commit 4e543782ec
11 changed files with 135 additions and 129 deletions

View File

@ -8,6 +8,7 @@
#define FONT_FAMILY "Arial"
#define FONT_SIZE 12
#define POI_DIR "POI"
#define TILES_DIR "tiles"
#define MAP_LIST_FILE TILES_DIR"/list.txt"

View File

@ -87,14 +87,17 @@ bool GPX::loadFile(const QString &fileName)
_data.clear();
_error.clear();
_errorLine = 0;
if (!file.open(QFile::ReadOnly | QFile::Text)) {
_error = qPrintable(file.errorString());
return false;
}
if (!(ret = _parser.loadFile(&file, _data)))
if (!(ret = _parser.loadFile(&file, _data))) {
_error = _parser.errorString();
_errorLine = _parser.errorLine();
}
file.close();
return ret;

View File

@ -11,6 +11,7 @@ class GPX
public:
bool loadFile(const QString &fileName);
const QString &errorString() const {return _error;}
int errorLine() const {return _errorLine;}
void elevationGraph(QVector<QPointF> &graph) const;
void speedGraph(QVector<QPointF> &graph) const;
@ -23,6 +24,7 @@ private:
Parser _parser;
QVector<TrackPoint> _data;
QString _error;
int _errorLine;
};
#endif // GPX_H

View File

@ -37,7 +37,7 @@ static QString timeSpan(qreal time)
GUI::GUI()
{
loadMaps();
loadFiles();
createActions();
createMenus();
@ -71,9 +71,20 @@ GUI::GUI()
resize(600, 800);
}
void GUI::loadMaps()
void GUI::loadFiles()
{
// Maps
_maps = MapList::load(QString("%1/"MAP_LIST_FILE).arg(QDir::homePath()));
// POI files
QDir dir(QString("%1/"POI_DIR).arg(QDir::homePath()));
QFileInfoList list = dir.entryInfoList(QStringList(), QDir::Files);
for (int i = 0; i < list.size(); ++i) {
if (!_poi.loadFile(list.at(i).absoluteFilePath()))
fprintf(stderr, "Error loading POI file: %s: %s",
qPrintable(list.at(i).absoluteFilePath()),
qPrintable(_poi.errorString()));
}
}
void GUI::createMapActions()
@ -346,8 +357,13 @@ bool GUI::loadFile(const QString &fileName)
return true;
} else {
QMessageBox::critical(this, tr("Error"), fileName + QString("\n\n")
+ tr("Error loading GPX file:\n%1").arg(gpx.errorString()));
QString error = fileName + QString("\n\n")
+ tr("Error loading GPX file:\n%1").arg(gpx.errorString())
+ QString("\n");
if (gpx.errorLine())
error.append(tr("Line: %1").arg(gpx.errorLine()));
QMessageBox::critical(this, tr("Error"), error);
return false;
}
}
@ -358,8 +374,11 @@ void GUI::openPOIFile()
if (!fileName.isEmpty()) {
if (!_poi.loadFile(fileName)) {
QMessageBox::critical(this, tr("Error"),
tr("Error loading POI file:\n%1").arg(_poi.errorString()));
QString error = tr("Error loading POI file:\n%1")
.arg(_poi.errorString()) + QString("\n");
if (_poi.errorLine())
error.append(tr("Line: %1").arg(_poi.errorLine()));
QMessageBox::critical(this, tr("Error"), error);
} else {
_showPOIAction->setChecked(true);
_track->loadPOI(_poi);
@ -527,7 +546,6 @@ void GUI::graphChanged(int index)
_speedGraph->setSliderPosition(_elevationGraph->sliderPosition());
}
void GUI::keyPressEvent(QKeyEvent *event)
{
QString file;

View File

@ -45,7 +45,7 @@ private slots:
void graphChanged(int);
private:
void loadMaps();
void loadFiles();
void createMapActions();
void createActions();

View File

@ -1,13 +1,17 @@
#include <QFile>
#include <QFileInfo>
#include "maplist.h"
QList<Map*> MapList::load(const QString &fileName)
{
QFile file(fileName);
QList<Map*> mapList;
int ln = 1;
QFileInfo fi(fileName);
if (!fi.exists())
return mapList;
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
fprintf(stderr, "Error opening map list file: %s: %s\n",
@ -15,6 +19,7 @@ QList<Map*> MapList::load(const QString &fileName)
return mapList;
}
int ln = 1;
while (!file.atEnd()) {
QByteArray line = file.readLine();
QList<QByteArray> list = line.split('\t');

View File

@ -92,20 +92,12 @@ bool Parser::parse(QVector<TrackPoint> &data)
if (_reader.name() == "gpx")
gpx(data);
else
_reader.raiseError(QObject::tr("Not a GPX file."));
_reader.raiseError("Not a GPX file.");
}
return !_reader.error();
}
QString Parser::errorString() const
{
return QObject::tr("%1\nLine %2")
.arg(_reader.errorString())
.arg(_reader.lineNumber());
}
bool Parser::loadFile(QIODevice *device, QVector<TrackPoint> &data)
{
_reader.clear();

View File

@ -20,7 +20,8 @@ class Parser
{
public:
bool loadFile(QIODevice *device, QVector<TrackPoint> &data);
QString errorString() const;
QString errorString() const {return _reader.errorString();}
int errorLine() const {return _reader.lineNumber();}
private:
bool parse(QVector<TrackPoint> &data);

View File

@ -11,9 +11,10 @@ bool POI::loadFile(const QString &fileName)
{
QFile file(fileName);
bool ret;
int ln = 1;
int ln = 1, cnt = _data.size();
_error.clear();
_errorLine = 0;
if (!file.open(QFile::ReadOnly | QFile::Text)) {
_error = qPrintable(file.errorString());
@ -24,18 +25,21 @@ bool POI::loadFile(const QString &fileName)
QByteArray line = file.readLine();
QList<QByteArray> list = line.split(',');
if (list.size() < 3) {
_error = QString("Parse error\nLine %1").arg(ln);
_error = "Parse error";
_errorLine = ln;
return false;
}
qreal lat = list[0].trimmed().toDouble(&ret);
if (!ret) {
_error = QObject::tr("Invalid latitude\nLine %1").arg(ln);
_error = "Invalid latitude";
_errorLine = ln;
return false;
}
qreal lon = list[1].trimmed().toDouble(&ret);
if (!ret) {
_error = QObject::tr("Invalid longitude\nLine %1").arg(ln);
_error = "Invalid longitude";
_errorLine = ln;
return false;
}
QByteArray ba = list[2].trimmed();
@ -48,20 +52,20 @@ bool POI::loadFile(const QString &fileName)
ln++;
}
for (int i = 0; i < _data.size(); ++i) {
for (int i = cnt; i < _data.size(); ++i) {
qreal c[2];
c[0] = _data.at(i).coordinates.x();
c[1] = _data.at(i).coordinates.y();
_tree.Insert(c, c, &_data.at(i));
_tree.Insert(c, c, i);
}
return true;
}
static bool cb(const Entry* data, void* context)
static bool cb(size_t data, void* context)
{
QSet<const Entry*> *set = (QSet<const Entry*>*) context;
set->insert(data);
QSet<int> *set = (QSet<int>*) context;
set->insert((int)data);
return true;
}
@ -69,7 +73,7 @@ static bool cb(const Entry* data, void* context)
QVector<Entry> POI::points(const QVector<QPointF> &path) const
{
QVector<Entry> ret;
QSet<const Entry*> set;
QSet<int> set;
qreal min[2], max[2];
for (int i = 0; i < path.count(); i++) {
@ -80,10 +84,10 @@ QVector<Entry> POI::points(const QVector<QPointF> &path) const
_tree.Search(min, max, cb, &set);
}
QSet<const Entry *>::const_iterator i = set.constBegin();
QSet<int>::const_iterator i = set.constBegin();
while (i != set.constEnd()) {
ret.append(*(*i));
++i;
ret.append(_data.at(*i));
++i;
}
return ret;

View File

@ -28,16 +28,19 @@ class POI
public:
bool loadFile(const QString &fileName);
QString errorString() const {return _error;}
int errorLine() const {return _errorLine;}
QVector<Entry> points(const QVector<QPointF> &path) const;
void clear();
private:
typedef RTree<const Entry*, qreal, 2> POITree;
typedef RTree<size_t, qreal, 2> POITree;
POITree _tree;
QVector<Entry> _data;
QString _error;
int _errorLine;
};
#endif // POI_H