1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-01-19 20:12:10 +01:00
GPXSee/src/data/poi.cpp

215 lines
4.2 KiB
C++
Raw Normal View History

2015-10-05 01:43:48 +02:00
#include <QFile>
#include <QDir>
#include "common/rectc.h"
#include "common/greatcircle.h"
2016-10-23 11:09:20 +02:00
#include "data.h"
#include "dem.h"
2019-01-31 01:46:53 +01:00
#include "path.h"
#include "area.h"
#include "common/wgs84.h"
2015-10-05 01:43:48 +02:00
#include "poi.h"
2016-10-09 23:46:30 +02:00
POI::POI(QObject *parent) : QObject(parent)
{
_errorLine = 0;
2016-12-06 01:48:26 +01:00
_radius = 1000;
2016-10-09 23:46:30 +02:00
}
bool POI::loadFile(const QString &path)
{
Data data(path);
FileIndex index;
index.enabled = true;
index.start = _data.size();
2015-10-05 01:43:48 +02:00
2019-01-18 00:17:28 +01:00
if (!data.isValid()) {
_errorString = data.errorString();
_errorLine = data.errorLine();
2015-10-05 01:43:48 +02:00
return false;
}
2016-10-23 11:09:20 +02:00
for (int i = 0; i < data.waypoints().size(); i++)
_data.append(data.waypoints().at(i));
index.end = _data.size() - 1;
2015-10-05 01:43:48 +02:00
for (int i = index.start; i <= index.end; i++) {
const Coordinates &p = _data.at(i).coordinates();
2015-10-05 01:43:48 +02:00
qreal c[2];
c[0] = p.lon();
c[1] = p.lat();
_tree.Insert(c, c, i);
2015-10-05 01:43:48 +02:00
}
_files.append(path);
_indexes.append(index);
2016-10-23 11:09:20 +02:00
emit pointsChanged();
2015-10-05 01:43:48 +02:00
return true;
}
void POI::loadDir(const QString &path)
{
QDir md(path);
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
QFileInfoList fl = md.entryInfoList();
for (int i = 0; i < fl.size(); i++) {
const QFileInfo &fi = fl.at(i);
if (fi.isDir())
loadDir(fi.absoluteFilePath());
else
if (!loadFile(fi.absoluteFilePath()))
qWarning(qPrintable(fi.absoluteFilePath() + ": "
+ _errorString));
}
}
static bool cb(size_t data, void* context)
2015-10-05 01:43:48 +02:00
{
QSet<int> *set = (QSet<int>*) context;
set->insert((int)data);
2015-10-05 01:43:48 +02:00
return true;
}
2018-09-13 01:15:43 +02:00
void POI::search(const RectC &rect, QSet<int> &set) const
{
qreal min[2], max[2];
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
}
2017-11-26 18:54:03 +01:00
QList<Waypoint> POI::points(const Path &path) const
{
2017-11-26 18:54:03 +01:00
QList<Waypoint> ret;
QSet<int> set;
2017-11-26 18:54:03 +01:00
QSet<int>::const_iterator it;
2016-12-06 01:48:26 +01:00
2019-02-11 23:28:08 +01:00
for (int i = 0; i < path.count(); i++) {
const PathSegment &segment = path.at(i);
for (int j = 1; j < segment.size(); j++) {
double ds = segment.at(j).distance() - segment.at(j-1).distance();
unsigned n = (unsigned)ceil(ds / _radius);
if (n > 1) {
GreatCircle gc(segment.at(j-1).coordinates(),
segment.at(j).coordinates());
for (unsigned k = 0; k < n; k++) {
RectC br(gc.pointAt((double)k/n), _radius);
search(br, set);
}
} else {
RectC br(segment.at(j-1).coordinates(), _radius);
2018-09-13 01:15:43 +02:00
search(br, set);
}
}
}
2019-02-11 23:28:08 +01:00
RectC br(path.last().last().coordinates(), _radius);
2018-09-13 01:15:43 +02:00
search(br, set);
2017-11-26 18:54:03 +01:00
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
2015-10-05 01:43:48 +02:00
return ret;
}
2017-11-26 18:54:03 +01:00
QList<Waypoint> POI::points(const Waypoint &point) const
2016-10-08 14:53:10 +02:00
{
2017-11-26 18:54:03 +01:00
QList<Waypoint> ret;
2016-10-08 14:53:10 +02:00
QSet<int> set;
qreal min[2], max[2];
2017-11-26 18:54:03 +01:00
QSet<int>::const_iterator it;
2016-10-08 14:53:10 +02:00
RectC br(point.coordinates(), _radius);
min[0] = br.topLeft().lon();
min[1] = br.bottomRight().lat();
max[0] = br.bottomRight().lon();
max[1] = br.topLeft().lat();
2016-12-06 01:48:26 +01:00
2017-11-26 18:54:03 +01:00
_tree.Search(min, max, cb, &set);
2016-10-08 14:53:10 +02:00
2017-11-26 18:54:03 +01:00
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
2016-10-08 14:53:10 +02:00
return ret;
}
2019-01-31 01:46:53 +01:00
QList<Waypoint> POI::points(const Area &area) const
{
QList<Waypoint> ret;
qreal min[2], max[2];
QSet<int> set;
QSet<int>::const_iterator it;
RectC br(area.boundingRect());
double offset = rad2deg(_radius / WGS84_RADIUS);
min[0] = br.topLeft().lon() - offset;
min[1] = br.bottomRight().lat() - offset;
max[0] = br.bottomRight().lon() + offset;
max[1] = br.topLeft().lat() + offset;
_tree.Search(min, max, cb, &set);
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
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 Coordinates &p = _data.at(j).coordinates();
qreal c[2];
c[0] = p.lon();
c[1] = p.lat();
_tree.Insert(c, c, j);
}
}
2016-10-09 23:46:30 +02:00
2016-10-11 00:19:42 +02:00
emit pointsChanged();
}
2015-10-05 01:43:48 +02:00
void POI::clear()
{
_tree.RemoveAll();
_data.clear();
_files.clear();
_indexes.clear();
2016-10-09 23:46:30 +02:00
2016-10-11 00:19:42 +02:00
emit pointsChanged();
2016-10-09 23:46:30 +02:00
}
2016-12-06 01:48:26 +01:00
void POI::setRadius(unsigned radius)
2016-10-09 23:46:30 +02:00
{
_radius = radius;
2016-10-11 00:19:42 +02:00
emit pointsChanged();
2015-10-05 01:43:48 +02:00
}