Hello community,

here is the log from the commit of package gpxsee for openSUSE:Factory checked 
in at 2017-07-12 19:36:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gpxsee (Old)
 and      /work/SRC/openSUSE:Factory/.gpxsee.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gpxsee"

Wed Jul 12 19:36:15 2017 rev:10 rq:509597 version:4.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/gpxsee/gpxsee.changes    2017-07-05 
23:57:02.919978618 +0200
+++ /work/SRC/openSUSE:Factory/.gpxsee.new/gpxsee.changes       2017-07-12 
19:36:17.341949591 +0200
@@ -1,0 +2,9 @@
+Tue Jul 11 23:37:00 CEST 2017 - tu...@cbox.cz
+
+- Update to version 4.9
+  * Improved map switching (no more track resizing on map change).
+  * Improved TARed Trekbuddy maps loading (now using TMI index
+    files if available).
+  * Optimized POI handling.
+
+-------------------------------------------------------------------

Old:
----
  GPXSee-4.8.tar.gz

New:
----
  GPXSee-4.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gpxsee.spec ++++++
--- /var/tmp/diff_new_pack.Cx5JVI/_old  2017-07-12 19:36:18.001856373 +0200
+++ /var/tmp/diff_new_pack.Cx5JVI/_new  2017-07-12 19:36:18.005855808 +0200
@@ -19,12 +19,12 @@
 # See also http://en.opensuse.org/openSUSE:Specfile_guidelines
 
 Name:           gpxsee
-Version:        4.8
+Version:        4.9
 Release:        1
 Summary:        GPS log files visualizing and analyzing tool
 License:        GPL-3.0
 Group:          Productivity/Graphics/Visualization
-Url:            http://tumic.wz.cz/gpxsee
+Url:            http://www.gpxsee.org
 Source0:        GPXSee-%{version}.tar.gz
 Source1:        gpxsee.desktop
 Source2:        gpxsee.xml

++++++ GPXSee-4.8.tar.gz -> GPXSee-4.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/Info.plist new/GPXSee-4.9/Info.plist
--- old/GPXSee-4.8/Info.plist   2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/Info.plist   2017-07-09 10:36:39.000000000 +0200
@@ -15,7 +15,7 @@
        <key>CFBundleExecutable</key>
        <string>@EXECUTABLE@</string>
        <key>CFBundleIdentifier</key>
-       <string>cz.wz.tumic.GPXSee</string>
+       <string>org.gpxsee.GPXSee</string>
 
        <key>CFBundleDocumentTypes</key>
        <array>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/README.md new/GPXSee-4.9/README.md
--- old/GPXSee-4.8/README.md    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/README.md    2017-07-09 10:36:39.000000000 +0200
@@ -30,4 +30,4 @@
 
