mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Added support for tared maps
This commit is contained in:
parent
d8477571cc
commit
70ddbe192f
@ -82,7 +82,8 @@ HEADERS += src/config.h \
|
|||||||
src/emptymap.h \
|
src/emptymap.h \
|
||||||
src/ozimap.h \
|
src/ozimap.h \
|
||||||
src/mapdir.h \
|
src/mapdir.h \
|
||||||
src/matrix.h
|
src/matrix.h \
|
||||||
|
src/tar.h
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
src/gui.cpp \
|
src/gui.cpp \
|
||||||
src/poi.cpp \
|
src/poi.cpp \
|
||||||
@ -140,7 +141,8 @@ SOURCES += src/main.cpp \
|
|||||||
src/emptymap.cpp \
|
src/emptymap.cpp \
|
||||||
src/ozimap.cpp \
|
src/ozimap.cpp \
|
||||||
src/mapdir.cpp \
|
src/mapdir.cpp \
|
||||||
src/matrix.cpp
|
src/matrix.cpp \
|
||||||
|
src/tar.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
|
||||||
|
111
src/ozimap.cpp
111
src/ozimap.cpp
@ -3,6 +3,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QBuffer>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "rd.h"
|
#include "rd.h"
|
||||||
#include "wgs84.h"
|
#include "wgs84.h"
|
||||||
@ -152,19 +153,16 @@ bool OziMap::computeResolution(QList<ReferencePoint> &points)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OziMap::getTileInfo(QDir &set)
|
bool OziMap::getTileName(const QStringList &tiles)
|
||||||
{
|
{
|
||||||
QFileInfoList tiles = set.entryInfoList(QDir::Files);
|
|
||||||
|
|
||||||
if (tiles.isEmpty()) {
|
if (tiles.isEmpty()) {
|
||||||
qWarning("%s: empty tile set", qPrintable(_name));
|
qWarning("%s: empty tile set", qPrintable(_name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < tiles.size(); i++) {
|
for (int i = 0; i < tiles.size(); i++) {
|
||||||
if (tiles.at(i).fileName().contains("_0_0.")) {
|
if (tiles.at(i).contains("_0_0.")) {
|
||||||
_tileName = QString(tiles.at(i).fileName())
|
_tileName = QString(tiles.at(i)).replace("_0_0.", "_%1_%2.");
|
||||||
.replace("_0_0.", "_%1_%2.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,14 +170,27 @@ bool OziMap::getTileInfo(QDir &set)
|
|||||||
qWarning("%s: invalid tile names", qPrintable(_name));
|
qWarning("%s: invalid tile names", qPrintable(_name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_tileName = set.absolutePath() + "/" + _tileName;
|
|
||||||
|
|
||||||
QImage tile(_tileName.arg("0", "0"));
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OziMap::getTileSize()
|
||||||
|
{
|
||||||
|
QString tileName(_tileName.arg(QString::number(0), QString::number(0)));
|
||||||
|
QImage tile;
|
||||||
|
|
||||||
|
if (_tar.isOpen()) {
|
||||||
|
QByteArray ba = _tar.file(tileName);
|
||||||
|
tile = QImage::fromData(ba);
|
||||||
|
} else
|
||||||
|
tile = QImage(tileName);
|
||||||
|
|
||||||
if (tile.isNull()) {
|
if (tile.isNull()) {
|
||||||
qWarning("%s: error retrieving tile size: %s: invalid image",
|
qWarning("%s: error retrieving tile size: %s: invalid image",
|
||||||
qPrintable(_name), qPrintable(_tileName.arg("0", "0")));
|
qPrintable(_name), qPrintable(QFileInfo(tileName).fileName()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_tileSize = tile.size();
|
_tileSize = tile.size();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -187,25 +198,45 @@ bool OziMap::getTileInfo(QDir &set)
|
|||||||
|
|
||||||
OziMap::OziMap(const QString &path, QObject *parent) : Map(parent)
|
OziMap::OziMap(const QString &path, QObject *parent) : Map(parent)
|
||||||
{
|
{
|
||||||
int errorLine;
|
int errorLine = -2;
|
||||||
QList<ReferencePoint> points;
|
QList<ReferencePoint> points;
|
||||||
|
|
||||||
|
|
||||||
_valid = false;
|
_valid = false;
|
||||||
|
|
||||||
QFileInfo fi(path);
|
QFileInfo fi(path);
|
||||||
_name = fi.baseName();
|
_name = fi.fileName();
|
||||||
|
|
||||||
QDir dir(path);
|
QDir dir(path);
|
||||||
QFileInfoList list = dir.entryInfoList(QStringList("*.map"), QDir::Files);
|
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
|
||||||
if (!list.count()) {
|
for (int i = 0; i < mapFiles.count(); i++) {
|
||||||
qWarning("%s: map file not found", qPrintable(_name));
|
const QString &fileName = mapFiles.at(i).fileName();
|
||||||
return;
|
if (fileName.endsWith(".tar")) {
|
||||||
|
if (!_tar.load(mapFiles.at(0).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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (fileName.endsWith(".map")) {
|
||||||
|
QFile mapFile(mapFiles.at(i).absoluteFilePath());
|
||||||
|
errorLine = parseMapFile(mapFile, points);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (errorLine) {
|
||||||
QFile mapFile(list[0].absoluteFilePath());
|
if (errorLine == -2)
|
||||||
if ((errorLine = parseMapFile(mapFile, points))) {
|
qWarning("%s: no map file found", qPrintable(_name));
|
||||||
if (errorLine < 0)
|
else if (errorLine == -1)
|
||||||
qWarning("%s: error opening map file", qPrintable(_name));
|
qWarning("%s: error opening map file", qPrintable(_name));
|
||||||
else
|
else
|
||||||
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
|
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
|
||||||
@ -224,19 +255,29 @@ OziMap::OziMap(const QString &path, QObject *parent) : Map(parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir set(fi.absoluteFilePath() + "/" + "set");
|
if (_tar.isOpen()) {
|
||||||
if (set.exists()) {
|
if (!getTileName(_tar.files()))
|
||||||
if (!getTileInfo(set))
|
return;
|
||||||
|
if (!getTileSize())
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
QFileInfo ii(_imgPath);
|
QDir set(fi.absoluteFilePath() + "/" + "set");
|
||||||
if (ii.isRelative())
|
if (set.exists()) {
|
||||||
_imgPath = fi.absoluteFilePath() + "/" + _imgPath;
|
if (!getTileName(set.entryList()))
|
||||||
ii = QFileInfo(_imgPath);
|
return;
|
||||||
if (!ii.exists()) {
|
_tileName = set.absolutePath() + "/" + _tileName;
|
||||||
qWarning("%s: %s: no such image", qPrintable(_name),
|
if (!getTileSize())
|
||||||
qPrintable(ii.absoluteFilePath()));
|
return;
|
||||||
return;
|
} else {
|
||||||
|
QFileInfo ii(_imgPath);
|
||||||
|
if (ii.isRelative())
|
||||||
|
_imgPath = fi.absoluteFilePath() + "/" + _imgPath;
|
||||||
|
ii = QFileInfo(_imgPath);
|
||||||
|
if (!ii.exists()) {
|
||||||
|
qWarning("%s: %s: no such image", qPrintable(_name),
|
||||||
|
qPrintable(ii.absoluteFilePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +343,16 @@ void OziMap::draw(QPainter *painter, const QRectF &rect)
|
|||||||
for (int j = 0; j < ceil(s.height() / _tileSize.height()); j++) {
|
for (int j = 0; j < ceil(s.height() / _tileSize.height()); j++) {
|
||||||
int x = tl.x() + i * _tileSize.width();
|
int x = tl.x() + i * _tileSize.width();
|
||||||
int y = tl.y() + j * _tileSize.height();
|
int y = tl.y() + j * _tileSize.height();
|
||||||
QPixmap pixmap(_tileName.arg(QString::number(x),
|
QString tileName(_tileName.arg(QString::number(x),
|
||||||
QString::number(y)));
|
QString::number(y)));
|
||||||
|
QPixmap pixmap;
|
||||||
|
|
||||||
|
if (_tar.isOpen()) {
|
||||||
|
QByteArray ba = _tar.file(tileName);
|
||||||
|
pixmap = QPixmap::fromImage(QImage::fromData(ba));
|
||||||
|
} else
|
||||||
|
pixmap = QPixmap(tileName);
|
||||||
|
|
||||||
if (pixmap.isNull()) {
|
if (pixmap.isNull()) {
|
||||||
qWarning("%s: error loading tile image", qPrintable(
|
qWarning("%s: error loading tile image", qPrintable(
|
||||||
_tileName.arg(QString::number(x), QString::number(y))));
|
_tileName.arg(QString::number(x), QString::number(y))));
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QTransform>
|
#include <QTransform>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "tar.h"
|
||||||
#include "coordinates.h"
|
#include "coordinates.h"
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
@ -42,7 +43,8 @@ private:
|
|||||||
int parseMapFile(QIODevice &device, QList<ReferencePoint> &points);
|
int parseMapFile(QIODevice &device, QList<ReferencePoint> &points);
|
||||||
bool computeTransformation(const QList<ReferencePoint> &points);
|
bool computeTransformation(const QList<ReferencePoint> &points);
|
||||||
bool computeResolution(QList<ReferencePoint> &points);
|
bool computeResolution(QList<ReferencePoint> &points);
|
||||||
bool getTileInfo(QDir &set);
|
bool getTileName(const QStringList &tiles);
|
||||||
|
bool getTileSize();
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
QString _imgPath;
|
QString _imgPath;
|
||||||
@ -50,6 +52,7 @@ private:
|
|||||||
QTransform _transform;
|
QTransform _transform;
|
||||||
qreal _resolution;
|
qreal _resolution;
|
||||||
|
|
||||||
|
Tar _tar;
|
||||||
QImage *_img;
|
QImage *_img;
|
||||||
QSize _tileSize;
|
QSize _tileSize;
|
||||||
QString _tileName;
|
QString _tileName;
|
||||||
|
74
src/tar.cpp
Normal file
74
src/tar.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include <cctype>
|
||||||
|
#include <QFile>
|
||||||
|
#include "tar.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define BLOCKSIZE 512
|
||||||
|
|
||||||
|
#define BLOCKCOUNT(size) \
|
||||||
|
((size)/BLOCKSIZE + ((size) % BLOCKSIZE > 0 ? 1 : 0))
|
||||||
|
|
||||||
|
struct Header
|
||||||
|
{
|
||||||
|
char name[100]; /* 0 */
|
||||||
|
char mode[8]; /* 100 */
|
||||||
|
char uid[8]; /* 108 */
|
||||||
|
char gid[8]; /* 116 */
|
||||||
|
char size[12]; /* 124 */
|
||||||
|
char mtime[12]; /* 136 */
|
||||||
|
char chksum[8]; /* 148 */
|
||||||
|
char typeflag; /* 156 */
|
||||||
|
char linkname[100]; /* 157 */
|
||||||
|
char magic[6]; /* 257 */
|
||||||
|
char version[2]; /* 263 */
|
||||||
|
char uname[32]; /* 265 */
|
||||||
|
char gname[32]; /* 297 */
|
||||||
|
char devmajor[8]; /* 329 */
|
||||||
|
char devminor[8]; /* 337 */
|
||||||
|
char prefix[155]; /* 345 */
|
||||||
|
/* 500 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static quint64 number(const char* data, size_t size)
|
||||||
|
{
|
||||||
|
const char *sp;
|
||||||
|
quint64 val = 0;
|
||||||
|
|
||||||
|
for (sp = data; sp < data + size; sp++)
|
||||||
|
if (isdigit(*sp))
|
||||||
|
break;
|
||||||
|
for (; sp < data + size && isdigit(*sp); sp++)
|
||||||
|
val = val * 8 + *sp - '0';
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tar::load(const QString &path)
|
||||||
|
{
|
||||||
|
struct Header hdr;
|
||||||
|
quint64 size;
|
||||||
|
|
||||||
|
_file.setFileName(path);
|
||||||
|
if (!_file.open(QIODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (_file.read((char*)&hdr, BLOCKSIZE)) {
|
||||||
|
size = number(hdr.size, sizeof(hdr.size));
|
||||||
|
if (size)
|
||||||
|
_index.insert(hdr.name, Info(size, _file.pos()));
|
||||||
|
_file.seek(_file.pos() + BLOCKCOUNT(size) * BLOCKSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Tar::file(const QString &name)
|
||||||
|
{
|
||||||
|
QMap<QString, Tar::Info>::const_iterator it = _index.find(name);
|
||||||
|
Q_ASSERT(it != _index.end());
|
||||||
|
|
||||||
|
if (_file.seek(it.value().offset()))
|
||||||
|
return _file.read(it.value().size());
|
||||||
|
else
|
||||||
|
return QByteArray();
|
||||||
|
}
|
35
src/tar.h
Normal file
35
src/tar.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef TAR_H
|
||||||
|
#define TAR_H
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
class Tar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool load(const QString &path);
|
||||||
|
|
||||||
|
QStringList files() const {return _index.keys();}
|
||||||
|
QByteArray file(const QString &name);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
QFile _file;
|
||||||
|
QMap<QString, Info> _index;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAR_H
|
Loading…
Reference in New Issue
Block a user