1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Added support for user defined TYP files for Garmin IMG maps

This commit is contained in:
Martin Tůma 2019-05-16 20:23:37 +02:00
parent 3747ae6afc
commit 785bf94a01
8 changed files with 102 additions and 31 deletions

View File

@ -724,6 +724,8 @@ void GUI::paths()
+ QDir::cleanPath(ProgramPaths::csvDir(true)) + "</code></td></tr><tr><td>"
+ tr("DEM directory:") + "</td><td><code>"
+ QDir::cleanPath(ProgramPaths::demDir(true)) + "</code></td></tr><tr><td>"
+ tr("Styles directory:") + "</td><td><code>"
+ QDir::cleanPath(ProgramPaths::styleDir(true)) + "</code></td></tr><tr><td>"
+ tr("Tile cache directory:") + "</td><td><code>"
+ QDir::cleanPath(ProgramPaths::tilesDir()) + "</code></td></tr></table>"
);

View File

@ -9,9 +9,11 @@
#define DEM_DIR "DEM"
#define TILES_DIR "tiles"
#define TRANSLATIONS_DIR "translations"
#define STYLE_DIR "style"
#define ELLIPSOID_FILE "ellipsoids.csv"
#define GCS_FILE "gcs.csv"
#define PCS_FILE "pcs.csv"
#define TYP_FILE "style.typ"
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
@ -79,6 +81,11 @@ QString ProgramPaths::demDir(bool writable)
return dir(DEM_DIR, writable);
}
QString ProgramPaths::styleDir(bool writable)
{
return dir(STYLE_DIR, writable);
}
QString ProgramPaths::tilesDir()
{
#if defined(Q_OS_WIN32)
@ -113,6 +120,11 @@ QString ProgramPaths::pcsFile()
return file(dir(CSV_DIR), PCS_FILE);
}
QString ProgramPaths::typFile()
{
return file(dir(STYLE_DIR), TYP_FILE);
}
#else // QT_VERSION < 5
#include <QStandardPaths>
@ -157,6 +169,16 @@ QString ProgramPaths::demDir(bool writable)
DEM_DIR, QStandardPaths::LocateDirectory);
}
QString ProgramPaths::styleDir(bool writable)
{
if (writable)
return QDir(QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation)).filePath(STYLE_DIR);
else
return QStandardPaths::locate(QStandardPaths::AppDataLocation,
STYLE_DIR, QStandardPaths::LocateDirectory);
}
QString ProgramPaths::tilesDir()
{
return QDir(QStandardPaths::writableLocation(
@ -187,4 +209,10 @@ QString ProgramPaths::pcsFile()
CSV_DIR "/" PCS_FILE, QStandardPaths::LocateFile);
}
QString ProgramPaths::typFile()
{
return QStandardPaths::locate(QStandardPaths::AppDataLocation,
STYLE_DIR "/" TYP_FILE, QStandardPaths::LocateFile);
}
#endif // QT_VERSION < 5

View File

@ -9,11 +9,13 @@ namespace ProgramPaths
QString poiDir(bool writable = false);
QString csvDir(bool writable = false);
QString demDir(bool writable = false);
QString styleDir(bool writable = false);
QString tilesDir();
QString translationsDir();
QString ellipsoidsFile();
QString gcsFile();
QString pcsFile();
QString typFile();
}
#endif // PROGRAMPATHS_H

View File

@ -1,5 +1,6 @@
#include <QSet>
#include <QtEndian>
#include "common/programpaths.h"
#include "vectortile.h"
#include "img.h"
@ -162,9 +163,18 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
// Read TYP file if any
if (!TYPMap.isEmpty()) {
if (TYPMap.size() > 1)
qWarning("%s: Multiple TYP files, using %s",
qPrintable(_file.fileName()), qPrintable(TYPMap.keys().first()));
SubFile *typ = TYPMap.values().first();
_style = Style(typ);
qDeleteAll(TYPMap);
} else {
QFile typFile(ProgramPaths::typFile());
if (typFile.exists()) {
SubFile typ(&typFile);
_style = Style(&typ);
}
}
_valid = true;

View File