[Changelog](https://build.opensuse.org/package/view_file/home:tumic:GPXSee/gpxsee/gpxsee.changes)
 
 ## Homepage
-GPXSee homepage: http://tumic.wz.cz/gpxsee
+http://www.gpxsee.org
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/gpxsee.pro new/GPXSee-4.9/gpxsee.pro
--- old/GPXSee-4.8/gpxsee.pro   2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/gpxsee.pro   2017-07-09 10:36:39.000000000 +0200
@@ -1,5 +1,5 @@
 TARGET = GPXSee
-VERSION = 4.8
+VERSION = 4.9
 QT += core \
     gui \
     network
@@ -94,7 +94,9 @@
     src/datum.h \
     src/maplist.h \
     src/albersequal.h \
-    src/oddspinbox.h
+    src/oddspinbox.h \
+    src/rectc.h \
+    src/searchpointer.h
 SOURCES += src/main.cpp \
     src/gui.cpp \
     src/poi.cpp \
@@ -162,7 +164,8 @@
     src/datum.cpp \
     src/maplist.cpp \
     src/albersequal.cpp \
-    src/oddspinbox.cpp
+    src/oddspinbox.cpp \
+    src/rectc.cpp
 RESOURCES += gpxsee.qrc
 TRANSLATIONS = lang/gpxsee_cs.ts \
     lang/gpxsee_sv.ts \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/pkg/gpxsee.nsi 
new/GPXSee-4.9/pkg/gpxsee.nsi
--- old/GPXSee-4.8/pkg/gpxsee.nsi       2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/pkg/gpxsee.nsi       2017-07-09 10:36:39.000000000 +0200
@@ -5,10 +5,12 @@
 ; The name of the installer
 Name "GPXSee"
 ; Program version
-!define VERSION "4.8"
+!define VERSION "4.9"
 
 ; The file to write
 OutFile "GPXSee-${VERSION}.exe"
+; Compression method
+SetCompressor /SOLID lzma
 
 ; Required execution level 
 RequestExecutionLevel admin
@@ -171,8 +173,8 @@
 
   DetailPrint "Installing Visual C++ 2015 Redistributable..."
   SetOutPath $TEMP
-  File "VC_redist.x86.exe"
-  ExecWait '"$TEMP/VC_redist.x86.exe" /install /quiet /norestart'
+  File "vcredist_x86.exe"
+  ExecWait '"$TEMP\vcredist_x86.exe" /install /quiet /norestart'
   SetOutPath $INSTDIR
 
   done:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/pkg/gpxsee64.nsi 
new/GPXSee-4.9/pkg/gpxsee64.nsi
--- old/GPXSee-4.8/pkg/gpxsee64.nsi     2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/pkg/gpxsee64.nsi     2017-07-09 10:36:39.000000000 +0200
@@ -5,10 +5,12 @@
 ; The name of the installer
 Name "GPXSee"
 ; Program version
-!define VERSION "4.8"
+!define VERSION "4.9"
 
 ; The file to write
 OutFile "GPXSee-${VERSION}_x64.exe"
+; Compression method
+SetCompressor /SOLID lzma
 
 ; Required execution level 
 RequestExecutionLevel admin
@@ -173,8 +175,8 @@
 
   DetailPrint "Installing Visual C++ 2015 Redistributable..."
   SetOutPath $TEMP
-  File "VC_redist.x64.exe"
-  ExecWait '"$TEMP/VC_redist.x64.exe" /install /quiet /norestart'
+  File "vcredist_x64.exe"
+  ExecWait '"$TEMP\vcredist_x64.exe" /install /quiet /norestart'
   SetOutPath $INSTDIR
 
   done:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/app.cpp new/GPXSee-4.9/src/app.cpp
--- old/GPXSee-4.8/src/app.cpp  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/app.cpp  2017-07-09 10:36:39.000000000 +0200
@@ -3,6 +3,7 @@
 #include <QLocale>
 #include <QFileOpenEvent>
 #include <QNetworkProxyFactory>
+#include <QLibraryInfo>
 #include "opengl.h"
 #include "gui.h"
 #include "onlinemap.h"
@@ -13,11 +14,16 @@
 App::App(int &argc, char **argv) : QApplication(argc, argv),
   _argc(argc), _argv(argv)
 {
-       QTranslator *translator = new QTranslator(this);
-
+       QTranslator *gpxsee = new QTranslator(this);
        QString locale = QLocale::system().name();
-       translator->load(QString(":/lang/gpxsee_") + locale);
-       installTranslator(translator);
+       gpxsee->load(QString(":/lang/gpxsee_") + locale);
+       installTranslator(gpxsee);
+
+       QTranslator *qt = new QTranslator(this);
+       qt->load(QLocale::system(), "qt", "_", QLibraryInfo::location(
+         QLibraryInfo::TranslationsPath));
+       installTranslator(qt);
+
 #ifdef Q_OS_MAC
        setAttribute(Qt::AA_DontShowIconsInMenus);
 #endif // Q_OS_MAC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/atlas.cpp new/GPXSee-4.9/src/atlas.cpp
--- old/GPXSee-4.8/src/atlas.cpp        2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/atlas.cpp        2017-07-09 10:36:39.000000000 +0200
@@ -1,6 +1,7 @@
 #include <QDir>
 #include <QtAlgorithms>
 #include <QPainter>
+#include "rectc.h"
 #include "tar.h"
 #include "atlas.h"
 
@@ -198,11 +199,11 @@
        return _zoom;
 }
 
-qreal Atlas::zoomFit(const QSize &size, const QRectF &br)
+qreal Atlas::zoomFit(const QSize &size, const RectC &br)
 {
        _zoom = 0;
 
-       if (br.isNull()) {
+       if (!br.isValid()) {
                _zoom = _zooms.size() - 1;
                return _zoom;
        }
@@ -220,6 +221,26 @@
                                return _zoom;
 
                        _zoom = z;
+                       break;
+               }
+       }
+
+       return _zoom;
+}
+
+qreal Atlas::zoomFit(qreal resolution, const Coordinates &c)
+{
+       _zoom = 0;
+
+       for (int z = 0; z < _zooms.count(); z++) {
+               for (int i = _zooms.at(z).first; i <= _zooms.at(z).second; i++) 
{
+                       if 
(!_bounds.at(i).first.contains(_maps.at(i)->ll2pp(c)))
+                               continue;
+
+                       if (_maps.at(i)->resolution(_maps.at(i)->ll2xy(c)) < 
resolution)
+                               return _zoom;
+
+                       _zoom = z;
                        break;
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/atlas.h new/GPXSee-4.9/src/atlas.h
--- old/GPXSee-4.8/src/atlas.h  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/atlas.h  2017-07-09 10:36:39.000000000 +0200
@@ -20,7 +20,8 @@
        qreal resolution(const QPointF &p) const;
 
        qreal zoom() const;
-       qreal zoomFit(const QSize &size, const QRectF &br);
+       qreal zoomFit(const QSize &size, const RectC &br);
+       qreal zoomFit(qreal resolution, const Coordinates &c);
        qreal zoomIn();
        qreal zoomOut();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/config.h new/GPXSee-4.9/src/config.h
--- old/GPXSee-4.8/src/config.h 2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/config.h 2017-07-09 10:36:39.000000000 +0200
@@ -7,7 +7,7 @@
 #include <QString>
 
 #define APP_NAME        "GPXSee"
-#define APP_HOMEPAGE    "http://tumic.wz.cz/gpxsee";
+#define APP_HOMEPAGE    "http://www.gpxsee.org";
 
 #define FONT_FAMILY     "Arial"
 #define FONT_SIZE       12
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/coordinates.cpp 
new/GPXSee-4.9/src/coordinates.cpp
--- old/GPXSee-4.8/src/coordinates.cpp  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/coordinates.cpp  2017-07-09 10:36:39.000000000 +0200
@@ -22,7 +22,7 @@
        dbg.nospace() << "Coordinates(" << coordinates.lon() << ", "
          << coordinates.lat() << ")";
 
-       return dbg.space();
+       return dbg.maybeSpace();
 }
 
 QPair<Coordinates, Coordinates> Coordinates::boundingRect(qreal distance) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/coordinates.h 
new/GPXSee-4.9/src/coordinates.h
--- old/GPXSee-4.8/src/coordinates.h    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/coordinates.h    2017-07-09 10:36:39.000000000 +0200
@@ -2,7 +2,7 @@
 #define COORDINATES_H
 
 #include <cmath>
-#include <QPointF>
+#include <QPair>
 #include <QDebug>
 
 class Coordinates
@@ -12,9 +12,6 @@
        Coordinates(const Coordinates &c) {_lon = c._lon; _lat = c._lat;}
        Coordinates(qreal lon, qreal lat) {_lon = lon; _lat = lat;}
 
-       Coordinates(const QPointF &p) {_lon = p.x(), _lat = p.y();}
-       QPointF toPointF() const {return QPointF(_lon, _lat);}
-
        qreal &rlon() {return _lon;}
        qreal &rlat() {return _lat;}
        void setLon(qreal lon) {_lon = lon;}
@@ -23,10 +20,10 @@
        qreal lat() const {return _lat;}
 
        bool isNull() const
-               {return (std::isnan(_lon) || std::isnan(_lat)) ? true : false;}
+         {return std::isnan(_lon) && std::isnan(_lat);}
        bool isValid() const
-               {return (_lon >= -180.0 && _lon <= 180.0 && _lat >= -90.0
-               && _lat <= 90.0) ? true : false;}
+         {return (_lon >= -180.0 && _lon <= 180.0
+           && _lat >= -90.0 && _lat <= 90.0);}
 
        qreal distanceTo(const Coordinates &c) const;
        QPair<Coordinates, Coordinates> boundingRect(qreal distance) const;
@@ -39,6 +36,7 @@
   {return (c1.lat() == c2.lat() && c1.lon() == c2.lon());}
 inline bool operator!=(const Coordinates &c1, const Coordinates &c2)
   {return !(c1 == c2);}
+
 QDebug operator<<(QDebug dbg, const Coordinates &trackpoint);
 
 #endif // COORDINATES_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/datum.cpp new/GPXSee-4.9/src/datum.cpp
--- old/GPXSee-4.8/src/datum.cpp        2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/datum.cpp        2017-07-09 10:36:39.000000000 +0200
@@ -1,5 +1,7 @@
+#include <cmath>
 #include <QFile>
 #include "wgs84.h"
+#include "rd.h"
 #include "datum.h"
 
 
@@ -81,3 +83,39 @@
 
        return true;
 }
+
+// Abridged Molodensky transformation
+Coordinates Datum::toWGS84(const Coordinates &c) const
+{
+       if (_ellipsoid.radius() == WGS84_RADIUS
+         && _ellipsoid.flattening() == WGS84_FLATTENING
+         && _dx == 0 && _dy == 0 && _dz == 0)
+               return c;
+
+       double rlat = deg2rad(c.lat());
+       double rlon = deg2rad(c.lon());
+
+       double slat = sin(rlat);
+       double clat = cos(rlat);
+       double slon = sin(rlon);
+       double clon = cos(rlon);
+       double ssqlat = slat * slat;
+
+       double from_f = ellipsoid().flattening();
+       double df = WGS84_FLATTENING - from_f;
+       double from_a = ellipsoid().radius();
+       double da = WGS84_RADIUS - from_a;
+       double from_esq = ellipsoid().flattening()
+         * (2.0 - ellipsoid().flattening());
+       double adb = 1.0 / (1.0 - from_f);
+       double rn = from_a / sqrt(1 - from_esq * ssqlat);
+       double rm = from_a * (1 - from_esq) / pow((1 - from_esq * ssqlat), 1.5);
+       double from_h = 0.0;
+
+       double dlat = (-dx() * slat * clon - dy() * slat * slon + dz() * clat + 
da
+         * rn * from_esq * slat * clat / from_a + df * (rm * adb + rn / adb) * 
slat
+         * clat) / (rm + from_h);
+       double dlon = (-dx() * slon + dy() * clon) / ((rn + from_h) * clat);
+
+       return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/datum.h new/GPXSee-4.9/src/datum.h
--- old/GPXSee-4.8/src/datum.h  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/datum.h  2017-07-09 10:36:39.000000000 +0200
@@ -3,6 +3,7 @@
 
 #include <QMap>
 #include "ellipsoid.h"
+#include "coordinates.h"
 
 class Datum
 {
@@ -17,8 +18,8 @@
        double dz() const {return _dz;}
 
        bool isNull() const {return _ellipsoid.isNull();}
-       bool isWGS84() const
-         {return _ellipsoid.isWGS84() && _dx == 0 && _dy == 0 && _dz == 0;}
+
+       Coordinates toWGS84(const Coordinates &c) const;
 
        static bool loadList(const QString &path);
        static const QString &errorString() {return _errorString;}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/ellipsoid.h 
new/GPXSee-4.9/src/ellipsoid.h
--- old/GPXSee-4.8/src/ellipsoid.h      2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/ellipsoid.h      2017-07-09 10:36:39.000000000 +0200
@@ -3,7 +3,6 @@
 
 #include <QString>
 #include <QMap>
-#include "wgs84.h"
 
 class Ellipsoid
 {
@@ -16,8 +15,6 @@
        double flattening() const {return _flattening;}
 
        bool isNull() const {return _radius < 0 || _flattening < 0;}
-       bool isWGS84() const
-         {return _radius == WGS84_RADIUS && _flattening == WGS84_FLATTENING;}
 
        static bool loadList(const QString &path);
        static const QString &errorString() {return _errorString;}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/emptymap.cpp 
new/GPXSee-4.9/src/emptymap.cpp
--- old/GPXSee-4.8/src/emptymap.cpp     2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/emptymap.cpp     2017-07-09 10:36:39.000000000 +0200
@@ -1,5 +1,6 @@
 #include <QtGlobal>
 #include <QPainter>
+#include "rectc.h"
 #include "misc.h"
 #include "rd.h"
 #include "wgs84.h"
@@ -21,22 +22,30 @@
        return scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)), 
1.0/_scale);
 }
 
