mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-02-26 04:00:49 +01:00
Added support for non-SQL Orux maps
+ error handling fixes/improvements
This commit is contained in:
parent
9a4514a464
commit
22e5ffaa0c
@ -234,6 +234,10 @@ void OruxMap::calibrationPoints(QXmlStreamReader &reader, const QSize &size,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
CalibrationPoint p(corner2point(corner, size), Coordinates(lon, lat));
|
CalibrationPoint p(corner2point(corner, size), Coordinates(lon, lat));
|
||||||
|
if (!p.isValid()) {
|
||||||
|
reader.raiseError(QString("invalid calibration point"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
points.append(p);
|
points.append(p);
|
||||||
|
|
||||||
reader.readElementText();
|
reader.readElementText();
|
||||||
@ -242,13 +246,15 @@ void OruxMap::calibrationPoints(QXmlStreamReader &reader, const QSize &size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OruxMap::mapCalibration(QXmlStreamReader &reader, int level)
|
void OruxMap::mapCalibration(QXmlStreamReader &reader, const QString &dir,
|
||||||
|
int level)
|
||||||
{
|
{
|
||||||
int zoom;
|
int zoom;
|
||||||
QSize tileSize, size, calibrationSize;
|
QSize tileSize, size, calibrationSize;
|
||||||
QString datum, projection;
|
QString datum, projection, fileName;
|
||||||
QList<CalibrationPoint> points;
|
QList<CalibrationPoint> points;
|
||||||
Projection proj;
|
Projection proj;
|
||||||
|
Transform t;
|
||||||
|
|
||||||
QXmlStreamAttributes attr = reader.attributes();
|
QXmlStreamAttributes attr = reader.attributes();
|
||||||
if (!intAttr(reader, attr, "layerLevel", zoom))
|
if (!intAttr(reader, attr, "layerLevel", zoom))
|
||||||
@ -256,10 +262,10 @@ void OruxMap::mapCalibration(QXmlStreamReader &reader, int level)
|
|||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("OruxTracker"))
|
if (reader.name() == QLatin1String("OruxTracker"))
|
||||||
oruxTracker(reader, level + 1);
|
oruxTracker(reader, dir, level + 1);
|
||||||
else if (reader.name() == QLatin1String("MapName")) {
|
else if (reader.name() == QLatin1String("MapName")) {
|
||||||
QString name(reader.readElementText());
|
QString name(reader.readElementText());
|
||||||
if (!level)
|
if (!level && dir.isEmpty())
|
||||||
_name = name;
|
_name = name;
|
||||||
} else if (reader.name() == QLatin1String("MapChunks")) {
|
} else if (reader.name() == QLatin1String("MapChunks")) {
|
||||||
int xMax, yMax, width, height;
|
int xMax, yMax, width, height;
|
||||||
@ -277,6 +283,8 @@ void OruxMap::mapCalibration(QXmlStreamReader &reader, int level)
|
|||||||
return;
|
return;
|
||||||
if (!strAttr(reader, attr, "projection", projection))
|
if (!strAttr(reader, attr, "projection", projection))
|
||||||
return;
|
return;
|
||||||
|
if (!strAttr(reader, attr, "file_name", fileName))
|
||||||
|
return;
|
||||||
|
|
||||||
tileSize = QSize(width, height);
|
tileSize = QSize(width, height);
|
||||||
size = QSize(xMax * width, yMax * height);
|
size = QSize(xMax * width, yMax * height);
|
||||||
@ -309,29 +317,50 @@ void OruxMap::mapCalibration(QXmlStreamReader &reader, int level)
|
|||||||
calibrationSize = QSize(width, height);
|
calibrationSize = QSize(width, height);
|
||||||
|
|
||||||
reader.readElementText();
|
reader.readElementText();
|
||||||
} else if (reader.name() == QLatin1String("CalibrationPoints"))
|
} else if (reader.name() == QLatin1String("CalibrationPoints")) {
|
||||||
calibrationPoints(reader, calibrationSize, points);
|
calibrationPoints(reader, calibrationSize, points);
|
||||||
else
|
|
||||||
|
t = computeTransformation(proj, points);
|
||||||
|
if (!t.isValid()) {
|
||||||
|
reader.raiseError(t.errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tileSize.isValid()) {
|
if (tileSize.isValid()) {
|
||||||
Transform t(computeTransformation(proj, points));
|
if (!t.isValid()) {
|
||||||
_zooms.append(Zoom(zoom, tileSize, size, proj, t));
|
reader.raiseError("Invalid map calibration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir mapDir(QFileInfo(path()).absoluteDir());
|
||||||
|
QDir subDir = dir.isEmpty()
|
||||||
|
? mapDir : QDir(mapDir.absoluteFilePath(dir));
|
||||||
|
QString set(subDir.absoluteFilePath("set"));
|
||||||
|
|
||||||
|
_zooms.append(Zoom(zoom, tileSize, size, proj, t, fileName, set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OruxMap::oruxTracker(QXmlStreamReader &reader, int level)
|
void OruxMap::oruxTracker(QXmlStreamReader &reader, const QString &dir,
|
||||||
|
int level)
|
||||||
{
|
{
|
||||||
|
if (level > 1 || (level && !dir.isEmpty())) {
|
||||||
|
reader.raiseError("invalid map nesting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("MapCalibration"))
|
if (reader.name() == QLatin1String("MapCalibration"))
|
||||||
mapCalibration(reader, level);
|
mapCalibration(reader, dir, level);
|
||||||
else
|
else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OruxMap::readXML(const QString &path)
|
bool OruxMap::readXML(const QString &path, const QString &dir)
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
@ -341,7 +370,7 @@ bool OruxMap::readXML(const QString &path)
|
|||||||
QXmlStreamReader reader(&file);
|
QXmlStreamReader reader(&file);
|
||||||
if (reader.readNextStartElement()) {
|
if (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("OruxTracker"))
|
if (reader.name() == QLatin1String("OruxTracker"))
|
||||||
oruxTracker(reader, 0);
|
oruxTracker(reader, dir, 0);
|
||||||
else
|
else
|
||||||
reader.raiseError("Not a Orux map calibration file");
|
reader.raiseError("Not a Orux map calibration file");
|
||||||
}
|
}
|
||||||
@ -354,31 +383,37 @@ bool OruxMap::readXML(const QString &path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OruxMap::OruxMap(const QString &fileName, QObject *parent)
|
OruxMap::OruxMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _zoom(0), _mapRatio(1.0), _valid(false)
|
: Map(fileName, parent), _zoom(0), _mapRatio(1.0), _valid(false)
|
||||||
{
|
{
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDir dir(fi.absoluteDir());
|
||||||
|
|
||||||
if (!readXML(fileName))
|
if (!readXML(fileName))
|
||||||
return;
|
return;
|
||||||
|
if (_zooms.isEmpty()) {
|
||||||
|
QStringList list(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot));
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
QDir subDir(dir.absoluteFilePath(list.at(i)));
|
||||||
|
if (!readXML(subDir.absoluteFilePath(list.at(i) + ".otrk2.xml"),
|
||||||
|
list.at(i))) {
|
||||||
|
_errorString = list.at(i) + ": " + _errorString;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_zooms.isEmpty()) {
|
if (_zooms.isEmpty()) {
|
||||||
_errorString = "No usable zoom level found";
|
_errorString = "No usable zoom level found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
std::sort(_zooms.begin(), _zooms.end());
|
std::sort(_zooms.begin(), _zooms.end());
|
||||||
|
|
||||||
|
|
||||||
QFileInfo fi(fileName);
|
if (dir.exists("OruxMapsImages.db")) {
|
||||||
QDir dir(fi.absoluteDir());
|
|
||||||
QString dbFile(dir.absoluteFilePath("OruxMapsImages.db"));
|
QString dbFile(dir.absoluteFilePath("OruxMapsImages.db"));
|
||||||
if (!QFileInfo::exists(dbFile)) {
|
|
||||||
_errorString = "Image DB file not found";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_db = QSqlDatabase::addDatabase("QSQLITE", dbFile);
|
_db = QSqlDatabase::addDatabase("QSQLITE", dbFile);
|
||||||
_db.setDatabaseName(dbFile);
|
_db.setDatabaseName(dbFile);
|
||||||
_db.setConnectOptions("QSQLITE_OPEN_READONLY");
|
_db.setConnectOptions("QSQLITE_OPEN_READONLY");
|
||||||
|
|
||||||
if (!_db.open()) {
|
if (!_db.open()) {
|
||||||
_errorString = "Error opening database file";
|
_errorString = "Error opening database file";
|
||||||
return;
|
return;
|
||||||
@ -399,6 +434,16 @@ OruxMap::OruxMap(const QString &fileName, QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_db.close();
|
_db.close();
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < _zooms.size(); i++) {
|
||||||
|
if (!_zooms.at(i).set.exists()) {
|
||||||
|
_errorString = "missing set directory (level "
|
||||||
|
+ QString::number(_zooms.at(i).zoom) + ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,11 +481,13 @@ int OruxMap::zoomOut()
|
|||||||
|
|
||||||
void OruxMap::load()
|
void OruxMap::load()
|
||||||
{
|
{
|
||||||
|
if (_db.isValid())
|
||||||
_db.open();
|
_db.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OruxMap::unload()
|
void OruxMap::unload()
|
||||||
{
|
{
|
||||||
|
if (_db.isValid())
|
||||||
_db.close();
|
_db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,20 +497,38 @@ void OruxMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
_mapRatio = mapRatio;
|
_mapRatio = mapRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap OruxMap::tile(int zoom, int x, int y) const
|
QPixmap OruxMap::tile(const Zoom &z, int x, int y) const
|
||||||
{
|
{
|
||||||
|
if (_db.isValid()) {
|
||||||
QSqlQuery query(_db);
|
QSqlQuery query(_db);
|
||||||
query.prepare("SELECT image FROM tiles WHERE z=:z AND x=:x AND y=:y");
|
query.prepare("SELECT image FROM tiles WHERE z=:z AND x=:x AND y=:y");
|
||||||
query.bindValue(":z", zoom);
|
query.bindValue(":z", z.zoom);
|
||||||
query.bindValue(":x", x);
|
query.bindValue(":x", x);
|
||||||
query.bindValue(":y", y);
|
query.bindValue(":y", y);
|
||||||
query.exec();
|
query.exec();
|
||||||
if (!query.first())
|
|
||||||
return QPixmap();
|
|
||||||
|
|
||||||
|
if (!query.first()) {
|
||||||
|
qWarning("%s: SQL %d-%d-%d: not found", qPrintable(name()), z.zoom,
|
||||||
|
x, y);
|
||||||
|
return QPixmap();
|
||||||
|
} else {
|
||||||
QImage img(QImage::fromData(query.value(0).toByteArray()));
|
QImage img(QImage::fromData(query.value(0).toByteArray()));
|
||||||
return QPixmap::fromImage(img);
|
return QPixmap::fromImage(img);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
QString fileName(z.fileName + "_" + QString::number(x) + "_"
|
||||||
|
+ QString::number(y) + ".omc2");
|
||||||
|
QString path(z.set.absoluteFilePath(fileName));
|
||||||
|
if (!QFileInfo::exists(path)) {
|
||||||
|
qWarning("%s: %s: not found", qPrintable(name()),
|
||||||
|
qPrintable(fileName));
|
||||||
|
return QPixmap();
|
||||||
|
} else {
|
||||||
|
QImage img(path);
|
||||||
|
return QPixmap::fromImage(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OruxMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
void OruxMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||||
{
|
{
|
||||||
@ -484,14 +549,12 @@ void OruxMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
+ "_" + QString::number(x/z.tileSize.width())
|
+ "_" + QString::number(x/z.tileSize.width())
|
||||||
+ "_" + QString::number(y/z.tileSize.height());
|
+ "_" + QString::number(y/z.tileSize.height());
|
||||||
if (!QPixmapCache::find(key, &pixmap)) {
|
if (!QPixmapCache::find(key, &pixmap)) {
|
||||||
pixmap = tile(z.zoom, x/z.tileSize.width(), y/z.tileSize.height());
|
pixmap = tile(z, x/z.tileSize.width(), y/z.tileSize.height());
|
||||||
if (!pixmap.isNull())
|
if (!pixmap.isNull())
|
||||||
QPixmapCache::insert(key, pixmap);
|
QPixmapCache::insert(key, pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmap.isNull())
|
if (!pixmap.isNull()) {
|
||||||
qWarning("%s: error loading tile image", qPrintable(key));
|
|
||||||
else {
|
|
||||||
pixmap.setDevicePixelRatio(_mapRatio);
|
pixmap.setDevicePixelRatio(_mapRatio);
|
||||||
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
|
QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
|
||||||
painter->drawPixmap(tp, pixmap);
|
painter->drawPixmap(tp, pixmap);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
|
#include <QDir>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
@ -44,9 +45,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct Zoom {
|
struct Zoom {
|
||||||
Zoom(int zoom, const QSize &tileSize, const QSize &size,
|
Zoom(int zoom, const QSize &tileSize, const QSize &size,
|
||||||
const Projection &proj, const Transform &transform)
|
const Projection &proj, const Transform &transform,
|
||||||
|
const QString &fileName, const QString &set)
|
||||||
: zoom(zoom), tileSize(tileSize), size(size), projection(proj),
|
: zoom(zoom), tileSize(tileSize), size(size), projection(proj),
|
||||||
transform(transform) {}
|
transform(transform), fileName(fileName), set(set) {}
|
||||||
bool operator<(const Zoom &other) const
|
bool operator<(const Zoom &other) const
|
||||||
{return zoom < other.zoom;}
|
{return zoom < other.zoom;}
|
||||||
|
|
||||||
@ -55,14 +57,16 @@ private:
|
|||||||
QSize size;
|
QSize size;
|
||||||
Projection projection;
|
Projection projection;
|
||||||
Transform transform;
|
Transform transform;
|
||||||
|
QString fileName;
|
||||||
|
QDir set;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool readXML(const QString &path);
|
bool readXML(const QString &path, const QString &dir = QString());
|
||||||
void oruxTracker(QXmlStreamReader &reader, int level);
|
void oruxTracker(QXmlStreamReader &reader, const QString &dir, int level);
|
||||||
void mapCalibration(QXmlStreamReader &reader, int level);
|
void mapCalibration(QXmlStreamReader &reader, const QString &dir, int level);
|
||||||
void calibrationPoints(QXmlStreamReader &reader, const QSize &size,
|
void calibrationPoints(QXmlStreamReader &reader, const QSize &size,
|
||||||
QList<CalibrationPoint> &points);
|
QList<CalibrationPoint> &points);
|
||||||
QPixmap tile(int zoom, int x, int y) const;
|
QPixmap tile(const Zoom &z, int x, int y) const;
|
||||||
|
|
||||||
friend QDebug operator<<(QDebug dbg, const Zoom &zoom);
|
friend QDebug operator<<(QDebug dbg, const Zoom &zoom);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user