mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-10-07 07:13:21 +02:00
228 lines
4.3 KiB
C++
228 lines
4.3 KiB
C++
#include <QFile>
|
|
#include <QSet>
|
|
#include <QList>
|
|
#include <QPainterPath>
|
|
#include "waypointitem.h"
|
|
#include "ll.h"
|
|
#include "gpx.h"
|
|
#include "poi.h"
|
|
|
|
|
|
bool POI::loadFile(const QString &fileName)
|
|
{
|
|
QString error;
|
|
int errorLine;
|
|
|
|
_error.clear();
|
|
_errorLine = 0;
|
|
|
|
|
|
if (loadCSVFile(fileName))
|
|
return true;
|
|
else {
|
|
error = _error;
|
|
errorLine = _errorLine;
|
|
}
|
|
if (loadGPXFile(fileName))
|
|
return true;
|
|
|
|
fprintf(stderr, "Error loading POI file: %s:\n", qPrintable(fileName));
|
|
fprintf(stderr, "CSV: line %d: %s\n", errorLine, qPrintable(error));
|
|
fprintf(stderr, "GPX: line %d: %s\n", _errorLine, qPrintable(_error));
|
|
|
|
if (errorLine > _errorLine) {
|
|
_errorLine = errorLine;
|
|
_error = error;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool POI::loadGPXFile(const QString &fileName)
|
|
{
|
|
GPX gpx;
|
|
FileIndex index;
|
|
|
|
index.enabled = true;
|
|
index.start = _data.size();
|
|
|
|
if (gpx.loadFile(fileName)) {
|
|
for (int i = 0; i < gpx.waypoints().size(); i++)
|
|
_data.append(gpx.waypoints().at(i));
|
|
index.end = _data.size() - 1;
|
|
|
|
for (int i = index.start; i <= index.end; i++) {
|
|
const QPointF &p = _data.at(i).coordinates();
|
|
qreal c[2];
|
|
c[0] = p.x();
|
|
c[1] = p.y();
|
|
_tree.Insert(c, c, i);
|
|
}
|
|
|
|
_files.append(fileName);
|
|
_indexes.append(index);
|
|
|
|
return true;
|
|
} else {
|
|
_error = gpx.errorString();
|
|
_errorLine = gpx.errorLine();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool POI::loadCSVFile(const QString &fileName)
|
|
{
|
|
QFile file(fileName);
|
|
FileIndex index;
|
|
bool ret;
|
|
int ln = 1;
|
|
|
|
index.enabled = true;
|
|
index.start = _data.size();
|
|
|
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
|
_error = qPrintable(file.errorString());
|
|
return false;
|
|
}
|
|
|
|
while (!file.atEnd()) {
|
|
QByteArray line = file.readLine();
|
|
QList<QByteArray> list = line.split(',');
|
|
if (list.size() < 3) {
|
|
_error = "Parse error";
|
|
_errorLine = ln;
|
|
return false;
|
|
}
|
|
|
|
qreal lat = list[0].trimmed().toDouble(&ret);
|
|
if (!ret) {
|
|
_error = "Invalid latitude";
|
|
_errorLine = ln;
|
|
return false;
|
|
}
|
|
qreal lon = list[1].trimmed().toDouble(&ret);
|
|
if (!ret) {
|
|
_error = "Invalid longitude";
|
|
_errorLine = ln;
|
|
return false;
|
|
}
|
|
Waypoint wp(QPointF(lon, lat));
|
|
|
|
QByteArray ba = list[2].trimmed();
|
|
QString name = QString::fromUtf8(ba.data(), ba.size());
|
|
wp.setName(name);
|
|
|
|
if (list.size() > 3) {
|
|
ba = list[3].trimmed();
|
|
wp.setDescription(QString::fromUtf8(ba.data(), ba.size()));
|
|
}
|
|
|
|
_data.append(wp);
|
|
ln++;
|
|
}
|
|
index.end = _data.size() - 1;
|
|
|
|
for (int i = index.start; i <= index.end; i++) {
|
|
const QPointF &p = _data.at(i).coordinates();
|
|
qreal c[2];
|
|
c[0] = p.x();
|
|
c[1] = p.y();
|
|
_tree.Insert(c, c, i);
|
|
}
|
|
|
|
_files.append(fileName);
|
|
_indexes.append(index);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool cb(size_t data, void* context)
|
|
{
|
|
QSet<int> *set = (QSet<int>*) context;
|
|
set->insert((int)data);
|
|
|
|
return true;
|
|
}
|
|
|
|
QVector<Waypoint> POI::points(const QPainterPath &path, qreal radius) const
|
|
{
|
|
QVector<Waypoint> ret;
|
|
QSet<int> set;
|
|
qreal min[2], max[2];
|
|
|
|
for (int i = 0; i < path.elementCount(); i++) {
|
|
QPointF p = mercator2ll(path.elementAt(i));
|
|
min[0] = p.x() - radius;
|
|
min[1] = -p.y() - radius;
|
|
max[0] = p.x() + radius;
|
|
max[1] = -p.y() + radius;
|
|
_tree.Search(min, max, cb, &set);
|
|
}
|
|
|
|
QSet<int>::const_iterator i = set.constBegin();
|
|
while (i != set.constEnd()) {
|
|
ret.append(_data.at(*i));
|
|
++i;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
QVector<Waypoint> POI::points(const QList<WaypointItem*> &list, qreal radius)
|
|
const
|
|
{
|
|
QVector<Waypoint> ret;
|
|
QSet<int> set;
|
|
qreal min[2], max[2];
|
|
|
|
for (int i = 0; i < list.count(); i++) {
|
|
const QPointF &p = list.at(i)->waypoint().coordinates();
|
|
min[0] = p.x() - radius;
|
|
min[1] = p.y() - radius;
|
|
max[0] = p.x() + radius;
|
|
max[1] = p.y() + radius;
|
|
_tree.Search(min, max, cb, &set);
|
|
}
|
|
|
|
QSet<int>::const_iterator i = set.constBegin();
|
|
while (i != set.constEnd()) {
|
|
ret.append(_data.at(*i));
|
|
++i;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void POI::enableFile(const QString &fileName, bool enable)
|
|
{
|
|
int i;
|
|
|
|
i = _files.indexOf(fileName);
|
|
Q_ASSERT(i >= 0);
|
|
_indexes[i].enabled = enable;
|
|
|
|
_tree.RemoveAll();
|
|
for (int i = 0; i < _indexes.count(); i++) {
|
|
FileIndex idx = _indexes.at(i);
|
|
if (!idx.enabled)
|
|
continue;
|
|
|
|
for (int j = idx.start; j <= idx.end; j++) {
|
|
const QPointF &p = _data.at(j).coordinates();
|
|
qreal c[2];
|
|
c[0] = p.x();
|
|
c[1] = p.y();
|
|
_tree.Insert(c, c, j);
|
|
}
|
|
}
|
|
}
|
|
|
|
void POI::clear()
|
|
{
|
|
_tree.RemoveAll();
|
|
_data.clear();
|
|
_files.clear();
|
|
_indexes.clear();
|
|
}
|