-qreal EmptyMap::zoomFit(const QSize &size, const QRectF &br)
+qreal EmptyMap::zoomFit(const QSize &size, const RectC &br)
 {
-       if (br.isNull())
+       if (!br.isValid())
                _scale = SCALE_MAX;
        else {
-               Coordinates topLeft(br.topLeft());
-               Coordinates bottomRight(br.bottomRight());
-               QRectF tbr(Mercator().ll2xy(topLeft), 
Mercator().ll2xy(bottomRight));
-
+               QRectF tbr(Mercator().ll2xy(br.topLeft()),
+                 Mercator().ll2xy(br.bottomRight()));
                QPointF sc(tbr.width() / size.width(), tbr.height() / 
size.height());
-
                _scale = qMax(sc.x(), sc.y());
        }
 
        _scale = qMax(_scale, SCALE_MAX);
        _scale = qMin(_scale, SCALE_MIN);
+
+       return _scale;
+}
+
+qreal EmptyMap::zoomFit(qreal resolution, const Coordinates &c)
+{
+       _scale = (360.0 * resolution) / (WGS84_RADIUS * 2 * M_PI
+         * cos(deg2rad(c.lat())));
+
+       _scale = qMax(_scale, SCALE_MAX);
+       _scale = qMin(_scale, SCALE_MIN);
 
        return _scale;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/emptymap.h 
new/GPXSee-4.9/src/emptymap.h
--- old/GPXSee-4.8/src/emptymap.h       2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/emptymap.h       2017-07-09 10:36:39.000000000 +0200
@@ -16,7 +16,8 @@
        qreal resolution(const QPointF &p) const;
 
        qreal zoom() const {return _scale;}
-       qreal zoomFit(const QSize &size, const QRectF &br);
+       qreal zoomFit(const QSize &size, const RectC &br);
+       qreal zoomFit(qreal resolution, const Coordinates &c);
        qreal zoomIn();
        qreal zoomOut();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/gui.cpp new/GPXSee-4.9/src/gui.cpp
--- old/GPXSee-4.8/src/gui.cpp  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/gui.cpp  2017-07-09 10:36:39.000000000 +0200
@@ -295,6 +295,7 @@
        // General actions
        _exitAction = new QAction(QIcon(QPixmap(QUIT_ICON)), tr("Quit"), this);
        _exitAction->setShortcut(QUIT_SHORTCUT);
+       _exitAction->setMenuRole(QAction::QuitRole);
        connect(_exitAction, SIGNAL(triggered()), this, SLOT(close()));
        addAction(_exitAction);
 
@@ -305,6 +306,7 @@
        connect(_keysAction, SIGNAL(triggered()), this, SLOT(keys()));
        _aboutAction = new QAction(QIcon(QPixmap(APP_ICON)),
          tr("About GPXSee"), this);
+       _aboutAction->setMenuRole(QAction::AboutRole);
        connect(_aboutAction, SIGNAL(triggered()), this, SLOT(about()));
 
        // File actions
@@ -477,6 +479,7 @@
          SLOT(showFullscreen(bool)));
        addAction(_fullscreenAction);
        _openOptionsAction = new QAction(tr("Options..."), this);
+       _openOptionsAction->setMenuRole(QAction::PreferencesRole);
        connect(_openOptionsAction, SIGNAL(triggered()), this,
          SLOT(openOptions()));
 