@ -50,20 +50,19 @@ public:
const QString &name() const {return _name;}
const RectC &bounds() const {return _bounds;}
Range zooms() const {return Range(_bits.first(), _bits.last());}
void objects(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines, QList<Point> *points) const;
const Style &style() const {return _style;}
bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;}
void objects(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines, QList<Point> *points) const;
const Style &style() const {return _style;}
private:
friend class SubFile;
typedef RTree<VectorTile*, double, 2> TileTree;
QString fileName() const {return _file.fileName();}
int blockSize() const {return _blockSize;}
bool readBlock(int blockNum, QByteArray &data);
qint64 read(char *data, qint64 maxSize);

View File

@ -779,7 +779,7 @@ bool Style::parseTYPFile(SubFile *file)
&& parsePolygons(file, hdl, polygons)
&& parseDrawOrder(file, hdl, order))) {
qWarning("%s: Invalid TYP file, using default style",
qPrintable(file->imgName()));
qPrintable(file->fileName()));
return false;
}
@ -791,7 +791,7 @@ Style::Style(SubFile *typ)
defaultLineStyle();
defaultPolygonStyle();
if (typ)
if (typ && typ->isValid())
parseTYPFile(typ);
}

View File

@ -1,3 +1,4 @@
#include <QFile>
#include "img.h"
#include "subfile.h"
@ -19,42 +20,68 @@ SubFile::Type SubFile::type(const char str[3])
return Unknown;
}
SubFile::SubFile(QFile *file) : _img(0), _file(file), _size(0)
{
if (!_file->open(QIODevice::ReadOnly))
qWarning("Error opening %s: %s", qPrintable(_file->fileName()),
qPrintable(_file->errorString()));
}
bool SubFile::isValid() const
{
return ((quint32)_img->blockSize() * (quint32)_blocks.size() - _size
< (quint32)_img->blockSize());
return _file
? _file->isOpen()
: ((quint32)_img->blockSize() * (quint32)_blocks.size() - _size
< (quint32)_img->blockSize());
}
bool SubFile::seek(Handle &handle, quint32 pos) const
{
quint32 blockSize = _img->blockSize();
int blockNum = pos / blockSize;
Q_ASSERT(_img || _file);
if (handle.blockNum != blockNum) {
if (blockNum >= _blocks.size())
return false;
if (!_img->readBlock(_blocks.at(blockNum), handle.data))
return false;
handle.blockNum = blockNum;
if (_file)
return _file->seek(pos);
else {
quint32 blockSize = _img->blockSize();
int blockNum = pos / blockSize;
if (handle.blockNum != blockNum) {
if (blockNum >= _blocks.size())
return false;
if (!_img->readBlock(_blocks.at(blockNum), handle.data))
return false;
handle.blockNum = blockNum;
}
handle.blockPos = pos % blockSize;
handle.pos = pos;
return true;
}
handle.blockPos = pos % blockSize;
handle.pos = pos;
return true;
}
bool SubFile::readByte(Handle &handle, quint8 &val) const
{
val = handle.data.at(handle.blockPos++);
handle.pos++;
return (handle.blockPos >= _img->blockSize())
? seek(handle, handle.pos) : true;
Q_ASSERT(_img || _file);
if (_file)
return _file->getChar((char*)&val);
else {
val = handle.data.at(handle.blockPos++);
handle.pos++;
return (handle.blockPos >= _img->blockSize())
? seek(handle, handle.pos) : true;
}
}
const QString &SubFile::imgName() const
quint32 SubFile::size() const
{
return _img->name();
return _img ? _size : (quint32)_file->size();
}
QString SubFile::fileName() const
{
return _img ? _img->fileName() : _file->fileName();
}
#ifndef QT_NO_DEBUG

View File

@ -5,6 +5,7 @@
#include <QDebug>
class IMG;
class QFile;
class SubFile
{
@ -21,12 +22,13 @@ public:
int pos;
};
SubFile(IMG *img, quint32 size) : _img(img), _size(size) {}
SubFile(IMG *img, quint32 size) : _img(img), _file(0), _size(size) {}
SubFile(QFile *file);
void addBlock(quint16 block) {_blocks.append(block);}
bool isValid() const;
quint32 size() const {return _size;}
quint32 size() const;
bool seek(Handle &handle, quint32 pos) const;
bool readByte(Handle &handle, quint8 &val) const;
@ -79,7 +81,7 @@ public:
}
quint16 offset() const {return _blocks.first();}
const QString &imgName() const;
QString fileName() const;
static Type type(const char str[3]);
@ -87,6 +89,7 @@ public:
private:
IMG *_img;
QFile *_file;
quint32 _size;
QVector<quint16> _blocks;
};