diff --git a/src/gui.cpp b/src/gui.cpp index 5d8403f8..b3d6e080 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -250,7 +250,8 @@ void GUI::createActions() tr("Show POIs"), this); _showPOIAction->setCheckable(true); _showPOIAction->setShortcut(SHOW_POI_SHORTCUT); - connect(_showPOIAction, SIGNAL(triggered(bool)), this, SLOT(showPOI(bool))); + connect(_showPOIAction, SIGNAL(triggered(bool)), _pathView, + SLOT(showPOI(bool))); addAction(_showPOIAction); createPOIFilesActions(); @@ -463,6 +464,8 @@ void GUI::createPathView() #ifdef Q_OS_WIN32 _pathView->setFrameShape(QFrame::NoFrame); #endif // Q_OS_WIN32 + + _pathView->setPOI(&_poi); } void GUI::createGraphTabs() @@ -622,8 +625,6 @@ bool GUI::loadFile(const QString &fileName) _tabs.at(i)->loadGPX(gpx, paths); updateGraphTabs(); _pathView->setHidden(false); - if (_showPOIAction->isChecked()) - _pathView->loadPOI(_poi); for (int i = 0; i < gpx.tracks().count(); i++) { _trackDistance += gpx.tracks().at(i)->distance(); @@ -679,8 +680,9 @@ bool GUI::openPOIFile(const QString &fileName) return false; } else { + _pathView->setPOI(&_poi); + _pathView->showPOI(true); _showPOIAction->setChecked(true); - _pathView->loadPOI(_poi); QAction *action = createPOIFileAction(_poi.files().indexOf(fileName)); action->setChecked(true); _poiFilesMenu->addAction(action); @@ -697,7 +699,7 @@ void GUI::closePOIFiles() delete _poiFilesActions[i]; _poiFilesActions.clear(); - _pathView->clearPOI(); + _pathView->setPOI(0); _poi.clear(); } @@ -853,14 +855,6 @@ void GUI::closeAll() updateTrackView(); } -void GUI::showPOI(bool checked) -{ - if (checked) - _pathView->loadPOI(_poi); - else - _pathView->clearPOI(); -} - void GUI::showMap(bool checked) { if (checked) @@ -1007,9 +1001,7 @@ void GUI::poiFileChecked(int index) _poi.enableFile(_poi.files().at(index), _poiFilesActions.at(index)->isChecked()); - _pathView->clearPOI(); - if (_showPOIAction->isChecked()) - _pathView->loadPOI(_poi); + _pathView->setPOI(&_poi); } void GUI::sliderPositionChanged(qreal pos) @@ -1311,6 +1303,8 @@ void GUI::readSettings() _showPOILabelsAction->setChecked(true); if (settings.value(SHOW_POI_SETTING, false).toBool() == true) _showPOIAction->setChecked(true); + else + _pathView->showPOI(false); for (int i = 0; i < _poiFilesActions.count(); i++) _poiFilesActions.at(i)->setChecked(true); int size = settings.beginReadArray(DISABLED_POI_FILE_SETTINGS_PREFIX); diff --git a/src/gui.h b/src/gui.h index 673930d8..eec7df3b 100644 --- a/src/gui.h +++ b/src/gui.h @@ -45,7 +45,6 @@ private slots: void reloadFile(); void openPOIFile(); void closePOIFiles(); - void showPOI(bool checked); void showMap(bool checked); void showGraphs(bool checked); void showToolbars(bool checked); diff --git a/src/pathview.cpp b/src/pathview.cpp index c2f34af2..17fee9d8 100644 --- a/src/pathview.cpp +++ b/src/pathview.cpp @@ -34,6 +34,7 @@ PathView::PathView(QWidget *parent) _zoom = ZOOM_MAX; _scale = mapScale(_zoom); _map = 0; + _poi = 0; _units = Metric; @@ -41,6 +42,7 @@ PathView::PathView(QWidget *parent) _showRoutes = true; _showWaypoints = true; _showWaypointLabels = true; + _showPOI = true; _showPOILabels = true; _overlapPOIs = true; _showRouteWaypoints = true; @@ -70,6 +72,9 @@ PathItem *PathView::addTrack(const Track &track) ti->setVisible(_showTracks); _scene->addItem(ti); + if (_poi) + addPOI(_poi->points(ti)); + return ti; } @@ -91,6 +96,9 @@ PathItem *PathView::addRoute(const Route &route) ri->showWaypointLabels(_showWaypointLabels); _scene->addItem(ri); + if (_poi) + addPOI(_poi->points(ri)); + return ri; } @@ -109,6 +117,9 @@ void PathView::addWaypoints(const QList &waypoints) _waypoints.append(wi); } + if (_poi) + addPOI(_poi->points(waypoints)); + _zoom = qMin(_zoom, scale2zoom(waypointScale())); _scale = mapScale(_zoom); } @@ -131,6 +142,8 @@ QList PathView::loadGPX(const GPX &gpx) if ((_tracks.size() + _routes.size() > 1 && _zoom < zoom) || (_waypoints.size() && _zoom < zoom)) rescale(_scale); + else + updatePOIVisibility(); QRectF br = trackBoundingRect() | routeBoundingRect() | waypointBoundingRect(); @@ -258,21 +271,31 @@ qreal PathView::mapScale(int zoom) const return ((360.0/(qreal)(1<::const_iterator it, jt; - for (it = _pois.constBegin(); it != _pois.constEnd(); it++) { - for (jt = _pois.constBegin(); jt != _pois.constEnd(); jt++) { - if (it != jt && it.value()->isVisible() && jt.value()->isVisible() - && it.value()->collidesWithItem(jt.value())) - jt.value()->hide(); + if (!_showPOI) + return; + + for (it = _pois.constBegin(); it != _pois.constEnd(); it++) + it.value()->show(); + + if (!_overlapPOIs) { + for (it = _pois.constBegin(); it != _pois.constEnd(); it++) { + for (jt = _pois.constBegin(); jt != _pois.constEnd(); jt++) { + if (it.value()->isVisible() && jt.value()->isVisible() + && it != jt && it.value()->collidesWithItem(jt.value())) + jt.value()->hide(); + } } } } void PathView::rescale(qreal scale) { + _scale = scale; + for (int i = 0; i < _tracks.size(); i++) _tracks.at(i)->setScale(1.0/scale); @@ -283,15 +306,44 @@ void PathView::rescale(qreal scale) _waypoints.at(i)->setScale(1.0/scale); QHash::const_iterator it; - for (it = _pois.constBegin(); it != _pois.constEnd(); it++) { + for (it = _pois.constBegin(); it != _pois.constEnd(); it++) it.value()->setScale(1.0/scale); - it.value()->show(); + + updatePOIVisibility(); +} + +void PathView::setPOI(POI *poi) +{ + _poi = poi; + + clearPOI(); + loadPOI(); +} + +void PathView::loadPOI() +{ + if (!_poi) + return; + + for (int i = 0; i < _tracks.size(); i++) + addPOI(_poi->points(_tracks.at(i))); + for (int i = 0; i < _routes.size(); i++) + addPOI(_poi->points(_routes.at(i))); + addPOI(_poi->points(_waypoints)); + + updatePOIVisibility(); +} + +void PathView::clearPOI() +{ + QHash::const_iterator it; + + for (it = _pois.constBegin(); it != _pois.constEnd(); it++) { + _scene->removeItem(it.value()); + delete it.value(); } - if (!_overlapPOIs) - checkPOIOverlap(); - - _scale = scale; + _pois.clear(); } void PathView::addPOI(const QVector &waypoints) @@ -306,27 +358,13 @@ void PathView::addPOI(const QVector &waypoints) pi->setScale(1.0/_scale); pi->setZValue(1); pi->showLabel(_showPOILabels); + pi->setVisible(_showPOI); _scene->addItem(pi); _pois.insert(w, pi); } } -void PathView::loadPOI(const POI &poi) -{ - if (!_tracks.size() && !_routes.size() && !_waypoints.size()) - return; - - for (int i = 0; i < _tracks.size(); i++) - addPOI(poi.points(_tracks.at(i)->path())); - for (int i = 0; i < _routes.size(); i++) - addPOI(poi.points(_routes.at(i)->path())); - addPOI(poi.points(_waypoints)); - - if (!_overlapPOIs) - checkPOIOverlap(); -} - void PathView::setMap(Map *map) { _map = map; @@ -454,18 +492,6 @@ void PathView::plot(QPainter *painter, const QRectF &target) setUpdatesEnabled(true); } -void PathView::clearPOI() -{ - QHash::const_iterator it; - - for (it = _pois.constBegin(); it != _pois.constEnd(); it++) { - _scene->removeItem(it.value()); - delete it.value(); - } - - _pois.clear(); -} - void PathView::clear() { if (_mapScale->scene() == _scene) @@ -527,6 +553,17 @@ void PathView::showRouteWaypoints(bool show) _routes.at(i)->showWaypoints(show); } +void PathView::showPOI(bool show) +{ + _showPOI = show; + + QHash::const_iterator it; + for (it = _pois.constBegin(); it != _pois.constEnd(); it++) + it.value()->setVisible(show); + + updatePOIVisibility(); +} + void PathView::showPOILabels(bool show) { _showPOILabels = show; @@ -535,19 +572,14 @@ void PathView::showPOILabels(bool show) for (it = _pois.constBegin(); it != _pois.constEnd(); it++) it.value()->showLabel(show); - setPOIOverlap(_overlapPOIs); + updatePOIVisibility(); } void PathView::setPOIOverlap(bool overlap) { _overlapPOIs = overlap; - if (_overlapPOIs) { - QHash::const_iterator it; - for (it = _pois.constBegin(); it != _pois.constEnd(); it++) - it.value()->show(); - } else - checkPOIOverlap(); + updatePOIVisibility(); } void PathView::drawBackground(QPainter *painter, const QRectF &rect) diff --git a/src/pathview.h b/src/pathview.h index 39b8b8c1..2fab5661 100644 --- a/src/pathview.h +++ b/src/pathview.h @@ -30,10 +30,7 @@ public: QList loadGPX(const GPX &gpx); - void loadPOI(const POI &poi); - void clearPOI(); - void clear(); - + void setPOI(POI *poi); void setMap(Map *map); void setUnits(enum Units units); @@ -43,9 +40,12 @@ public: int routeCount() const {return _routes.count();} int waypointCount() const {return _waypoints.count();} + void clear(); + public slots: void redraw(); + void showPOI(bool show); void setPOIOverlap(bool overlap); void showWaypointLabels(bool show); void showPOILabels(bool show); @@ -59,6 +59,8 @@ private: PathItem *addRoute(const Route &route); void addWaypoints(const QList &waypoints); void addPOI(const QVector &waypoints); + void loadPOI(); + void clearPOI(); QRectF trackBoundingRect() const; QRectF routeBoundingRect() const; @@ -70,7 +72,7 @@ private: void rescale(qreal scale); void rescale(); void zoom(int z, const QPointF &pos); - void checkPOIOverlap(); + void updatePOIVisibility(); void wheelEvent(QWheelEvent *event); void keyPressEvent(QKeyEvent *event); @@ -79,13 +81,14 @@ private: void paintEvent(QPaintEvent *e); QGraphicsScene *_scene; + ScaleItem *_mapScale; QList _tracks; QList _routes; QList _waypoints; QHash _pois; Map *_map; - ScaleItem *_mapScale; + POI *_poi; Palette _palette; @@ -98,6 +101,7 @@ private: bool _showRoutes; bool _showWaypoints; bool _showWaypointLabels; + bool _showPOI; bool _showPOILabels; bool _overlapPOIs; bool _showRouteWaypoints; diff --git a/src/poi.cpp b/src/poi.cpp index 5364e84c..1748e411 100644 --- a/src/poi.cpp +++ b/src/poi.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include "pathitem.h" #include "waypointitem.h" #include "ll.h" #include "gpx.h" @@ -145,14 +145,15 @@ static bool cb(size_t data, void* context) return true; } -QVector POI::points(const QPainterPath &path, qreal radius) const +QVector POI::points(const PathItem *path, qreal radius) const { QVector ret; QSet set; qreal min[2], max[2]; + const QPainterPath &pp = path->path(); - for (int i = 0; i < path.elementCount(); i++) { - QPointF p = mercator2ll(path.elementAt(i)); + for (int i = 0; i < pp.elementCount(); i++) { + QPointF p = mercator2ll(pp.elementAt(i)); min[0] = p.x() - radius; min[1] = -p.y() - radius; max[0] = p.x() + radius; @@ -194,6 +195,30 @@ QVector POI::points(const QList &list, qreal radius) return ret; } +QVector POI::points(const QList &list, qreal radius) const +{ + QVector ret; + QSet set; + qreal min[2], max[2]; + + for (int i = 0; i < list.count(); i++) { + const QPointF &p = list.at(i).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::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; diff --git a/src/poi.h b/src/poi.h index c1f56656..f0104755 100644 --- a/src/poi.h +++ b/src/poi.h @@ -8,7 +8,7 @@ #include "waypoint.h" #include "rtree.h" -class QPainterPath; +class PathItem; class WaypointItem; #define POI_RADIUS 0.01 @@ -21,10 +21,12 @@ public: const QString &errorString() const {return _error;} int errorLine() const {return _errorLine;} - QVector points(const QPainterPath &path, + QVector points(const PathItem *path, qreal radius = POI_RADIUS) const; QVector points(const QList &list, qreal radius = POI_RADIUS) const; + QVector points(const QList &list, + qreal radius = POI_RADIUS) const; const QStringList &files() const {return _files;} void enableFile(const QString &fileName, bool enable);