@@ -647,6 +650,7 @@
 void GUI::about()
 {
        QMessageBox msgBox(this);
+       QUrl homepage(APP_HOMEPAGE);
 
        msgBox.setWindowTitle(tr("About GPXSee"));
        msgBox.setText("<h2>" + QString(APP_NAME) + "</h2><p><p>" + tr("Version 
")
@@ -654,7 +658,8 @@
        msgBox.setInformativeText("<table width=\"300\"><tr><td>"
          + tr("GPXSee is distributed under the terms of the GNU General Public 
"
          "License version 3. For more info about GPXSee visit the project "
-         "homepage at ") + "<a href=\"" + APP_HOMEPAGE + "\">" + APP_HOMEPAGE
+         "homepage at ") + "<a href=\"" + homepage.toString() + "\">"
+         + homepage.toString(QUrl::RemoveScheme).mid(2)
          + "</a>.</td></tr></table>");
 
        QIcon icon = msgBox.windowIcon();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/latlon.h new/GPXSee-4.9/src/latlon.h
--- old/GPXSee-4.8/src/latlon.h 2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/latlon.h 2017-07-09 10:36:39.000000000 +0200
@@ -7,9 +7,9 @@
 {
 public:
        virtual QPointF ll2xy(const Coordinates &c) const
-         {return c.toPointF();}
+         {return QPointF(c.lon(), c.lat());}
        virtual Coordinates xy2ll(const QPointF &p) const
-         {return Coordinates(p);}
+         {return Coordinates(p.x(), p.y());}
 };
 
 #endif // LATLON_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/map.h new/GPXSee-4.9/src/map.h
--- old/GPXSee-4.8/src/map.h    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/map.h    2017-07-09 10:36:39.000000000 +0200
@@ -7,6 +7,7 @@
 
 class QPainter;
 class Coordinates;
+class RectC;
 
 class Map : public QObject
 {
@@ -21,7 +22,8 @@
        virtual qreal resolution(const QPointF &p) const = 0;
 
        virtual qreal zoom() const = 0;
-       virtual qreal zoomFit(const QSize &size, const QRectF &br) = 0;
+       virtual qreal zoomFit(const QSize &size, const RectC &br) = 0;
+       virtual qreal zoomFit(qreal resolution, const Coordinates &c) = 0;
        virtual qreal zoomIn() = 0;
        virtual qreal zoomOut() = 0;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/offlinemap.cpp 
new/GPXSee-4.9/src/offlinemap.cpp
--- old/GPXSee-4.8/src/offlinemap.cpp   2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/offlinemap.cpp   2017-07-09 10:36:39.000000000 +0200
@@ -23,39 +23,6 @@
 #include "offlinemap.h"
 
 
-// Abridged Molodensky transformation
-static Coordinates toWGS84(Coordinates c, const Datum &datum)
-{
-       double rlat = deg2rad(c.lat());
-       double rlon = deg2rad(c.lon());
-
-       double slat = sin(rlat);
-       double clat = cos(rlat);
-       double slon = sin(rlon);
-       double clon = cos(rlon);
-       double ssqlat = slat * slat;
-
-       double from_f = datum.ellipsoid().flattening();
-       double df = WGS84_FLATTENING - from_f;
-       double from_a = datum.ellipsoid().radius();
-       double da = WGS84_RADIUS - from_a;
-       double from_esq = datum.ellipsoid().flattening()
-         * (2.0 - datum.ellipsoid().flattening());
-       double adb = 1.0 / (1.0 - from_f);
-       double rn = from_a / sqrt(1 - from_esq * ssqlat);
-       double rm = from_a * (1 - from_esq) / pow((1 - from_esq * ssqlat), 1.5);
-       double from_h = 0.0;
-
-       double dlat = (-datum.dx() * slat * clon - datum.dy() * slat * slon
-         + datum.dz() * clat + da * rn * from_esq * slat * clat / from_a + df
-         * (rm * adb + rn / adb) * slat * clat) / (rm + from_h);
-       double dlon = (-datum.dx() * slon + datum.dy() * clon) / ((rn + from_h)
-         * clat);
-
-       return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
-}
-
-
 int OfflineMap::parse(QIODevice &device, QList<ReferencePoint> &points,
   QString &projection, ProjectionSetup &setup, QString &datum)
 {
@@ -263,15 +230,10 @@
        }
 
        for (int i = 0; i < points.size(); i++) {
-               if (points.at(i).ll.isNull()) {
-                       if (d.isWGS84())
-                               points[i].ll = 
_projection->xy2ll(points.at(i).pp);
-                       else
-                               points[i].ll = 
toWGS84(_projection->xy2ll(points.at(i).pp), d);
-               } else {
-                       if (!d.isWGS84())
-                               points[i].ll = toWGS84(points[i].ll, d);
-               }
+               if (points.at(i).ll.isNull())
+                       points[i].ll = 
d.toWGS84(_projection->xy2ll(points.at(i).pp));
+               else
+                       points[i].ll = d.toWGS84(points[i].ll);
        }
 
        return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/offlinemap.h 
new/GPXSee-4.9/src/offlinemap.h
--- old/GPXSee-4.8/src/offlinemap.h     2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/offlinemap.h     2017-07-09 10:36:39.000000000 +0200
@@ -26,10 +26,11 @@
        QRectF bounds() const {return QRectF(QPointF(0, 0), _size);}
        qreal resolution(const QPointF &) const {return _resolution;}
 
-       qreal zoom() const {return 1.0;}
-       qreal zoomFit(const QSize &, const QRectF &) {return 1.0;}
-       qreal zoomIn() {return 1.0;}
-       qreal zoomOut() {return 1.0;}
+       qreal zoom() const {return 0;}
+       qreal zoomFit(const QSize &, const RectC &) {return 0;}
+       qreal zoomFit(qreal, const Coordinates &) {return 0;}
+       qreal zoomIn() {return 0;}
+       qreal zoomOut() {return 0;}
 
        QPointF ll2xy(const Coordinates &c)
          {return _transform.map(_projection->ll2xy(c));}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/onlinemap.cpp 
new/GPXSee-4.9/src/onlinemap.cpp
--- old/GPXSee-4.8/src/onlinemap.cpp    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/onlinemap.cpp    2017-07-09 10:36:39.000000000 +0200
@@ -1,6 +1,7 @@
 #include <QFileInfo>
 #include <QDir>
 #include <QPainter>
+#include "rectc.h"
 #include "downloader.h"
 #include "config.h"
 #include "rd.h"
@@ -25,16 +26,14 @@
        return tile;
 }
 
-static int scale2zoom(qreal scale)
+static qreal zoom2scale(int zoom)
 {
-       int zoom = (int)log2(360.0/(scale * (qreal)TILE_SIZE));
-
-       if (zoom < ZOOM_MIN)
-               return ZOOM_MIN;
-       if (zoom > ZOOM_MAX)
-               return ZOOM_MAX;
+       return (360.0/(qreal)((1<<zoom) * TILE_SIZE));
+}
 
-       return zoom;
+static int scale2zoom(qreal scale)
+{
+       return (int)log2(360.0/(scale * (qreal)TILE_SIZE));
 }
 
 
@@ -46,7 +45,7 @@
        _name = name;
        _url = url;
        _block = false;
-       _scale = ((360.0/(qreal)(1<<ZOOM_MAX))/(qreal)TILE_SIZE);
+       _zoom = ZOOM_MAX;
 
        connect(downloader, SIGNAL(finished()), this, SLOT(emitLoaded()));
 
@@ -163,53 +162,68 @@
 
 QRectF OnlineMap::bounds() const
 {
-       return scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)), 
1.0/_scale);
+       return scaled(QRectF(QPointF(-180, -180), QSizeF(360, 360)),
+         1.0/zoom2scale(_zoom));
 }
 
