mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Added "runtime" offline map loading
Offline map loading & error handling cleanup
This commit is contained in:
parent
610ac3d73f
commit
0808f6679e
10
gpxsee.pro
10
gpxsee.pro
@ -23,7 +23,6 @@ HEADERS += src/config.h \
|
|||||||
src/filebrowser.h \
|
src/filebrowser.h \
|
||||||
src/map.h \
|
src/map.h \
|
||||||
src/onlinemap.h \
|
src/onlinemap.h \
|
||||||
src/maplist.h \
|
|
||||||
src/downloader.h \
|
src/downloader.h \
|
||||||
src/units.h \
|
src/units.h \
|
||||||
src/scaleitem.h \
|
src/scaleitem.h \
|
||||||
@ -81,7 +80,6 @@ HEADERS += src/config.h \
|
|||||||
src/timetype.h \
|
src/timetype.h \
|
||||||
src/emptymap.h \
|
src/emptymap.h \
|
||||||
src/offlinemap.h \
|
src/offlinemap.h \
|
||||||
src/mapdir.h \
|
|
||||||
src/matrix.h \
|
src/matrix.h \
|
||||||
src/tar.h \
|
src/tar.h \
|
||||||
src/atlas.h \
|
src/atlas.h \
|
||||||
@ -93,7 +91,8 @@ HEADERS += src/config.h \
|
|||||||
src/lambertconic.h \
|
src/lambertconic.h \
|
||||||
src/ellipsoid.h \
|
src/ellipsoid.h \
|
||||||
src/ozf.h \
|
src/ozf.h \
|
||||||
src/datum.h
|
src/datum.h \
|
||||||
|
src/maplist.h
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
src/gui.cpp \
|
src/gui.cpp \
|
||||||
src/poi.cpp \
|
src/poi.cpp \
|
||||||
@ -106,7 +105,6 @@ SOURCES += src/main.cpp \
|
|||||||
src/sliderinfoitem.cpp \
|
src/sliderinfoitem.cpp \
|
||||||
src/filebrowser.cpp \
|
src/filebrowser.cpp \
|
||||||
src/onlinemap.cpp \
|
src/onlinemap.cpp \
|
||||||
src/maplist.cpp \
|
|
||||||
src/downloader.cpp \
|
src/downloader.cpp \
|
||||||
src/scaleitem.cpp \
|
src/scaleitem.cpp \
|
||||||
src/track.cpp \
|
src/track.cpp \
|
||||||
@ -150,7 +148,6 @@ SOURCES += src/main.cpp \
|
|||||||
src/stylecombobox.cpp \
|
src/stylecombobox.cpp \
|
||||||
src/emptymap.cpp \
|
src/emptymap.cpp \
|
||||||
src/offlinemap.cpp \
|
src/offlinemap.cpp \
|
||||||
src/mapdir.cpp \
|
|
||||||
src/matrix.cpp \
|
src/matrix.cpp \
|
||||||
src/tar.cpp \
|
src/tar.cpp \
|
||||||
src/atlas.cpp \
|
src/atlas.cpp \
|
||||||
@ -160,7 +157,8 @@ SOURCES += src/main.cpp \
|
|||||||
src/lambertconic.cpp \
|
src/lambertconic.cpp \
|
||||||
src/ellipsoid.cpp \
|
src/ellipsoid.cpp \
|
||||||
src/ozf.cpp \
|
src/ozf.cpp \
|
||||||
src/datum.cpp
|
src/datum.cpp \
|
||||||
|
src/maplist.cpp
|
||||||
RESOURCES += gpxsee.qrc
|
RESOURCES += gpxsee.qrc
|
||||||
TRANSLATIONS = lang/gpxsee_cs.ts \
|
TRANSLATIONS = lang/gpxsee_cs.ts \
|
||||||
lang/gpxsee_sv.ts \
|
lang/gpxsee_sv.ts \
|
||||||
|
@ -30,25 +30,35 @@ static bool yCmp(const OfflineMap *m1, const OfflineMap *m2)
|
|||||||
return TL(m1).y() > TL(m2).y();
|
return TL(m1).y() > TL(m2).y();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Atlas::isAtlas(Tar &tar, const QFileInfoList &files)
|
bool Atlas::isAtlas(Tar &tar, const QString &path)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < files.count(); i++) {
|
QFileInfo fi(path);
|
||||||
const QString &fileName = files.at(i).fileName();
|
QByteArray ba;
|
||||||
if (fileName.endsWith(".tar")) {
|
|
||||||
if (!tar.load(files.at(i).absoluteFilePath())) {
|
|
||||||
qWarning("%s: %s: error loading tar file", qPrintable(_name),
|
if (fi.suffix() == "tar") {
|
||||||
qPrintable(fileName));
|
if (!tar.load(path)) {
|
||||||
return false;
|
_errorString = "Error reading tar file";
|
||||||
}
|
return false;
|
||||||
QStringList tarFiles = tar.files();
|
}
|
||||||
for (int j = 0; j < tarFiles.size(); j++)
|
QString tbaFileName = fi.completeBaseName() + ".tba";
|
||||||
if (tarFiles.at(j).endsWith(".tba"))
|
ba = tar.file(tbaFileName);
|
||||||
return true;
|
} else if (fi.suffix() == "tba") {
|
||||||
} else if (fileName.endsWith(".tba"))
|
QFile tbaFile(path);
|
||||||
return true;
|
if (!tbaFile.open(QIODevice::ReadOnly)) {
|
||||||
|
_errorString = QString("Error opening tba file: %1")
|
||||||
|
.arg(tbaFile.errorString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ba = tbaFile.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (ba.startsWith("Atlas 1.0"))
|
||||||
|
return true;
|
||||||
|
else {
|
||||||
|
_errorString = "Missing or invalid tba file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atlas::computeZooms()
|
void Atlas::computeZooms()
|
||||||
@ -100,38 +110,45 @@ void Atlas::computeBounds()
|
|||||||
BR(_maps.at(i))), QRectF(offsets.at(i), _maps.at(i)->bounds().size())));
|
BR(_maps.at(i))), QRectF(offsets.at(i), _maps.at(i)->bounds().size())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Atlas::Atlas(const QString &path, QObject *parent) : Map(parent)
|
Atlas::Atlas(const QString &fileName, QObject *parent) : Map(parent)
|
||||||
{
|
{
|
||||||
Tar tar;
|
Tar tar;
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_zoom = 0;
|
_zoom = 0;
|
||||||
|
_name = fi.dir().dirName();
|
||||||
|
|
||||||
QFileInfo fi(path);
|
if (!isAtlas(tar, fileName))
|
||||||
_name = fi.fileName();
|
|
||||||
|
|
||||||
QDir dir(path);
|
|
||||||
QFileInfoList files = dir.entryInfoList(QDir::Files);
|
|
||||||
if (!isAtlas(tar, files))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QDir dir(fi.absolutePath());
|
||||||
QFileInfoList layers = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
QFileInfoList layers = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
for (int n = 0; n < layers.count(); n++) {
|
for (int n = 0; n < layers.count(); n++) {
|
||||||
QDir zdir(layers.at(n).absoluteFilePath());
|
QDir zdir(layers.at(n).absoluteFilePath());
|
||||||
QFileInfoList maps = zdir.entryInfoList(QDir::Dirs
|
QFileInfoList maps = zdir.entryInfoList(QDir::Dirs
|
||||||
| QDir::NoDotAndDotDot);
|
| QDir::NoDotAndDotDot);
|
||||||
for (int i = 0; i < maps.count(); i++) {
|
for (int i = 0; i < maps.count(); i++) {
|
||||||
|
QString mapFile = maps.at(i).absoluteFilePath() + "/"
|
||||||
|
+ maps.at(i).fileName() + ".map";
|
||||||
|
|
||||||
OfflineMap *map;
|
OfflineMap *map;
|
||||||
if (tar.isOpen())
|
if (tar.isOpen())
|
||||||
map = new OfflineMap(tar, maps.at(i).absoluteFilePath(), this);
|
map = new OfflineMap(mapFile, tar, this);
|
||||||
else
|
else
|
||||||
map = new OfflineMap(maps.at(i).absoluteFilePath(), this);
|
map = new OfflineMap(mapFile, this);
|
||||||
|
|
||||||
if (map->isValid())
|
if (map->isValid())
|
||||||
_maps.append(map);
|
_maps.append(map);
|
||||||
|
else {
|
||||||
|
_errorString = QString("Error loading map: %1: %2")
|
||||||
|
.arg(mapFile, map->errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_maps.isEmpty()) {
|
if (_maps.isEmpty()) {
|
||||||
qWarning("%s: No usable maps available", qPrintable(_name));
|
_errorString = "No maps found in atlas";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class Atlas : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Atlas(const QString &path, QObject *parent = 0);
|
Atlas(const QString &fileName, QObject *parent = 0);
|
||||||
~Atlas();
|
~Atlas();
|
||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
@ -29,16 +29,18 @@ public:
|
|||||||
|
|
||||||
void draw(QPainter *painter, const QRectF &rect);
|
void draw(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
bool isValid() {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void draw(QPainter *painter, const QRectF &rect, int mapIndex);
|
void draw(QPainter *painter, const QRectF &rect, int mapIndex);
|
||||||
bool isAtlas(Tar &tar, const QFileInfoList &files);
|
bool isAtlas(Tar &tar, const QString &path);
|
||||||
void computeZooms();
|
void computeZooms();
|
||||||
void computeBounds();
|
void computeBounds();
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
bool _valid;
|
bool _valid;
|
||||||
|
QString _errorString;
|
||||||
|
|
||||||
QList<OfflineMap*> _maps;
|
QList<OfflineMap*> _maps;
|
||||||
QVector<QPair<int, int> > _zooms;
|
QVector<QPair<int, int> > _zooms;
|
||||||
|
157
src/gui.cpp
157
src/gui.cpp
@ -30,7 +30,6 @@
|
|||||||
#include "datum.h"
|
#include "datum.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "maplist.h"
|
#include "maplist.h"
|
||||||
#include "mapdir.h"
|
|
||||||
#include "emptymap.h"
|
#include "emptymap.h"
|
||||||
#include "elevationgraph.h"
|
#include "elevationgraph.h"
|
||||||
#include "speedgraph.h"
|
#include "speedgraph.h"
|
||||||
@ -166,21 +165,48 @@ void GUI::loadDatums()
|
|||||||
|
|
||||||
void GUI::loadMaps()
|
void GUI::loadMaps()
|
||||||
{
|
{
|
||||||
QList<Map*> online, offline;
|
_ml = new MapList(this);
|
||||||
|
|
||||||
|
QString offline, online;
|
||||||
|
|
||||||
if (QFile::exists(USER_MAP_FILE))
|
if (QFile::exists(USER_MAP_FILE))
|
||||||
online = MapList::load(USER_MAP_FILE, this);
|
online = USER_MAP_FILE;
|
||||||
else
|
else if (QFile::exists(GLOBAL_MAP_FILE))
|
||||||
online = MapList::load(GLOBAL_MAP_FILE, this);
|
online = GLOBAL_MAP_FILE;
|
||||||
|
|
||||||
|
if (!online.isNull() && !_ml->loadList(online))
|
||||||
|
qWarning("%s: %s", qPrintable(online), qPrintable(_ml->errorString()));
|
||||||
|
|
||||||
|
|
||||||
if (QFile::exists(USER_MAP_DIR))
|
if (QFile::exists(USER_MAP_DIR))
|
||||||
offline = MapDir::load(USER_MAP_DIR, this);
|
offline = USER_MAP_DIR;
|
||||||
else
|
else if (QFile::exists(GLOBAL_MAP_DIR))
|
||||||
offline = MapDir::load(GLOBAL_MAP_DIR, this);
|
offline = GLOBAL_MAP_DIR;
|
||||||
|
|
||||||
_maps = online + offline;
|
if (!offline.isNull()) {
|
||||||
|
QDir md(offline);
|
||||||
|
QFileInfoList ml = md.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.map" << "*.tba" << "*.tar";
|
||||||
|
|
||||||
_map = _maps.isEmpty() ? new EmptyMap(this) : _maps.first();
|
for (int i = 0; i < ml.size(); i++) {
|
||||||
|
QDir dir(ml.at(i).absoluteFilePath());
|
||||||
|
QFileInfoList fl = dir.entryInfoList(filters, QDir::Files);
|
||||||
|
|
||||||
|
if (fl.isEmpty())
|
||||||
|
qWarning("%s: no map/atlas file found",
|
||||||
|
qPrintable(ml.at(i).absoluteFilePath()));
|
||||||
|
else if (fl.size() > 1)
|
||||||
|
qWarning("%s: ambiguous directory content",
|
||||||
|
qPrintable(ml.at(i).absoluteFilePath()));
|
||||||
|
else
|
||||||
|
if (!_ml->loadMap(fl.first().absoluteFilePath()))
|
||||||
|
qWarning("%s: %s", qPrintable(fl.first().absoluteFilePath()),
|
||||||
|
qPrintable(_ml->errorString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_map = _ml->maps().isEmpty() ? new EmptyMap(this) : _ml->maps().first();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::loadPOIs()
|
void GUI::loadPOIs()
|
||||||
@ -209,33 +235,33 @@ void GUI::loadPOIs()
|
|||||||
|
|
||||||
void GUI::createMapActions()
|
void GUI::createMapActions()
|
||||||
{
|
{
|
||||||
QActionGroup *ag = new QActionGroup(this);
|
_mapsSignalMapper = new QSignalMapper(this);
|
||||||
ag->setExclusive(true);
|
_mapsActionGroup = new QActionGroup(this);
|
||||||
|
_mapsActionGroup->setExclusive(true);
|
||||||
|
|
||||||
QSignalMapper *sm = new QSignalMapper(this);
|
for (int i = 0; i < _ml->maps().count(); i++) {
|
||||||
|
QAction *a = new QAction(_ml->maps().at(i)->name(), this);
|
||||||
for (int i = 0; i < _maps.count(); i++) {
|
|
||||||
QAction *a = new QAction(_maps.at(i)->name(), this);
|
|
||||||
a->setCheckable(true);
|
a->setCheckable(true);
|
||||||
a->setActionGroup(ag);
|
a->setActionGroup(_mapsActionGroup);
|
||||||
|
|
||||||
sm->setMapping(a, i);
|
_mapsSignalMapper->setMapping(a, i);
|
||||||
connect(a, SIGNAL(triggered()), sm, SLOT(map()));
|
connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map()));
|
||||||
|
|
||||||
_mapActions.append(a);
|
_mapActions.append(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(sm, SIGNAL(mapped(int)), this, SLOT(mapChanged(int)));
|
connect(_mapsSignalMapper, SIGNAL(mapped(int)), this,
|
||||||
|
SLOT(mapChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::createPOIFilesActions()
|
void GUI::createPOIFilesActions()
|
||||||
{
|
{
|
||||||
_poiFilesSM = new QSignalMapper(this);
|
_poiFilesSignalMapper = new QSignalMapper(this);
|
||||||
|
|
||||||
for (int i = 0; i < _poi->files().count(); i++)
|
for (int i = 0; i < _poi->files().count(); i++)
|
||||||
createPOIFileAction(i);
|
createPOIFileAction(i);
|
||||||
|
|
||||||
connect(_poiFilesSM, SIGNAL(mapped(int)), this, SLOT(poiFileChecked(int)));
|
connect(_poiFilesSignalMapper, SIGNAL(mapped(int)), this, SLOT(poiFileChecked(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *GUI::createPOIFileAction(int index)
|
QAction *GUI::createPOIFileAction(int index)
|
||||||
@ -244,8 +270,8 @@ QAction *GUI::createPOIFileAction(int index)
|
|||||||
this);
|
this);
|
||||||
a->setCheckable(true);
|
a->setCheckable(true);
|
||||||
|
|
||||||
_poiFilesSM->setMapping(a, index);
|
_poiFilesSignalMapper->setMapping(a, index);
|
||||||
connect(a, SIGNAL(triggered()), _poiFilesSM, SLOT(map()));
|
connect(a, SIGNAL(triggered()), _poiFilesSignalMapper, SLOT(map()));
|
||||||
|
|
||||||
_poiFilesActions.append(a);
|
_poiFilesActions.append(a);
|
||||||
|
|
||||||
@ -341,23 +367,24 @@ void GUI::createActions()
|
|||||||
connect(_showMapAction, SIGNAL(triggered(bool)), _pathView,
|
connect(_showMapAction, SIGNAL(triggered(bool)), _pathView,
|
||||||
SLOT(showMap(bool)));
|
SLOT(showMap(bool)));
|
||||||
addAction(_showMapAction);
|
addAction(_showMapAction);
|
||||||
|
_loadMapAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)), tr("Load map"),
|
||||||
|
this);
|
||||||
|
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
|
||||||
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
|
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
|
||||||
connect(_clearMapCacheAction, SIGNAL(triggered()), this,
|
connect(_clearMapCacheAction, SIGNAL(triggered()), this,
|
||||||
SLOT(clearMapCache()));
|
SLOT(clearMapCache()));
|
||||||
if (_maps.empty()) {
|
createMapActions();
|
||||||
|
_nextMapAction = new QAction(tr("Next map"), this);
|
||||||
|
_nextMapAction->setShortcut(NEXT_MAP_SHORTCUT);
|
||||||
|
connect(_nextMapAction, SIGNAL(triggered()), this, SLOT(nextMap()));
|
||||||
|
addAction(_nextMapAction);
|
||||||
|
_prevMapAction = new QAction(tr("Next map"), this);
|
||||||
|
_prevMapAction->setShortcut(PREV_MAP_SHORTCUT);
|
||||||
|
connect(_prevMapAction, SIGNAL(triggered()), this, SLOT(prevMap()));
|
||||||
|
addAction(_prevMapAction);
|
||||||
|
if (_ml->maps().isEmpty()) {
|
||||||
_showMapAction->setEnabled(false);
|
_showMapAction->setEnabled(false);
|
||||||
_clearMapCacheAction->setEnabled(false);
|
_clearMapCacheAction->setEnabled(false);
|
||||||
} else {
|
|
||||||
createMapActions();
|
|
||||||
|
|
||||||
_nextMapAction = new QAction(tr("Next map"), this);
|
|
||||||
_nextMapAction->setShortcut(NEXT_MAP_SHORTCUT);
|
|
||||||
connect(_nextMapAction, SIGNAL(triggered()), this, SLOT(nextMap()));
|
|
||||||
addAction(_nextMapAction);
|
|
||||||
_prevMapAction = new QAction(tr("Next map"), this);
|
|
||||||
_prevMapAction->setShortcut(PREV_MAP_SHORTCUT);
|
|
||||||
connect(_prevMapAction, SIGNAL(triggered()), this, SLOT(prevMap()));
|
|
||||||
addAction(_prevMapAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data actions
|
// Data actions
|
||||||
@ -484,12 +511,13 @@ void GUI::createMenus()
|
|||||||
fileMenu->addAction(_exitAction);
|
fileMenu->addAction(_exitAction);
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
QMenu *mapMenu = menuBar()->addMenu(tr("Map"));
|
_mapMenu = menuBar()->addMenu(tr("Map"));
|
||||||
mapMenu->addActions(_mapActions);
|
_mapMenu->addActions(_mapActions);
|
||||||
mapMenu->addSeparator();
|
_mapsEnd = _mapMenu->addSeparator();
|
||||||
mapMenu->addAction(_clearMapCacheAction);
|
_mapMenu->addAction(_loadMapAction);
|
||||||
mapMenu->addSeparator();
|
_mapMenu->addAction(_clearMapCacheAction);
|
||||||
mapMenu->addAction(_showMapAction);
|
_mapMenu->addSeparator();
|
||||||
|
_mapMenu->addAction(_showMapAction);
|
||||||
|
|
||||||
QMenu *graphMenu = menuBar()->addMenu(tr("Graph"));
|
QMenu *graphMenu = menuBar()->addMenu(tr("Graph"));
|
||||||
graphMenu->addAction(_distanceGraphAction);
|
graphMenu->addAction(_distanceGraphAction);
|
||||||
@ -1132,6 +1160,32 @@ void GUI::showGraphGrids(bool show)
|
|||||||
_tabs.at(i)->showGrid(show);
|
_tabs.at(i)->showGrid(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI::loadMap()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Load Map/Atlas"),
|
||||||
|
QString(), tr("Map/Atlas files (*.map *.tba *.tar)"));
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_ml->loadMap(fileName)) {
|
||||||
|
QAction *a = new QAction(_ml->maps().last()->name(), this);
|
||||||
|
a->setCheckable(true);
|
||||||
|
a->setActionGroup(_mapsActionGroup);
|
||||||
|
_mapsSignalMapper->setMapping(a, _ml->maps().size() - 1);
|
||||||
|
connect(a, SIGNAL(triggered()), _mapsSignalMapper, SLOT(map()));
|
||||||
|
_mapActions.append(a);
|
||||||
|
_mapMenu->insertAction(_mapsEnd, a);
|
||||||
|
_showMapAction->setEnabled(true);
|
||||||
|
_clearMapCacheAction->setEnabled(true);
|
||||||
|
a->activate(QAction::Trigger);
|
||||||
|
} else {
|
||||||
|
QString error = tr("Error loading map/atlas:") + "\n\n"
|
||||||
|
+ fileName + "\n\n" + _ml->errorString();
|
||||||
|
QMessageBox::critical(this, APP_NAME, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GUI::clearMapCache()
|
void GUI::clearMapCache()
|
||||||
{
|
{
|
||||||
_map->clearCache();
|
_map->clearCache();
|
||||||
@ -1178,26 +1232,27 @@ void GUI::updateWindowTitle()
|
|||||||
|
|
||||||
void GUI::mapChanged(int index)
|
void GUI::mapChanged(int index)
|
||||||
{
|
{
|
||||||
_map = _maps.at(index);
|
_map = _ml->maps().at(index);
|
||||||
_pathView->setMap(_map);
|
_pathView->setMap(_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::nextMap()
|
void GUI::nextMap()
|
||||||
{
|
{
|
||||||
if (_maps.count() < 2)
|
if (_ml->maps().count() < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int next = (_maps.indexOf(_map) + 1) % _maps.count();
|
int next = (_ml->maps().indexOf(_map) + 1) % _ml->maps().count();
|
||||||
_mapActions.at(next)->setChecked(true);
|
_mapActions.at(next)->setChecked(true);
|
||||||
mapChanged(next);
|
mapChanged(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::prevMap()
|
void GUI::prevMap()
|
||||||
{
|
{
|
||||||
if (_maps.count() < 2)
|
if (_ml->maps().count() < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int prev = (_maps.indexOf(_map) + _maps.count() - 1) % _maps.count();
|
int prev = (_ml->maps().indexOf(_map) + _ml->maps().count() - 1)
|
||||||
|
% _ml->maps().count();
|
||||||
_mapActions.at(prev)->setChecked(true);
|
_mapActions.at(prev)->setChecked(true);
|
||||||
mapChanged(prev);
|
mapChanged(prev);
|
||||||
}
|
}
|
||||||
@ -1578,10 +1633,10 @@ void GUI::readSettings()
|
|||||||
settings.beginGroup(MAP_SETTINGS_GROUP);
|
settings.beginGroup(MAP_SETTINGS_GROUP);
|
||||||
if (settings.value(SHOW_MAP_SETTING, SHOW_MAP_DEFAULT).toBool())
|
if (settings.value(SHOW_MAP_SETTING, SHOW_MAP_DEFAULT).toBool())
|
||||||
_showMapAction->setChecked(true);
|
_showMapAction->setChecked(true);
|
||||||
if (_maps.count()) {
|
if (_ml->maps().count()) {
|
||||||
int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString());
|
int index = mapIndex(settings.value(CURRENT_MAP_SETTING).toString());
|
||||||
_mapActions.at(index)->setChecked(true);
|
_mapActions.at(index)->setChecked(true);
|
||||||
_map = _maps.at(index);
|
_map = _ml->maps().at(index);
|
||||||
_pathView->setMap(_map);
|
_pathView->setMap(_map);
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
@ -1743,8 +1798,8 @@ void GUI::readSettings()
|
|||||||
|
|
||||||
int GUI::mapIndex(const QString &name)
|
int GUI::mapIndex(const QString &name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _maps.count(); i++)
|
for (int i = 0; i < _ml->maps().count(); i++)
|
||||||
if (_maps.at(i)->name() == name)
|
if (_ml->maps().at(i)->name() == name)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
12
src/gui.h
12
src/gui.h
@ -13,6 +13,7 @@
|
|||||||
#include "exportdialog.h"
|
#include "exportdialog.h"
|
||||||
#include "optionsdialog.h"
|
#include "optionsdialog.h"
|
||||||
|
|
||||||
|
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QToolBar;
|
class QToolBar;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
@ -25,6 +26,7 @@ class FileBrowser;
|
|||||||
class GraphTab;
|
class GraphTab;
|
||||||
class PathView;
|
class PathView;
|
||||||
class Map;
|
class Map;
|
||||||
|
class MapList;
|
||||||
|
|
||||||
class GUI : public QMainWindow
|
class GUI : public QMainWindow
|
||||||
{
|
{
|
||||||
@ -53,6 +55,7 @@ private slots:
|
|||||||
void showFullscreen(bool show);
|
void showFullscreen(bool show);
|
||||||
void showTracks(bool show);
|
void showTracks(bool show);
|
||||||
void showRoutes(bool show);
|
void showRoutes(bool show);
|
||||||
|
void loadMap();
|
||||||
void clearMapCache();
|
void clearMapCache();
|
||||||
void nextMap();
|
void nextMap();
|
||||||
void prevMap();
|
void prevMap();
|
||||||
@ -129,9 +132,11 @@ private:
|
|||||||
QToolBar *_showToolBar;
|
QToolBar *_showToolBar;
|
||||||
QToolBar *_navigationToolBar;
|
QToolBar *_navigationToolBar;
|
||||||
QMenu *_poiFilesMenu;
|
QMenu *_poiFilesMenu;
|
||||||
|
QMenu *_mapMenu;
|
||||||
|
|
||||||
QActionGroup *_fileActionGroup;
|
QActionGroup *_fileActionGroup;
|
||||||
QActionGroup *_navigationActionGroup;
|
QActionGroup *_navigationActionGroup;
|
||||||
|
QActionGroup *_mapsActionGroup;
|
||||||
QAction *_exitAction;
|
QAction *_exitAction;
|
||||||
QAction *_keysAction;
|
QAction *_keysAction;
|
||||||
QAction *_dataSourcesAction;
|
QAction *_dataSourcesAction;
|
||||||
@ -149,6 +154,7 @@ private:
|
|||||||
QAction *_showPOILabelsAction;
|
QAction *_showPOILabelsAction;
|
||||||
QAction *_showMapAction;
|
QAction *_showMapAction;
|
||||||
QAction *_fullscreenAction;
|
QAction *_fullscreenAction;
|
||||||
|
QAction *_loadMapAction;
|
||||||
QAction *_clearMapCacheAction;
|
QAction *_clearMapCacheAction;
|
||||||
QAction *_showGraphsAction;
|
QAction *_showGraphsAction;
|
||||||
QAction *_showGraphGridAction;
|
QAction *_showGraphGridAction;
|
||||||
@ -171,10 +177,12 @@ private:
|
|||||||
QAction *_showWaypointLabelsAction;
|
QAction *_showWaypointLabelsAction;
|
||||||
QAction *_showRouteWaypointsAction;
|
QAction *_showRouteWaypointsAction;
|
||||||
QAction *_openOptionsAction;
|
QAction *_openOptionsAction;
|
||||||
|
QAction *_mapsEnd;
|
||||||
QList<QAction*> _mapActions;
|
QList<QAction*> _mapActions;
|
||||||
QList<QAction*> _poiFilesActions;
|
QList<QAction*> _poiFilesActions;
|
||||||
|
|
||||||
QSignalMapper *_poiFilesSM;
|
QSignalMapper *_poiFilesSignalMapper;
|
||||||
|
QSignalMapper *_mapsSignalMapper;
|
||||||
|
|
||||||
QLabel *_fileNameLabel;
|
QLabel *_fileNameLabel;
|
||||||
QLabel *_distanceLabel;
|
QLabel *_distanceLabel;
|
||||||
@ -185,7 +193,7 @@ private:
|
|||||||
QList<GraphTab*> _tabs;
|
QList<GraphTab*> _tabs;
|
||||||
|
|
||||||
POI *_poi;
|
POI *_poi;
|
||||||
QList<Map*> _maps;
|
MapList *_ml;
|
||||||
|
|
||||||
FileBrowser *_browser;
|
FileBrowser *_browser;
|
||||||
QList<QString> _files;
|
QList<QString> _files;
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
#include <QDir>
|
|
||||||
#include "atlas.h"
|
|
||||||
#include "offlinemap.h"
|
|
||||||
#include "mapdir.h"
|
|
||||||
|
|
||||||
QList<Map*> MapDir::load(const QString &path, QObject *parent)
|
|
||||||
{
|
|
||||||
QList<Map*> maps;
|
|
||||||
QDir dir(path);
|
|
||||||
|
|
||||||
|
|
||||||
if (!dir.exists())
|
|
||||||
return maps;
|
|
||||||
|
|
||||||
if (!dir.isReadable()) {
|
|
||||||
qWarning("Map directory not readable: %s\n", qPrintable(path));
|
|
||||||
return maps;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
QFileInfo fileInfo = list.at(i);
|
|
||||||
|
|
||||||
Atlas *atlas = new Atlas(fileInfo.absoluteFilePath(), parent);
|
|
||||||
if (atlas->isValid())
|
|
||||||
maps.append(atlas);
|
|
||||||
else {
|
|
||||||
delete atlas;
|
|
||||||
|
|
||||||
OfflineMap *map = new OfflineMap(fileInfo.absoluteFilePath(),
|
|
||||||
parent);
|
|
||||||
if (map->isValid())
|
|
||||||
maps.append(map);
|
|
||||||
else
|
|
||||||
delete map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maps;
|
|
||||||
}
|
|
16
src/mapdir.h
16
src/mapdir.h
@ -1,16 +0,0 @@
|
|||||||
#ifndef MAPDIR_H
|
|
||||||
#define MAPDIR_H
|
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class QObject;
|
|
||||||
class Map;
|
|
||||||
|
|
||||||
class MapDir
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static QList<Map*> load(const QString &path, QObject *parent = 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MAPDIR_H
|
|
101
src/maplist.cpp
101
src/maplist.cpp
@ -1,41 +1,100 @@
|
|||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QDir>
|
||||||
|
#include "atlas.h"
|
||||||
|
#include "offlinemap.h"
|
||||||
#include "onlinemap.h"
|
#include "onlinemap.h"
|
||||||
#include "maplist.h"
|
#include "maplist.h"
|
||||||
|
|
||||||
|
|
||||||
QList<Map*> MapList::load(const QString &fileName, QObject *parent)
|
bool MapList::loadListEntry(const QByteArray &line)
|
||||||
{
|
{
|
||||||
QList<Map*> maps;
|
QList<QByteArray> list = line.split('\t');
|
||||||
QFileInfo fi(fileName);
|
if (list.size() != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!fi.exists())
|
QByteArray ba1 = list[0].trimmed();
|
||||||
return maps;
|
QByteArray ba2 = list[1].trimmed();
|
||||||
|
if (ba1.isEmpty() || ba2.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
QFile file(fileName);
|
_maps.append(new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()),
|
||||||
|
QString::fromLatin1(ba2.data(), ba2.size()), this));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapList::loadList(const QString &path)
|
||||||
|
{
|
||||||
|
QFile file(path);
|
||||||
|
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
qWarning("Error opening map list file: %s: %s\n",
|
_errorString = file.errorString();
|
||||||
qPrintable(fileName), qPrintable(file.errorString()));
|
return false;
|
||||||
return maps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ln = 0;
|
int ln = 0;
|
||||||
while (!file.atEnd()) {
|
while (!file.atEnd()) {
|
||||||
ln++;
|
ln++;
|
||||||
QByteArray line = file.readLine();
|
QByteArray line = file.readLine();
|
||||||
QList<QByteArray> list = line.split('\t');
|
|
||||||
if (list.size() != 2) {
|
if (!loadListEntry(line)) {
|
||||||
qWarning("Invalid map list entry on line %d\n", ln);
|
_errorString = QString("Invalid map list entry on line %1.")
|
||||||
continue;
|
.arg(QString::number(ln));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ba1 = list[0].trimmed();
|
|
||||||
QByteArray ba2 = list[1].trimmed();
|
|
||||||
|
|
||||||
maps.append(new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()),
|
|
||||||
QString::fromLatin1(ba2.data(), ba2.size()), parent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return maps;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapList::loadMap(const QString &path)
|
||||||
|
{
|
||||||
|
QFileInfo fi(path);
|
||||||
|
QString suffix = fi.suffix().toLower();
|
||||||
|
|
||||||
|
if (suffix == "map") {
|
||||||
|
OfflineMap *om = new OfflineMap(path, this);
|
||||||
|
if (om->isValid()) {
|
||||||
|
_maps.append(om);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
_errorString = om->errorString();
|
||||||
|
delete om;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (suffix == "tba") {
|
||||||
|
Atlas *atlas = new Atlas(path, this);
|
||||||
|
if (atlas->isValid()) {
|
||||||
|
_maps.append(atlas);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
_errorString = atlas->errorString();
|
||||||
|
delete atlas;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (suffix == "tar") {
|
||||||
|
Atlas *atlas = new Atlas(path, this);
|
||||||
|
if (atlas->isValid()) {
|
||||||
|
_maps.append(atlas);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
_errorString = atlas->errorString();
|
||||||
|
delete atlas;
|
||||||
|
OfflineMap *om = new OfflineMap(path, this);
|
||||||
|
if (om->isValid()) {
|
||||||
|
_maps.append(om);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
qWarning("%s: %s", qPrintable(path), qPrintable(_errorString));
|
||||||
|
qWarning("%s: %s", qPrintable(path),
|
||||||
|
qPrintable(om->errorString()));
|
||||||
|
_errorString = "Not a map/atlas file";
|
||||||
|
delete om;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_errorString = "Not a map/atlas file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,28 @@
|
|||||||
#ifndef MAPLIST_H
|
#ifndef MAPLIST_H
|
||||||
#define MAPLIST_H
|
#define MAPLIST_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
class QObject;
|
class MapList : public QObject
|
||||||
class Map;
|
|
||||||
|
|
||||||
class MapList
|
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QList<Map*> load(const QString &fileName, QObject *parent = 0);
|
MapList(QObject *parent = 0) : QObject(parent) {}
|
||||||
|
|
||||||
|
bool loadMap(const QString &path);
|
||||||
|
bool loadList(const QString &path);
|
||||||
|
|
||||||
|
QList<Map*> &maps() {return _maps;}
|
||||||
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool loadListEntry(const QByteArray &line);
|
||||||
|
|
||||||
|
QList<Map*> _maps;
|
||||||
|
QString _errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAPLIST_H
|
#endif // MAPLIST_H
|
||||||
|
@ -46,7 +46,7 @@ static Coordinates toWGS84(Coordinates c, const Datum &datum)
|
|||||||
double adb = 1.0 / (1.0 - from_f);
|
double adb = 1.0 / (1.0 - from_f);
|
||||||
double rn = from_a / sqrt(1 - from_esq * ssqlat);
|
double rn = from_a / sqrt(1 - from_esq * ssqlat);
|
||||||
double rm = from_a * (1 - from_esq) / pow((1 - from_esq * ssqlat), 1.5);
|
double rm = from_a * (1 - from_esq) / pow((1 - from_esq * ssqlat), 1.5);
|
||||||
double from_h = 0.0; // we're flat!
|
double from_h = 0.0;
|
||||||
|
|
||||||
double dlat = (-dX * slat * clon - dY * slat * slon + dZ * clat + da * rn
|
double dlat = (-dX * slat * clon - dY * slat * slon + dZ * clat + da * rn
|
||||||
* from_esq * slat * clat / from_a + +df * (rm * adb + rn / adb) * slat
|
* from_esq * slat * clat / from_a + +df * (rm * adb + rn / adb) * slat
|
||||||
@ -56,23 +56,22 @@ static Coordinates toWGS84(Coordinates c, const Datum &datum)
|
|||||||
return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
|
return Coordinates(c.lon() + rad2deg(dlon), c.lat() + rad2deg(dlat));
|
||||||
}
|
}
|
||||||
|
|
||||||
int OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
|
||||||
|
int OfflineMap::parse(QIODevice &device, QList<ReferencePoint> &points,
|
||||||
QString &projection, ProjectionSetup &setup, QString &datum)
|
QString &projection, ProjectionSetup &setup, QString &datum)
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
int ln = 1;
|
int ln = 1;
|
||||||
|
|
||||||
|
|
||||||
if (!device.open(QIODevice::ReadOnly))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while (!device.atEnd()) {
|
while (!device.atEnd()) {
|
||||||
QByteArray line = device.readLine();
|
QByteArray line = device.readLine();
|
||||||
|
|
||||||
if (ln == 1) {
|
if (ln == 1) {
|
||||||
if (!line.trimmed().startsWith("OziExplorer Map Data File"))
|
if (!line.trimmed().startsWith("OziExplorer Map Data File"))
|
||||||
return ln;
|
return ln;
|
||||||
} else if (ln == 3)
|
} else if (ln == 2)
|
||||||
|
_name = line.trimmed();
|
||||||
|
else if (ln == 3)
|
||||||
_imgPath = line.trimmed();
|
_imgPath = line.trimmed();
|
||||||
else if (ln == 5)
|
else if (ln == 5)
|
||||||
datum = line.split(',').at(0).trimmed();
|
datum = line.split(',').at(0).trimmed();
|
||||||
@ -173,19 +172,37 @@ int OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
||||||
|
QString &projection, ProjectionSetup &setup, QString &datum)
|
||||||
|
{
|
||||||
|
int el;
|
||||||
|
|
||||||
|
if (!device.open(QIODevice::ReadOnly)) {
|
||||||
|
_errorString = QString("Error opening map file: %1")
|
||||||
|
.arg(device.errorString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((el = parse(device, points, projection, setup, datum))) {
|
||||||
|
_errorString = QString("Map file parse error on line %1").arg(el);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool OfflineMap::createProjection(const QString &datum,
|
bool OfflineMap::createProjection(const QString &datum,
|
||||||
const QString &projection, const ProjectionSetup &setup,
|
const QString &projection, const ProjectionSetup &setup,
|
||||||
QList<ReferencePoint> &points)
|
QList<ReferencePoint> &points)
|
||||||
{
|
{
|
||||||
if (points.count() < 2) {
|
if (points.count() < 2) {
|
||||||
qWarning("%s: insufficient number of reference points",
|
_errorString = "Insufficient number of reference points";
|
||||||
qPrintable(_name));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum d = Datum::datum(datum);
|
Datum d = Datum::datum(datum);
|
||||||
if (d.isNull()) {
|
if (d.isNull()) {
|
||||||
qWarning("%s: %s: unknown datum", qPrintable(_name), qPrintable(datum));
|
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,12 +225,11 @@ bool OfflineMap::createProjection(const QString &datum,
|
|||||||
else if (!points.first().ll.isNull())
|
else if (!points.first().ll.isNull())
|
||||||
_projection = new UTM(d.ellipsoid(), points.first().ll);
|
_projection = new UTM(d.ellipsoid(), points.first().ll);
|
||||||
else {
|
else {
|
||||||
qWarning("%s: Can not determine UTM zone", qPrintable(_name));
|
_errorString = "Can not determine UTM zone";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qWarning("%s: %s: unsupported map projection", qPrintable(_name),
|
_errorString = QString("%1: Unknown map projection").arg(projection);
|
||||||
qPrintable(projection));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +286,7 @@ bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
|
|||||||
|
|
||||||
Matrix M = Q.augemented(c);
|
Matrix M = Q.augemented(c);
|
||||||
if (!M.eliminate()) {
|
if (!M.eliminate()) {
|
||||||
qWarning("%s: singular transformation matrix", qPrintable(_name));
|
_errorString = "Singular transformation matrix";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,17 +343,15 @@ bool OfflineMap::getImageInfo(const QString &path)
|
|||||||
if (ii.exists())
|
if (ii.exists())
|
||||||
_imgPath = ii.absoluteFilePath();
|
_imgPath = ii.absoluteFilePath();
|
||||||
else {
|
else {
|
||||||
qWarning("%s: %s: No such image file", qPrintable(_name),
|
_errorString = QString("%1: No such image file").arg(_imgPath);
|
||||||
qPrintable(_imgPath));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_imgPath.endsWith("ozf3", Qt::CaseInsensitive)
|
if (_imgPath.endsWith("ozf3") || _imgPath.endsWith("ozf4")) {
|
||||||
|| _imgPath.endsWith("ozf4", Qt::CaseInsensitive)) {
|
_errorString = QString("%1: Obfuscated image files not supported")
|
||||||
qWarning("%s: %s: obfuscated image files are not supported",
|
.arg(QFileInfo(_imgPath).fileName());
|
||||||
qPrintable(_name), qPrintable(_imgPath));
|
|
||||||
return false;
|
return false;
|
||||||
} else if (_imgPath.endsWith("ozf2", Qt::CaseInsensitive)) {
|
} else if (_imgPath.endsWith("ozf2")) {
|
||||||
_ozf.load(_imgPath);
|
_ozf.load(_imgPath);
|
||||||
_size = _ozf.size();
|
_size = _ozf.size();
|
||||||
} else {
|
} else {
|
||||||
@ -345,8 +359,8 @@ bool OfflineMap::getImageInfo(const QString &path)
|
|||||||
_size = img.size();
|
_size = img.size();
|
||||||
}
|
}
|
||||||
if (!_size.isValid()) {
|
if (!_size.isValid()) {
|
||||||
qWarning("%s: %s: error reading map image", qPrintable(_name),
|
_errorString = QString("%1: Error reading map image")
|
||||||
qPrintable(_imgPath));
|
.arg(QFileInfo(_imgPath).fileName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +370,7 @@ bool OfflineMap::getImageInfo(const QString &path)
|
|||||||
bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
|
bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
|
||||||
{
|
{
|
||||||
if (tiles.isEmpty()) {
|
if (tiles.isEmpty()) {
|
||||||
qWarning("%s: empty tile set", qPrintable(_name));
|
_errorString = "Empty tile set.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,9 +388,8 @@ bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
|
|||||||
_tileSize = QImageReader(path + "/" + tiles.at(i)).size();
|
_tileSize = QImageReader(path + "/" + tiles.at(i)).size();
|
||||||
}
|
}
|
||||||
if (!_tileSize.isValid()) {
|
if (!_tileSize.isValid()) {
|
||||||
qWarning("%s: error retrieving tile size: %s: invalid image",
|
_errorString = QString("Error retrieving tile size: "
|
||||||
qPrintable(_name), qPrintable(QFileInfo(tiles.at(i))
|
"%1: Invalid image").arg(QFileInfo(tiles.at(i)).fileName());
|
||||||
.fileName()));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,42 +397,26 @@ bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qWarning("%s: invalid tile names", qPrintable(_name));
|
_errorString = "Invalid tile names";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OfflineMap::mapLoaded(int res)
|
|
||||||
{
|
|
||||||
if (res) {
|
|
||||||
if (res == -2)
|
|
||||||
qWarning("%s: no map file found", qPrintable(_name));
|
|
||||||
else if (res == -1)
|
|
||||||
qWarning("%s: error opening map file", qPrintable(_name));
|
|
||||||
else
|
|
||||||
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
|
|
||||||
res);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OfflineMap::totalSizeSet()
|
bool OfflineMap::totalSizeSet()
|
||||||
{
|
{
|
||||||
if (!_size.isValid()) {
|
if (!_size.isValid()) {
|
||||||
qWarning("%s: missing total image size (IWH)", qPrintable(_name));
|
_errorString = "Missing total image size (IWH)";
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
|
OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||||
|
: Map(parent)
|
||||||
{
|
{
|
||||||
int errorLine = -2;
|
|
||||||
QList<ReferencePoint> points;
|
QList<ReferencePoint> points;
|
||||||
QString proj, datum;
|
QString proj, datum;
|
||||||
ProjectionSetup setup;
|
ProjectionSetup setup;
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
|
||||||
|
|
||||||
_valid = false;
|
_valid = false;
|
||||||
@ -427,38 +424,29 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
|
|||||||
_projection = 0;
|
_projection = 0;
|
||||||
_resolution = 0;
|
_resolution = 0;
|
||||||
|
|
||||||
QFileInfo fi(path);
|
if (fi.suffix() == "tar") {
|
||||||
_name = fi.fileName();
|
if (!_tar.load(fileName)) {
|
||||||
|
_errorString = "Error reading tar file";
|
||||||
QDir dir(path);
|
return;
|
||||||
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
|
|
||||||
for (int i = 0; i < mapFiles.count(); i++) {
|
|
||||||
const QString &fileName = mapFiles.at(i).fileName();
|
|
||||||
if (fileName.endsWith(".tar")) {
|
|
||||||
if (!_tar.load(mapFiles.at(i).absoluteFilePath())) {
|
|
||||||
qWarning("%s: %s: error loading tar file", qPrintable(_name),
|
|
||||||
qPrintable(fileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QStringList tarFiles = _tar.files();
|
|
||||||
for (int j = 0; j < tarFiles.size(); j++) {
|
|
||||||
if (tarFiles.at(j).endsWith(".map")) {
|
|
||||||
QByteArray ba = _tar.file(tarFiles.at(j));
|
|
||||||
QBuffer buffer(&ba);
|
|
||||||
errorLine = parseMapFile(buffer, points, proj, setup, datum);
|
|
||||||
_imgPath = QString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if (fileName.endsWith(".map")) {
|
|
||||||
QFile mapFile(mapFiles.at(i).absoluteFilePath());
|
|
||||||
errorLine = parseMapFile(mapFile, points, proj, setup, datum);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!mapLoaded(errorLine))
|
QString mapFileName = fi.completeBaseName() + ".map";
|
||||||
|
QByteArray ba = _tar.file(mapFileName);
|
||||||
|
if (ba.isNull()) {
|
||||||
|
_errorString = "Map file not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QBuffer mapFile(&ba);
|
||||||
|
if (!parseMapFile(mapFile, points, proj, setup, datum))
|
||||||
|
return;
|
||||||
|
} else if (fi.suffix() =="map") {
|
||||||
|
QFile mapFile(fileName);
|
||||||
|
if (!parseMapFile(mapFile, points, proj, setup, datum))
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_errorString = "Not a map file";
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!createProjection(datum, proj, setup, points))
|
if (!createProjection(datum, proj, setup, points))
|
||||||
return;
|
return;
|
||||||
@ -471,16 +459,17 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
|
|||||||
return;
|
return;
|
||||||
if (!getTileInfo(_tar.files()))
|
if (!getTileInfo(_tar.files()))
|
||||||
return;
|
return;
|
||||||
|
_imgPath = QString();
|
||||||
} else {
|
} else {
|
||||||
QDir set(fi.absoluteFilePath() + "/" + "set");
|
QDir set(fi.absolutePath() + "/" + "set");
|
||||||
if (set.exists()) {
|
if (set.exists()) {
|
||||||
if (!totalSizeSet())
|
if (!totalSizeSet())
|
||||||
return;
|
return;
|
||||||
if (!getTileInfo(set.entryList(), set.canonicalPath()))
|
if (!getTileInfo(set.entryList(), set.absolutePath()))
|
||||||
return;
|
return;
|
||||||
_imgPath = QString();
|
_imgPath = QString();
|
||||||
} else {
|
} else {
|
||||||
if (!getImageInfo(fi.absoluteFilePath()))
|
if (!getImageInfo(fi.absolutePath()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,36 +477,31 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
|
|||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OfflineMap::OfflineMap(Tar &tar, const QString &path, QObject *parent)
|
OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||||
: Map(parent)
|
: Map(parent)
|
||||||
{
|
{
|
||||||
int errorLine = -2;
|
|
||||||
QList<ReferencePoint> points;
|
QList<ReferencePoint> points;
|
||||||
QString proj, datum;
|
QString proj, datum;
|
||||||
ProjectionSetup setup;
|
ProjectionSetup setup;
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_img = 0;
|
_img = 0;
|
||||||
_projection = 0;
|
_projection = 0;
|
||||||
|
|
||||||
QFileInfo fi(path);
|
QFileInfo map(fi.absolutePath());
|
||||||
_name = fi.fileName();
|
QFileInfo layer(map.absolutePath());
|
||||||
|
QString mapFile = layer.fileName() + "/" + map.fileName() + "/"
|
||||||
QFileInfo li(fi.absoluteDir().dirName());
|
+ fi.fileName();
|
||||||
QString prefix = li.fileName() + "/" + fi.fileName() + "/";
|
QByteArray ba = tar.file(mapFile);
|
||||||
QStringList tarFiles = tar.files();
|
if (ba.isNull()) {
|
||||||
for (int j = 0; j < tarFiles.size(); j++) {
|
_errorString = "Map file not found";
|
||||||
if (tarFiles.at(j).startsWith(prefix)) {
|
|
||||||
QByteArray ba = tar.file(tarFiles.at(j));
|
|
||||||
QBuffer buffer(&ba);
|
|
||||||
errorLine = parseMapFile(buffer, points, proj, setup, datum);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mapLoaded(errorLine))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
QBuffer buffer(&ba);
|
||||||
|
|
||||||
|
if (!parseMapFile(buffer, points, proj, setup, datum))
|
||||||
|
return;
|
||||||
if (!createProjection(datum, proj, setup, points))
|
if (!createProjection(datum, proj, setup, points))
|
||||||
return;
|
return;
|
||||||
if (!totalSizeSet())
|
if (!totalSizeSet())
|
||||||
@ -526,14 +510,8 @@ OfflineMap::OfflineMap(Tar &tar, const QString &path, QObject *parent)
|
|||||||
return;
|
return;
|
||||||
computeResolution(points);
|
computeResolution(points);
|
||||||
|
|
||||||
QDir dir(path);
|
|
||||||
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
|
|
||||||
for (int i = 0; i < mapFiles.count(); i++) {
|
|
||||||
const QString &fileName = mapFiles.at(i).absoluteFilePath();
|
|
||||||
if (fileName.endsWith(".tar"))
|
|
||||||
_tarPath = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_tarPath = fi.absolutePath() + "/" + fi.completeBaseName() + ".tar";
|
||||||
_imgPath = QString();
|
_imgPath = QString();
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
@ -550,8 +528,7 @@ void OfflineMap::load()
|
|||||||
{
|
{
|
||||||
if (!_tarPath.isNull() && !_tileSize.isValid()) {
|
if (!_tarPath.isNull() && !_tileSize.isValid()) {
|
||||||
if (!_tar.load(_tarPath)) {
|
if (!_tar.load(_tarPath)) {
|
||||||
qWarning("%s: %s: error loading tar file", qPrintable(_name),
|
qWarning("%s: error loading tar file", qPrintable(_tarPath));
|
||||||
qPrintable(_tarPath));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getTileInfo(_tar.files());
|
getTileInfo(_tar.files());
|
||||||
|
@ -17,8 +17,8 @@ class OfflineMap : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OfflineMap(const QString &path, QObject *parent = 0);
|
OfflineMap(const QString &fileName, QObject *parent = 0);
|
||||||
OfflineMap(Tar &tar, const QString &path, QObject *parent = 0);
|
OfflineMap(const QString &fileName, Tar &tar, QObject *parent = 0);
|
||||||
~OfflineMap();
|
~OfflineMap();
|
||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
@ -41,7 +41,8 @@ public:
|
|||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
bool isValid() {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
QPointF ll2pp(const Coordinates &c) const
|
QPointF ll2pp(const Coordinates &c) const
|
||||||
{return _projection->ll2xy(c);}
|
{return _projection->ll2xy(c);}
|
||||||
@ -68,9 +69,10 @@ private:
|
|||||||
int zone;
|
int zone;
|
||||||
} ProjectionSetup;
|
} ProjectionSetup;
|
||||||
|
|
||||||
int parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
int parse(QIODevice &device, QList<ReferencePoint> &points,
|
||||||
|
QString &projection, ProjectionSetup &setup, QString &datum);
|
||||||
|
bool parseMapFile(QIODevice &device, QList<ReferencePoint> &points,
|
||||||
QString &projection, ProjectionSetup &setup, QString &datum);
|
QString &projection, ProjectionSetup &setup, QString &datum);
|
||||||
bool mapLoaded(int res);
|
|
||||||
bool totalSizeSet();
|
bool totalSizeSet();
|
||||||
bool createProjection(const QString &datum, const QString &projection,
|
bool createProjection(const QString &datum, const QString &projection,
|
||||||
const ProjectionSetup &setup, QList<ReferencePoint> &points);
|
const ProjectionSetup &setup, QList<ReferencePoint> &points);
|
||||||
@ -84,6 +86,9 @@ private:
|
|||||||
void drawImage(QPainter *painter, const QRectF &rect);
|
void drawImage(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
|
bool _valid;
|
||||||
|
QString _errorString;
|
||||||
|
|
||||||
QSize _size;
|
QSize _size;
|
||||||
Projection *_projection;
|
Projection *_projection;
|
||||||
QTransform _transform, _inverted;
|
QTransform _transform, _inverted;
|
||||||
@ -96,8 +101,6 @@ private:
|
|||||||
QString _imgPath;
|
QString _imgPath;
|
||||||
QSize _tileSize;
|
QSize _tileSize;
|
||||||
QString _tileName;
|
QString _tileName;
|
||||||
|
|
||||||
bool _valid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OFFLINEMAP_H
|
#endif // OFFLINEMAP_H
|
||||||
|
Loading…
Reference in New Issue
Block a user