diff --git a/gpxsee.pro b/gpxsee.pro index 0677af71..e70238a6 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -89,7 +89,7 @@ HEADERS += src/config.h \ src/map/downloader.h \ src/map/tile.h \ src/map/emptymap.h \ - src/map/offlinemap.h \ + src/map/ozimap.h \ src/map/tar.h \ src/map/ozf.h \ src/map/atlas.h \ @@ -139,7 +139,8 @@ HEADERS += src/config.h \ src/map/krovak.h \ src/GUI/kv.h \ src/data/locparser.h \ - src/data/slfparser.h + src/data/slfparser.h \ + src/map/geotiffmap.h SOURCES += src/main.cpp \ src/common/coordinates.cpp \ src/common/rectc.cpp \ @@ -192,7 +193,7 @@ SOURCES += src/main.cpp \ src/map/onlinemap.cpp \ src/map/downloader.cpp \ src/map/emptymap.cpp \ - src/map/offlinemap.cpp \ + src/map/ozimap.cpp \ src/map/tar.cpp \ src/map/atlas.cpp \ src/map/ozf.cpp \ @@ -242,7 +243,8 @@ SOURCES += src/main.cpp \ src/map/krovak.cpp \ src/map/map.cpp \ src/data/locparser.cpp \ - src/data/slfparser.cpp + src/data/slfparser.cpp \ + src/map/geotiffmap.cpp RESOURCES += gpxsee.qrc TRANSLATIONS = lang/gpxsee_cs.ts \ diff --git a/src/map/atlas.cpp b/src/map/atlas.cpp index db0b914d..83ef1943 100644 --- a/src/map/atlas.cpp +++ b/src/map/atlas.cpp @@ -2,7 +2,7 @@ #include #include #include "common/rectc.h" -#include "offlinemap.h" +#include "ozimap.h" #include "tar.h" #include "atlas.h" @@ -12,7 +12,7 @@ #define TL(m) ((m)->xy2pp((m)->bounds().topLeft())) #define BR(m) ((m)->xy2pp((m)->bounds().bottomRight())) -static bool resCmp(OfflineMap *m1, OfflineMap *m2) +static bool resCmp(OziMap *m1, OziMap *m2) { qreal r1, r2; @@ -22,12 +22,12 @@ static bool resCmp(OfflineMap *m1, OfflineMap *m2) return r1 > r2; } -static bool xCmp(OfflineMap *m1, OfflineMap *m2) +static bool xCmp(OziMap *m1, OziMap *m2) { return TL(m1).x() < TL(m2).x(); } -static bool yCmp(OfflineMap *m1, OfflineMap *m2) +static bool yCmp(OziMap *m1, OziMap *m2) { return TL(m1).y() > TL(m2).y(); } @@ -52,7 +52,7 @@ void Atlas::computeBounds() QVector offsets(_maps.count()); for (int z = 0; z < _zooms.count(); z++) { - QList m; + QList m; for (int i = _zooms.at(z).first; i <= _zooms.at(z).last; i++) m.append(_maps.at(i)); @@ -119,11 +119,11 @@ Atlas::Atlas(const QString &fileName, QObject *parent) QString mapFile = maps.at(i).absoluteFilePath() + "/" + maps.at(i).fileName() + ".map"; - OfflineMap *map; + OziMap *map; if (tar.isOpen()) - map = new OfflineMap(mapFile, tar, this); + map = new OziMap(mapFile, tar, this); else - map = new OfflineMap(mapFile, this); + map = new OziMap(mapFile, this); if (map->isValid()) _maps.append(map); @@ -277,7 +277,7 @@ void Atlas::draw(QPainter *painter, const QRectF &rect, bool block) void Atlas::draw(QPainter *painter, const QRectF &rect, int mapIndex) { - OfflineMap *map = _maps.at(mapIndex); + OziMap *map = _maps.at(mapIndex); const QPointF offset = _bounds.at(mapIndex).xy.topLeft(); QRectF pr = QRectF(rect.topLeft() - offset, rect.size()); diff --git a/src/map/atlas.h b/src/map/atlas.h index 3008340d..0a198a6b 100644 --- a/src/map/atlas.h +++ b/src/map/atlas.h @@ -4,7 +4,7 @@ #include "map.h" #include "rectd.h" -class OfflineMap; +class OziMap; class Atlas : public Map { @@ -59,7 +59,7 @@ private: QString _name; - QList _maps; + QList _maps; QVector _zooms; QVector _bounds; int _zoom; diff --git a/src/map/geotiffmap.cpp b/src/map/geotiffmap.cpp new file mode 100644 index 00000000..63125d1e --- /dev/null +++ b/src/map/geotiffmap.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include "config.h" +#include "geotiff.h" +#include "geotiffmap.h" + + +GeoTIFFMap::GeoTIFFMap(const QString &fileName, QObject *parent) + : Map(parent), _img(0), _ratio(1.0), _valid(false) +{ + GeoTIFF gt(fileName); + if (!gt.isValid()) { + _errorString = gt.errorString(); + return; + } else { + _path = fileName; + _projection = gt.projection(); + _transform = gt.transform(); + } + + QImageReader img(_path); + _size = img.size(); + if (!_size.isValid()) { + _errorString = QString("%1: Invalid image file").arg(_path); + return; + } + + _valid = true; +} + +GeoTIFFMap::~GeoTIFFMap() +{ + delete _img; +} + +QString GeoTIFFMap::name() const +{ + QFileInfo fi(_path); + return fi.fileName(); +} + +void GeoTIFFMap::load() +{ + if (!_img) { + _img = new QImage(_path); + if (!_img || _img->isNull()) { + qWarning("%s: error loading map image", qPrintable(_path)); + return; + } +#ifdef ENABLE_HIDPI + _img->setDevicePixelRatio(_ratio); +#endif // ENABLE_HIDPI + } +} + +void GeoTIFFMap::unload() +{ + delete _img; + _img = 0; +} + +QPointF GeoTIFFMap::ll2xy(const Coordinates &c) +{ + return QPointF(_transform.proj2img(_projection.ll2xy(c))) / _ratio; +} + +Coordinates GeoTIFFMap::xy2ll(const QPointF &p) +{ + return _projection.xy2ll(_transform.img2proj(p * _ratio)); +} + +QRectF GeoTIFFMap::bounds() +{ + return QRectF(QPointF(0, 0), _size / _ratio); +} + +void GeoTIFFMap::draw(QPainter *painter, const QRectF &rect, bool block) +{ + Q_UNUSED(block) + + if (_img && !_img->isNull()) + painter->drawImage(rect.topLeft(), *_img, QRectF(rect.topLeft() + * _ratio, rect.size() * _ratio)); +} diff --git a/src/map/geotiffmap.h b/src/map/geotiffmap.h new file mode 100644 index 00000000..775068a9 --- /dev/null +++ b/src/map/geotiffmap.h @@ -0,0 +1,50 @@ +#ifndef GEOTIFFMAP_H +#define GEOTIFFMAP_H + +#include "transform.h" +#include "projection.h" +#include "map.h" + +class GeoTIFFMap : public Map +{ + Q_OBJECT + +public: + GeoTIFFMap(const QString &fileName, QObject *parent = 0); + ~GeoTIFFMap(); + + QString name() const; + + QRectF bounds(); + + int zoom() const {return 0;} + void setZoom(int) {} + int zoomFit(const QSize &, const RectC &) {return 0;} + int zoomIn() {return 0;} + int zoomOut() {return 0;} + + QPointF ll2xy(const Coordinates &c); + Coordinates xy2ll(const QPointF &p); + + void draw(QPainter *painter, const QRectF &rect, bool block); + + void setDevicePixelRatio(qreal ratio) {_ratio = ratio;} + void load(); + void unload(); + + bool isValid() const {return _valid;} + QString errorString() const {return _errorString;} + +private: + QString _path; + Projection _projection; + Transform _transform; + QImage *_img; + QSize _size; + qreal _ratio; + + bool _valid; + QString _errorString; +}; + +#endif // GEOTIFFMAP_H diff --git a/src/map/maplist.cpp b/src/map/maplist.cpp index cd5cba75..97dd88eb 100644 --- a/src/map/maplist.cpp +++ b/src/map/maplist.cpp @@ -1,9 +1,10 @@ #include #include #include "atlas.h" -#include "offlinemap.h" +#include "ozimap.h" #include "onlinemap.h" #include "jnxmap.h" +#include "geotiffmap.h" #include "mapsource.h" #include "maplist.h" @@ -53,8 +54,10 @@ bool MapList::loadFile(const QString &path, bool *atlas, bool dir) return loadSource(path, dir); else if (suffix == "jnx") return loadMap(new JNXMap(path, this), path, dir); + else if (suffix == "tif" || suffix == "tiff") + return loadMap(new GeoTIFFMap(path, this), path, dir); else - return loadMap(new OfflineMap(path, this), path, dir); + return loadMap(new OziMap(path, this), path, dir); } bool MapList::loadDirR(const QString &path) diff --git a/src/map/offlinemap.cpp b/src/map/ozimap.cpp similarity index 86% rename from src/map/offlinemap.cpp rename to src/map/ozimap.cpp index 871a88f5..55649d8d 100644 --- a/src/map/offlinemap.cpp +++ b/src/map/ozimap.cpp @@ -11,12 +11,11 @@ #include "tar.h" #include "ozf.h" #include "mapfile.h" -#include "geotiff.h" #include "config.h" -#include "offlinemap.h" +#include "ozimap.h" -bool OfflineMap::setImageInfo(const QString &path) +bool OziMap::setImageInfo(const QString &path) { QFileInfo ii(_map.path); @@ -59,7 +58,7 @@ bool OfflineMap::setImageInfo(const QString &path) return true; } -bool OfflineMap::setTileInfo(const QStringList &tiles, const QString &path) +bool OziMap::setTileInfo(const QStringList &tiles, const QString &path) { if (!_map.size.isValid()) { _errorString = "Missing total image size (IWH)"; @@ -94,7 +93,7 @@ bool OfflineMap::setTileInfo(const QStringList &tiles, const QString &path) return false; } -OfflineMap::OfflineMap(const QString &fileName, QObject *parent) +OziMap::OziMap(const QString &fileName, QObject *parent) : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false) { QFileInfo fi(fileName); @@ -126,7 +125,10 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent) _projection = mf.projection(); _transform = mf.transform(); } - } else if (suffix == "map") { + + if (!setTileInfo(_tar->files())) + return; + } else { QFile file(fileName); MapFile mf(file); if (!mf.isValid()) { @@ -139,26 +141,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent) _projection = mf.projection(); _transform = mf.transform(); } - } else if (suffix == "tif" || suffix == "tiff") { - GeoTIFF gt(fileName); - if (!gt.isValid()) { - _errorString = gt.errorString(); - return; - } else { - _name = fi.fileName(); - _map.path = fileName; - _projection = gt.projection(); - _transform = gt.transform(); - } - } else { - _errorString = "Not a map file"; - return; - } - if (_tar) { - if (!setTileInfo(_tar->files())) - return; - } else { QDir set(fi.absolutePath() + "/" + "set"); if (set.exists()) { if (!setTileInfo(set.entryList(), set.absolutePath())) @@ -172,7 +155,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent) _valid = true; } -OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent) +OziMap::OziMap(const QString &fileName, Tar &tar, QObject *parent) : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false) { QFileInfo fi(fileName); @@ -202,14 +185,14 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent) _valid = true; } -OfflineMap::~OfflineMap() +OziMap::~OziMap() { delete _img; delete _tar; delete _ozf; } -void OfflineMap::load() +void OziMap::load() { if (_tar && !_tar->isOpen()) { if (!_tar->open()) { @@ -235,13 +218,13 @@ void OfflineMap::load() } } -void OfflineMap::unload() +void OziMap::unload() { delete _img; _img = 0; } -void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const +void OziMap::drawTiled(QPainter *painter, const QRectF &rect) const { QSizeF ts(_tile.size.width() / _ratio, _tile.size.height() / _ratio); QPointF tl(floor(rect.left() / ts.width()) * ts.width(), @@ -282,7 +265,7 @@ void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const } } -void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const +void OziMap::drawOZF(QPainter *painter, const QRectF &rect) const { QSizeF ts(_ozf->tileSize().width() / _ratio, _ozf->tileSize().height() / _ratio); @@ -317,13 +300,13 @@ void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const } } -void OfflineMap::drawImage(QPainter *painter, const QRectF &rect) const +void OziMap::drawImage(QPainter *painter, const QRectF &rect) const { painter->drawImage(rect.topLeft(), *_img, QRectF(rect.topLeft() * _ratio, rect.size() * _ratio)); } -void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block) +void OziMap::draw(QPainter *painter, const QRectF &rect, bool block) { Q_UNUSED(block); @@ -335,7 +318,7 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block) drawImage(painter, rect); } -QPointF OfflineMap::ll2xy(const Coordinates &c) +QPointF OziMap::ll2xy(const Coordinates &c) { QPointF p(_transform.proj2img(_projection.ll2xy(c))); return _ozf @@ -343,7 +326,7 @@ QPointF OfflineMap::ll2xy(const Coordinates &c) : p / _ratio; } -Coordinates OfflineMap::xy2ll(const QPointF &p) +Coordinates OziMap::xy2ll(const QPointF &p) { return _ozf ? _projection.xy2ll(_transform.img2proj(QPointF(p.x() / _scale.x(), @@ -351,14 +334,14 @@ Coordinates OfflineMap::xy2ll(const QPointF &p) : _projection.xy2ll(_transform.img2proj(p * _ratio)); } -QRectF OfflineMap::bounds() +QRectF OziMap::bounds() { return _ozf ? QRectF(QPointF(0, 0), _ozf->size(_zoom) / _ratio) : QRectF(QPointF(0, 0), _map.size / _ratio); } -int OfflineMap::zoomFit(const QSize &size, const RectC &rect) +int OziMap::zoomFit(const QSize &size, const RectC &rect) { if (!_ozf) return _zoom; @@ -381,7 +364,7 @@ int OfflineMap::zoomFit(const QSize &size, const RectC &rect) return _zoom; } -int OfflineMap::zoomIn() +int OziMap::zoomIn() { if (_ozf) rescale(qMax(_zoom - 1, 0)); @@ -389,7 +372,7 @@ int OfflineMap::zoomIn() return _zoom; } -int OfflineMap::zoomOut() +int OziMap::zoomOut() { if (_ozf) rescale(qMin(_zoom + 1, _ozf->zooms() - 1)); @@ -397,7 +380,7 @@ int OfflineMap::zoomOut() return _zoom; } -void OfflineMap::rescale(int zoom) +void OziMap::rescale(int zoom) { _zoom = zoom; _scale = _ozf->scale(zoom); diff --git a/src/map/offlinemap.h b/src/map/ozimap.h similarity index 86% rename from src/map/offlinemap.h rename to src/map/ozimap.h index 604bfb62..8715fc73 100644 --- a/src/map/offlinemap.h +++ b/src/map/ozimap.h @@ -1,5 +1,5 @@ -#ifndef OFFLINEMAP_H -#define OFFLINEMAP_H +#ifndef OZIMAP_H +#define OZIMAP_H #include "transform.h" #include "projection.h" @@ -9,14 +9,14 @@ class Tar; class OZF; class QImage; -class OfflineMap : public Map +class OziMap : public Map { Q_OBJECT public: - OfflineMap(const QString &fileName, QObject *parent = 0); - OfflineMap(const QString &fileName, Tar &tar, QObject *parent = 0); - ~OfflineMap(); + OziMap(const QString &fileName, QObject *parent = 0); + OziMap(const QString &fileName, Tar &tar, QObject *parent = 0); + ~OziMap(); QString name() const {return _name;} @@ -79,4 +79,4 @@ private: QString _errorString; }; -#endif // OFFLINEMAP_H +#endif // OZIMAP_H