-qreal OnlineMap::zoomFit(const QSize &size, const QRectF &br)
+qreal OnlineMap::zoomFit(const QSize &size, const RectC &br)
 {
-       if (br.isNull())
-               _scale = ((360.0/(qreal)(1<<ZOOM_MAX))/(qreal)TILE_SIZE);
+       if (!br.isValid())
+               _zoom = ZOOM_MAX;
        else {
-               Coordinates topLeft(br.topLeft());
-               Coordinates bottomRight(br.bottomRight());
-               QRectF tbr(Mercator().ll2xy(topLeft), 
Mercator().ll2xy(bottomRight));
-
+               QRectF tbr(Mercator().ll2xy(br.topLeft()),
+                 Mercator().ll2xy(br.bottomRight()));
                QPointF sc(tbr.width() / size.width(), tbr.height() / 
size.height());
 
-               _scale = ((360.0/(qreal)(1<<scale2zoom(qMax(sc.x(), sc.y()))))
-                 / (qreal)TILE_SIZE);
+               _zoom = scale2zoom(qMax(sc.x(), sc.y()));
+               if (_zoom < ZOOM_MIN)
+                       _zoom = ZOOM_MIN;
+               if (_zoom > ZOOM_MAX)
+                       _zoom = ZOOM_MAX;
        }
 
-       return _scale;
+       return _zoom;
+}
+
+qreal OnlineMap::zoomFit(qreal resolution, const Coordinates &c)
+{
+       _zoom = (int)(log2((WGS84_RADIUS * 2 * M_PI * cos(deg2rad(c.lat())))
+         / resolution) - log2(TILE_SIZE));
+
+       if (_zoom < ZOOM_MIN)
+               _zoom = ZOOM_MIN;
+       if (_zoom > ZOOM_MAX)
+               _zoom = ZOOM_MAX;
+
+       return _zoom;
 }
 
 qreal OnlineMap::resolution(const QPointF &p) const
 {
-       return (WGS84_RADIUS * 2 * M_PI * _scale / 360.0
-         * cos(2.0 * atan(exp(deg2rad(-p.y() * _scale))) - M_PI/2));
+       qreal scale = zoom2scale(_zoom);
+
+       return (WGS84_RADIUS * 2 * M_PI * scale / 360.0
+         * cos(2.0 * atan(exp(deg2rad(-p.y() * scale))) - M_PI/2));
 }
 
 qreal OnlineMap::zoomIn()
 {
-       int zoom = qMin(scale2zoom(_scale) + 1, ZOOM_MAX);
-       _scale = ((360.0/(qreal)(1<<zoom))/(qreal)TILE_SIZE);
-       return _scale;
+       _zoom = qMin(_zoom + 1, ZOOM_MAX);
+       return _zoom;
 }
 
 qreal OnlineMap::zoomOut()
 {
-       int zoom = qMax(scale2zoom(_scale) - 1, ZOOM_MIN);
-       _scale = ((360.0/(qreal)(1<<zoom))/(qreal)TILE_SIZE);
-       return _scale;
+       _zoom = qMax(_zoom - 1, ZOOM_MIN);
+       return _zoom;
 }
 
 void OnlineMap::draw(QPainter *painter, const QRectF &rect)
 {
-       int zoom = scale2zoom(_scale);
+       qreal scale = zoom2scale(_zoom);
 
-       QPoint tile = mercator2tile(QPointF(rect.topLeft().x() * _scale,
-         -rect.topLeft().y() * _scale), zoom);
+       QPoint tile = mercator2tile(QPointF(rect.topLeft().x() * scale,
+         -rect.topLeft().y() * scale), _zoom);
        QPoint tl = QPoint((int)floor(rect.left() / (qreal)TILE_SIZE)
          * TILE_SIZE, (int)floor(rect.top() / TILE_SIZE) * TILE_SIZE);
 
@@ -217,7 +231,7 @@
        QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
        for (int i = 0; i < ceil(s.width() / TILE_SIZE); i++)
                for (int j = 0; j < ceil(s.height() / TILE_SIZE); j++)
-                       tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), 
zoom));
+                       tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), 
_zoom));
 
        if (_block)
                loadTilesSync(tiles);
