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

215 lines
4.3 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"
2021-03-21 21:04:26 +01:00
static bool cb(size_t data, void* context)
{
QSet<int> *set = (QSet<int>*) context;
set->insert((int)data);
return true;
}
POI::File::File(int start, int end, const QVector<Waypoint> &data)
: _enabled(true)
{
qreal c[2];
for (int i = start; i <= end; i++) {
const Coordinates &p = data.at(i).coordinates();
c[0] = p.lon();
c[1] = p.lat();
_tree.Insert(c, c, i);
}
}
2021-03-21 21:04:26 +01:00
void POI::File::search(const RectC &rect, QSet<int> &set) const
{
qreal min[2], max[2];
if (_enabled) {
if (rect.left() > rect.right()) {
min[0] = rect.topLeft().lon();
min[1] = rect.bottomRight().lat();
max[0] = 180.0;
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
min[0] = -180.0;
min[1] = rect.bottomRight().lat();
max[0] = rect.bottomRight().lon();
max[1] = rect.topLeft().lat();
_tree.Search(min, max, cb, &set);
} else {
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);
}
}
}
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
}
POI::~POI()
{
qDeleteAll(_files);
}
bool POI::loadFile(const QString &path)
{
Data data(path);
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;
}
int start = _data.size();
_data.append(data.waypoints());
2015-10-05 01:43:48 +02:00
_files.insert(path, new File(start, _data.size() - 1, _data));
2016-10-23 11:09:20 +02:00
emit pointsChanged();
2015-10-05 01:43:48 +02:00
return true;
}
TreeNode<QString> POI::loadDir(const QString &path)
{
QDir md(path);
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
md.setSorting(QDir::DirsFirst);
QFileInfoList fl = md.entryInfoList();
TreeNode<QString> tree(md.dirName());
for (int i = 0; i < fl.size(); i++) {
const QFileInfo &fi = fl.at(i);
if (fi.isDir()) {
TreeNode<QString> child(loadDir(fi.absoluteFilePath()));
if (!child.isEmpty())
tree.addChild(child);
} else {
if (loadFile(fi.absoluteFilePath()))
tree.addItem(fi.absoluteFilePath());
else
qWarning("%s: %s", qPrintable(fi.absoluteFilePath()),
qPrintable(_errorString));
}
}
return tree;
}
2018-09-13 01:15:43 +02:00
void POI::search(const RectC &rect, QSet<int> &set) const
{
2021-03-21 21:04:26 +01:00
for (ConstIterator it = _files.constBegin(); it != _files.constEnd(); ++it)
(*it)->search(rect, set);
2018-09-13 01:15:43 +02:00
}
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;
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);
search(br, 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;
}
2020-12-02 23:58:11 +01:00
QList<Waypoint> POI::points(const RectC &rect) const
2019-01-31 01:46:53 +01:00
{
QList<Waypoint> ret;
QSet<int> set;
QSet<int>::const_iterator it;
double offset = rad2deg(_radius / WGS84_RADIUS);
RectC br(rect.adjusted(-offset, offset, offset, -offset));
search(br, set);
2019-01-31 01:46:53 +01:00
for (it = set.constBegin(); it != set.constEnd(); ++it)
ret.append(_data.at(*it));
return ret;
}
bool POI::enableFile(const QString &fileName, bool enable)
{
Iterator it = _files.find(fileName);
if (it == _files.end())
return false;
(*it)->enable(enable);
2016-10-09 23:46:30 +02:00
2016-10-11 00:19:42 +02:00
emit pointsChanged();
return true;
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
}