@@ -234,12 +248,14 @@
 
 QPointF OnlineMap::ll2xy(const Coordinates &c)
 {
+       qreal scale = zoom2scale(_zoom);
        QPointF m = Mercator().ll2xy(c);
-       return QPointF(m.x() / _scale, m.y() / -_scale);
+       return QPointF(m.x() / scale, m.y() / -scale);
 }
 
 Coordinates OnlineMap::xy2ll(const QPointF &p)
 {
-       QPointF m(p.x() * _scale, -p.y() * _scale);
+       qreal scale = zoom2scale(_zoom);
+       QPointF m(p.x() * scale, -p.y() * scale);
        return Mercator().xy2ll(m);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/onlinemap.h 
new/GPXSee-4.9/src/onlinemap.h
--- old/GPXSee-4.8/src/onlinemap.h      2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/onlinemap.h      2017-07-09 10:36:39.000000000 +0200
@@ -18,8 +18,9 @@
        QRectF bounds() const;
        qreal resolution(const QPointF &p) const;
 
-       qreal zoom() const {return _scale;}
-       qreal zoomFit(const QSize &size, const QRectF &br);
+       qreal zoom() const {return _zoom;}
+       qreal zoomFit(const QSize &size, const RectC &br);
+       qreal zoomFit(qreal resolution, const Coordinates &c);
        qreal zoomIn();
        qreal zoomOut();
 
@@ -45,7 +46,7 @@
        void loadTilesAsync(QList<Tile> &list);
        void loadTilesSync(QList<Tile> &list);
 
-       qreal _scale;
+       int _zoom;
        QString _name;
        QString _url;
        bool _block;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/path.cpp new/GPXSee-4.9/src/path.cpp
--- old/GPXSee-4.8/src/path.cpp 2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/path.cpp 2017-07-09 10:36:39.000000000 +0200
@@ -1,27 +1,15 @@
 #include "path.h"
 
-QRectF Path::boundingRect() const
+RectC Path::boundingRect() const
 {
        if (size() < 2)
-               return QRectF();
+               return RectC();
 
-       QPointF topLeft(at(0).coordinates().lon(), at(0).coordinates().lat());
-       QPointF bottomRight(topLeft);
+       RectC ret(first().coordinates(), first().coordinates());
+       for (int i = 1; i < size(); i++)
+               ret.unite(at(i).coordinates());
 
-       for (int i = 1; i < size(); i++) {
-               qreal x = at(i).coordinates().lon();
-               qreal y = at(i).coordinates().lat();
-
-               if (x < topLeft.x())
-                       topLeft.setX(x);
-               if (y < topLeft.y())
-                       topLeft.setY(y);
-               if (x > bottomRight.x())
-                       bottomRight.setX(x);
-               if (y > bottomRight.y())
-                       bottomRight.setY(y);
-       }
-       return QRectF(topLeft, bottomRight);
+       return ret;
 }
 
 QDebug operator<<(QDebug dbg, const PathPoint &point)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/path.h new/GPXSee-4.9/src/path.h
--- old/GPXSee-4.8/src/path.h   2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/path.h   2017-07-09 10:36:39.000000000 +0200
@@ -4,6 +4,7 @@
 #include <QVector>
 #include <QRectF>
 #include "coordinates.h"
+#include "rectc.h"
 
 class PathPoint
 {
@@ -28,7 +29,7 @@
 class Path : public QVector<PathPoint>
 {
 public:
-       QRectF boundingRect() const;
+       RectC boundingRect() const;
 };
 
 #endif // PATH_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/pathview.cpp 
new/GPXSee-4.9/src/pathview.cpp
--- old/GPXSee-4.8/src/pathview.cpp     2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/pathview.cpp     2017-07-09 10:36:39.000000000 +0200
@@ -8,7 +8,6 @@
 #include "poi.h"
 #include "data.h"
 #include "map.h"
-#include "emptymap.h"
 #include "trackitem.h"
 #include "routeitem.h"
 #include "waypointitem.h"
@@ -16,25 +15,14 @@
 #include "keys.h"
 #include "pathview.h"
 
-#define MAX_ZOOM      1
-#define MIN_ZOOM      -3
-#define MARGIN        10.0
-#define SCALE_OFFSET  7
-
-static void unite(QRectF &rect, const QPointF &p)
-{
-       if (p.x() < rect.left())
-               rect.setLeft(p.x());
-       if (p.x() > rect.right())
-               rect.setRight(p.x());
-       if (p.y() > rect.bottom())
-               rect.setBottom(p.y());
-       if (p.y() < rect.top())
-               rect.setTop(p.y());
-}
+
+#define MAX_DIGITAL_ZOOM 1
+#define MIN_DIGITAL_ZOOM -3
+#define MARGIN           10.0
+#define SCALE_OFFSET     7
 
 PathView::PathView(Map *map, POI *poi, QWidget *parent)
-       : QGraphicsView(parent)
+: QGraphicsView(parent)
 {
        Q_ASSERT(map != 0);
        Q_ASSERT(poi != 0);
@@ -141,8 +129,7 @@
 
                WaypointItem *wi = new WaypointItem(w, _map);
                _waypoints.append(wi);
-               Coordinates c = wi->waypoint().coordinates();
-               updateWaypointsBoundingRect(QPointF(c.lon(), c.lat()));
+               updateWaypointsBoundingRect(wi->waypoint().coordinates());
                wi->setZValue(1);
                wi->showLabel(_showWaypointLabels);
                wi->setUnits(_units);
@@ -184,43 +171,31 @@
        return paths;
 }
 
-void PathView::updateWaypointsBoundingRect(const QPointF &wp)
+void PathView::updateWaypointsBoundingRect(const Coordinates &wp)
 {
-       if (_wr.isNull()) {
-               if (_wp.isNull())
-                       _wp = wp;
-               else {
-                       _wr = QRectF(_wp, wp).normalized();
-                       _wp = QPointF();
-               }
-       } else
-               unite(_wr, wp);
+       if (_wr.isNull())
+               _wr = RectC(wp, wp);
+       else
+               _wr.unite(wp);
 }
 
 qreal PathView::mapScale() const
 {
-       QRectF br = _tr | _rr | _wr;
-       if (!br.isNull() && !_wp.isNull())
-               unite(br, _wp);
+       RectC br = _tr | _rr | _wr;
 
        return _map->zoomFit(viewport()->size() - QSize(MARGIN/2, MARGIN/2), 
br);
 }
 
 QPointF PathView::contentCenter() const
 {
-       QRectF br = _tr | _rr | _wr;
-       if (!br.isNull() && !_wp.isNull())
-               unite(br, _wp);
+       RectC br = _tr | _rr | _wr;
 
-       if (br.isNull())
-               return _map->ll2xy(_wp);
-       else
-               return _map->ll2xy(br.center());
+       return _map->ll2xy(br.center());
 }
 
 void PathView::updatePOIVisibility()
 {
-       QHash<Waypoint, WaypointItem*>::const_iterator it, jt;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it, jt;
 
        if (!_showPOI)
                return;
@@ -251,7 +226,7 @@
        for (int i = 0; i < _waypoints.size(); i++)
                _waypoints.at(i)->setMap(_map);
 
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
                it.value()->setMap(_map);
 
@@ -271,6 +246,10 @@
 
 void PathView::setMap(Map *map)
 {
+       QPointF pos = mapToScene(viewport()->rect().center());
+       Coordinates center = _map->xy2ll(pos);
+       qreal resolution = _map->resolution(pos);
+
        _map->unload();
        disconnect(_map, SIGNAL(loaded()), this, SLOT(redraw()));
 
@@ -280,7 +259,7 @@
 
        resetDigitalZoom();
 
-       mapScale();
+       _map->zoomFit(resolution, center);
        _scene->setSceneRect(_map->bounds());
 
        for (int i = 0; i < _tracks.size(); i++)
@@ -290,15 +269,15 @@
        for (int i = 0; i < _waypoints.size(); i++)
                _waypoints.at(i)->setMap(map);
 
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
                it.value()->setMap(_map);
        updatePOIVisibility();
 
-       QPointF center = contentCenter();
-       centerOn(center);
+       pos = _map->ll2xy(center);
+       centerOn(pos);
 
-       _res = _map->resolution(center);
+       _res = _map->resolution(pos);
        _mapScale->setResolution(_res);
 
        resetCachedContent();
@@ -317,7 +296,7 @@
 
 void PathView::updatePOI()
 {
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
 
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++) {
                _scene->removeItem(it.value());
@@ -339,7 +318,7 @@
        for (int i = 0; i < waypoints.size(); i++) {
                const Waypoint &w = waypoints.at(i);
 
-               if (_pois.contains(w))
+               if (_pois.contains(SearchPointer<Waypoint>(&w)))
                        continue;
 
                WaypointItem *pi = new WaypointItem(w, _map);
@@ -349,7 +328,7 @@
                pi->setDigitalZoom(_digitalZoom);
                _scene->addItem(pi);
 
-               _pois.insert(w, pi);
+               _pois.insert(SearchPointer<Waypoint>(&(pi->waypoint())), pi);
        }
 }
 
@@ -366,7 +345,7 @@
        for (int i = 0; i < _waypoints.size(); i++)
                _waypoints.at(i)->setUnits(units);
 
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
                it.value()->setUnits(units);
 }
@@ -378,7 +357,7 @@
 
 void PathView::resetDigitalZoom()
 {
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
 
        _digitalZoom = 0;
        resetTransform();
@@ -397,7 +376,7 @@
 
 void PathView::digitalZoom(int zoom)
 {
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
 
        _digitalZoom += zoom;
        scale(pow(2, zoom), pow(2, zoom));
@@ -420,8 +399,8 @@
 
        if (_digitalZoom) {
                if (((_digitalZoom > 0 && zoom > 0) && (!shift || _digitalZoom
-                 >= MAX_ZOOM)) || ((_digitalZoom < 0 && zoom < 0) && (!shift
-                 || _digitalZoom <= MIN_ZOOM)))
+                 >= MAX_DIGITAL_ZOOM)) || ((_digitalZoom < 0 && zoom < 0) && 
(!shift
+                 || _digitalZoom <= MIN_DIGITAL_ZOOM)))
                        return;
 
                digitalZoom(zoom);
@@ -473,7 +452,7 @@
 {
        int z;
 
-       QPoint pos = QRect(QPoint(), viewport()->size()).center();
+       QPoint pos = viewport()->rect().center();
        Coordinates c = _map->xy2ll(mapToScene(pos));
 
        if (event->matches(ZOOM_IN))
@@ -539,8 +518,9 @@
        _scene->clear();
        _palette.reset();
 
-       _tr = QRectF(); _rr = QRectF(); _wr = QRectF();
-       _wp = QPointF();
+       _tr = RectC();
+       _rr = RectC();
+       _wr = RectC();
 
        resetDigitalZoom();
        resetCachedContent();
@@ -600,7 +580,7 @@
 {
        _showPOI = show;
 
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
                it.value()->setVisible(show);
 
@@ -611,7 +591,7 @@
 {
        _showPOILabels = show;
 
-       QHash<Waypoint, WaypointItem*>::const_iterator it;
+       QHash<SearchPointer<Waypoint>, WaypointItem*>::const_iterator it;
        for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
                it.value()->showLabel(show);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/pathview.h 
new/GPXSee-4.9/src/pathview.h
--- old/GPXSee-4.8/src/pathview.h       2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/pathview.h       2017-07-09 10:36:39.000000000 +0200
@@ -8,6 +8,8 @@
 #include "units.h"
 #include "palette.h"
 #include "waypoint.h"
+#include "rectc.h"
+#include "searchpointer.h"
 
 class Data;
 class POI;
@@ -80,7 +82,7 @@
        void digitalZoom(int zoom);
        void resetDigitalZoom();
        void updatePOIVisibility();
-       void updateWaypointsBoundingRect(const QPointF &wp);
+       void updateWaypointsBoundingRect(const Coordinates &wp);
 
        void mouseDoubleClickEvent(QMouseEvent *event);
        void wheelEvent(QWheelEvent *event);
@@ -95,10 +97,9 @@
        QList<TrackItem*> _tracks;
        QList<RouteItem*> _routes;
        QList<WaypointItem*> _waypoints;
-       QHash<Waypoint, WaypointItem*> _pois;
+       QHash<SearchPointer<Waypoint>, WaypointItem*> _pois;
 
-       QRectF _tr, _rr, _wr;
-       QPointF _wp;
+       RectC _tr, _rr, _wr;
        qreal _res;
 
        Map *_map;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/rectc.cpp new/GPXSee-4.9/src/rectc.cpp
--- old/GPXSee-4.8/src/rectc.cpp        1970-01-01 01:00:00.000000000 +0100
+++ new/GPXSee-4.9/src/rectc.cpp        2017-07-09 10:36:39.000000000 +0200
@@ -0,0 +1,63 @@
+#include "rectc.h"
+
+RectC RectC::operator|(const RectC &r) const
+{
+       if (isNull())
+               return r;
+       if (r.isNull())
+               return *this;
+
+       qreal l1 = _tl.lon();
+       qreal r1 = _tl.lon();
+       if (_br.lon() - _tl.lon() < 0)
+               l1 = _br.lon();
+       else
+               r1 = _br.lon();
+
+       qreal l2 = r._tl.lon();
+       qreal r2 = r._tl.lon();
+       if (r._br.lon() - r._tl.lon() < 0)
+               l2 = r._br.lon();
+       else
+               r2 = r._br.lon();
+
+       qreal t1 = _tl.lat();
+       qreal b1 = _tl.lat();
+       if (_br.lat() - _tl.lat() < 0)
+               t1 = _br.lat();
+       else
+               b1 = _br.lat();
+
+       qreal t2 = r._tl.lat();
+       qreal b2 = r._tl.lat();
+       if (r._br.lat() - r._tl.lat() < 0)
+               t2 = r._br.lat();
+       else
+               b2 = r._br.lat();
+
+       RectC tmp;
+       tmp._tl.setLon(qMin(l1, l2));
+       tmp._br.setLon(qMax(r1, r2));
+       tmp._tl.setLat(qMin(t1, t2));
+       tmp._br.setLat(qMax(b1, b2));
+
+       return tmp;
+}
+
+void RectC::unite(const Coordinates &c)
+{
+       if (c.lon() < _tl.lon())
+               _tl.setLon(c.lon());
+       if (c.lon() > _br.lon())
+               _br.setLon(c.lon());
+       if (c.lat() > _br.lat())
+               _br.setLat(c.lat());
+       if (c.lat() < _tl.lat())
+               _tl.setLat(c.lat());
+}
+
+QDebug operator<<(QDebug dbg, const RectC &rect)
+{
+       dbg.nospace() << "RectC(" << rect.topLeft() << ", " << rect.size() << 
")";
+       return dbg.maybeSpace();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/rectc.h new/GPXSee-4.9/src/rectc.h
--- old/GPXSee-4.8/src/rectc.h  1970-01-01 01:00:00.000000000 +0100
+++ new/GPXSee-4.9/src/rectc.h  2017-07-09 10:36:39.000000000 +0200
@@ -0,0 +1,42 @@
+#ifndef RECTC_H
+#define RECTC_H
+
+#include <QDebug>
+#include <QSizeF>
+#include "coordinates.h"
+
+class RectC
+{
+public:
+       RectC() {}
+       RectC(const Coordinates &topLeft, const Coordinates &bottomRight)
+         : _tl(topLeft), _br(bottomRight) {}
+
+       bool isNull() const
+         {return _tl.isNull() && _br.isNull();}
+       bool isValid() const
+         {return (_tl.isValid() && _br.isValid() && _tl != _br);}
+
+       Coordinates topLeft() const {return _tl;}
+       Coordinates bottomRight() const {return _br;}
+
+       Coordinates center() const
+         {return Coordinates((_tl.lon() + _br.lon()) / 2.0,
+           (_tl.lat() + _br.lat()) / 2.0);}
+       qreal width() const {return  _br.lon() - _tl.lon();}
+       qreal height() const {return  _br.lat() - _tl.lat();}
+
+       QSizeF size() const {return QSizeF(width(), height());}
+
+       RectC operator|(const RectC &r) const;
+       RectC &operator|=(const RectC &r) {*this = *this | r; return *this;}
+
+       void unite(const Coordinates &c);
+
+private:
+       Coordinates _tl, _br;
+};
+
+QDebug operator<<(QDebug dbg, const RectC &rect);
+
+#endif // RECTC_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/searchpointer.h 
new/GPXSee-4.9/src/searchpointer.h
--- old/GPXSee-4.8/src/searchpointer.h  1970-01-01 01:00:00.000000000 +0100
+++ new/GPXSee-4.9/src/searchpointer.h  2017-07-09 10:36:39.000000000 +0200
@@ -0,0 +1,24 @@
+#ifndef SEARCHPOINTER_H
+#define SEARCHPOINTER_H
+
+template <class T>
+class SearchPointer
+{
+public:
+       SearchPointer(const T *ptr) : _ptr(ptr) {}
+
+       const T *data() const {return _ptr;}
+       bool operator==(const SearchPointer<T> &other) const
+         {return *data() == *(other.data());}
+
+private:
+       const T *_ptr;
+};
+
+template <class T>
+inline uint qHash(const SearchPointer<T> &t)
+{
+       return ::qHash(*(t.data()));
+}
+
+#endif // SEARCHPOINTER_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/tar.cpp new/GPXSee-4.9/src/tar.cpp
--- old/GPXSee-4.8/src/tar.cpp  2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/tar.cpp  2017-07-09 10:36:39.000000000 +0200
@@ -1,5 +1,6 @@
 #include <cctype>
 #include <QFile>
+#include <QFileInfo>
 #include "tar.h"
 
 
@@ -29,7 +30,7 @@
                                      /* 500 */
 };
 
-static quint64 number(const char* data, size_t size)
+static quint64 number(const char* data, size_t size, int base = 8)
 {
        const char *sp;
        quint64 val = 0;
@@ -38,18 +39,13 @@
                if (isdigit(*sp))
                        break;
        for (; sp < data + size && isdigit(*sp); sp++)
-               val = val * 8 + *sp - '0';
+               val = val * base + *sp - '0';
 
        return val;
 }
 
 bool Tar::load(const QString &path)
 {
-       char buffer[BLOCKSIZE];
-       struct Header *hdr = (struct Header*)&buffer;
-       quint64 size;
-       qint64 ret;
-
        if (_file.isOpen())
                _file.close();
        _index.clear();
@@ -58,16 +54,33 @@
        if (!_file.open(QIODevice::ReadOnly))
                return false;
 
+       QFileInfo fi(path);
+       QString tmiPath = fi.path() + "/" + fi.completeBaseName() + ".tmi";
+
+       if (loadTmi(tmiPath))
+               return true;
+       else
+               return loadTar();
+}
+
+bool Tar::loadTar()
+{
+       char buffer[BLOCKSIZE];
+       struct Header *hdr = (struct Header*)&buffer;
+       quint64 size;
+       qint64 ret;
+
        while ((ret = _file.read(buffer, BLOCKSIZE)) > 0) {
                if (ret < BLOCKSIZE) {
                        _file.close();
+                       _index.clear();
                        return false;
                }
                size = number(hdr->size, sizeof(hdr->size));
-               if (size)
-                       _index.insert(hdr->name, Info(size, _file.pos()));
+               _index.insert(hdr->name, _file.pos() / BLOCKSIZE - 1);
                if (!_file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE)) {
                        _file.close();
+                       _index.clear();
                        return false;
                }
        }
@@ -75,15 +88,49 @@
        return true;
 }
 
+bool Tar::loadTmi(const QString &path)
+{
+       quint64 block;
+       int ln = 1;
+
+       QFile file(path);
+       if (!file.open(QIODevice::ReadOnly))
+               return false;
+
+       while (!file.atEnd()) {
+               QByteArray line = file.readLine();
+               int pos = line.indexOf(':');
+               if (line.size() < 10 || pos < 7 || !line.startsWith("block")) {
+                       qWarning("%s:%d: syntax error\n", qPrintable(path), ln);
+                       _index.clear();
+                       return false;
+               }
+               block = number(line.constData() + 6, line.size() - 6, 10);
+               QString file(line.mid(pos + 1).trimmed());
+
+               _index.insert(file, block);
+               ln++;
+       }
+
+       return true;
+}
+
 QByteArray Tar::file(const QString &name)
 {
-       QMap<QString, Tar::Info>::const_iterator it = _index.find(name);
+       char buffer[BLOCKSIZE];
+       struct Header *hdr = (struct Header*)&buffer;
+       quint64 size;
+
+       QMap<QString, quint64>::const_iterator it = _index.find(name);
        if (it == _index.end())
                return QByteArray();
 
        Q_ASSERT(_file.isOpen());
-       if (_file.seek(it.value().offset()))
-               return _file.read(it.value().size());
-       else
+       if (_file.seek(it.value() * BLOCKSIZE)) {
+               if (_file.read(buffer, BLOCKSIZE) < BLOCKSIZE)
+                       return QByteArray();
+               size = number(hdr->size, sizeof(hdr->size));
+               return _file.read(size);
+       } else
                return QByteArray();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/tar.h new/GPXSee-4.9/src/tar.h
--- old/GPXSee-4.8/src/tar.h    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/tar.h    2017-07-09 10:36:39.000000000 +0200
@@ -17,20 +17,11 @@
        bool isOpen() const {return _file.isOpen();}
 
 private:
-       class Info
-       {
-       public:
-               Info(quint64 size, quint64 offset) : _size(size),  
_offset(offset) {}
-               quint64 size() const {return _size;}
-               quint64 offset() const {return _offset;}
-
-       private:
-               quint64 _size;
-               quint64 _offset;
-       };
+       bool loadTar();
+       bool loadTmi(const QString &path);
 
        QFile _file;
-       QMap<QString, Info> _index;
+       QMap<QString, quint64> _index;
 };
 
 #endif // TAR_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/GPXSee-4.8/src/tcxparser.cpp 
new/GPXSee-4.9/src/tcxparser.cpp
--- old/GPXSee-4.8/src/tcxparser.cpp    2017-05-25 01:55:09.000000000 +0200
+++ new/GPXSee-4.9/src/tcxparser.cpp    2017-07-09 10:36:39.000000000 +0200
@@ -112,7 +112,7 @@
                if (_reader.name() == "Trackpoint") {
                        Trackpoint t;
                        trackpointData(t);
-                       if (!t.coordinates().isNull())
+                       if (t.coordinates().isValid())
                                track.append(t);
                        else
                                warning("Missing Trackpoint coordinates");
@@ -143,7 +143,7 @@
                else if (_reader.name() == "CoursePoint") {
                        Waypoint w;
                        waypointData(w);
-                       if (!w.coordinates().isNull())
+                       if (w.coordinates().isValid())
                                _waypoints.append(w);
                        else
                                warning("Missing Trackpoint coordinates");

++++++ debian.changelog ++++++
--- /var/tmp/diff_new_pack.Cx5JVI/_old  2017-07-12 19:36:18.197828691 +0200
+++ /var/tmp/diff_new_pack.Cx5JVI/_new  2017-07-12 19:36:18.197828691 +0200
@@ -1,3 +1,12 @@
+gpxsee (4.9) stable; urgency=low
+
+  * Improved map switching (no more track resizing on map change).
+  * Improved TARed Trekbuddy maps loading (now using TMI index
+    files if available).
+  * Optimized POI handling.
+
+ -- Martin Tuma <tu...@cbox.cz>  Tue, 11 Jul 2017 23:48:15 +0200
+
 gpxsee (4.8) stable; urgency=low
 
   * Added data filtering settings.

++++++ gpxsee.dsc ++++++
--- /var/tmp/diff_new_pack.Cx5JVI/_old  2017-07-12 19:36:18.289815697 +0200
+++ /var/tmp/diff_new_pack.Cx5JVI/_new  2017-07-12 19:36:18.289815697 +0200
@@ -1,9 +1,9 @@
 Format: 1.0
 Source: gpxsee
-Version: 4.8
+Version: 4.9
 Binary: gpxsee
 Maintainer: Martin Tuma <tu...@cbox.cz>
 Architecture: any
 Build-Depends: debhelper (>= 9), qtbase5-dev, qtbase5-dev-tools, qt5-qmake, 
qttools5-dev-tools, libqt5opengl5-dev
 Files:
- 00000000000000000000000000000000 0 GPXSee-4.8.tar.gz
+ 00000000000000000000000000000000 0 GPXSee-4.9.tar.gz


Reply via email to