diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 4090e74a..bc02ff3b 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -1750,7 +1750,7 @@ bool GUI::loadMapNode(const TreeNode &node, MapAction *&action, bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError) { - TreeNode maps(MapList::loadMaps(fileName)); + TreeNode maps(MapList::loadMaps(fileName, _mapView->inputProjection())); QList existingActions(_mapsActionGroup->actions()); return loadMapNode(maps, action, existingActions, showError); @@ -1854,7 +1854,7 @@ void GUI::loadMapDir() return; QFileInfo fi(dir); - TreeNode maps(MapList::loadMaps(dir)); + TreeNode maps(MapList::loadMaps(dir, _mapView->inputProjection())); QList existingActions(_mapsActionGroup->actions()); QList actions; QMenu *menu = new QMenu(maps.name()); @@ -2985,7 +2985,7 @@ void GUI::loadInitialMaps(const QString &selected) if (mapDir.isNull()) return; - TreeNode maps(MapList::loadMaps(mapDir)); + TreeNode maps(MapList::loadMaps(mapDir, _mapView->inputProjection())); createMapNodeMenu(createMapActionsNode(maps), _mapMenu, _mapsEnd); // Select the active map according to the user settings diff --git a/src/GUI/mapitem.cpp b/src/GUI/mapitem.cpp index af275a19..4c66e521 100644 --- a/src/GUI/mapitem.cpp +++ b/src/GUI/mapitem.cpp @@ -81,15 +81,15 @@ ToolTip MapItem::info() const return tt; } -MapItem::MapItem(MapAction *action, Map *map, const Projection &proj, - GraphicsItem *parent) : PlaneItem(parent) +MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent) + : PlaneItem(parent) { Map *src = action->data().value(); Q_ASSERT(map->isReady()); _name = src->name(); _fileName = src->path(); - _bounds = src->llBounds(proj); + _bounds = src->llBounds(); connect(this, &MapItem::triggered, action, &MapAction::trigger); diff --git a/src/GUI/mapitem.h b/src/GUI/mapitem.h index 72f8d63a..a347448f 100644 --- a/src/GUI/mapitem.h +++ b/src/GUI/mapitem.h @@ -11,8 +11,7 @@ class MapItem : public QObject, public PlaneItem Q_OBJECT public: - MapItem(MapAction *action, Map *map, const Projection &proj, - GraphicsItem *parent = 0); + MapItem(MapAction *action, Map *map, GraphicsItem *parent = 0); QPainterPath shape() const {return _painterPath;} QRectF boundingRect() const {return _painterPath.boundingRect();} diff --git a/src/GUI/mapview.cpp b/src/GUI/mapview.cpp index 9f1be444..4cf22435 100644 --- a/src/GUI/mapview.cpp +++ b/src/GUI/mapview.cpp @@ -250,7 +250,7 @@ void MapView::addWaypoints(const QVector &waypoints) MapItem *MapView::addMap(MapAction *map) { - MapItem *mi = new MapItem(map, _map, _inputProjection); + MapItem *mi = new MapItem(map, _map); mi->setColor(_palette.nextColor()); mi->setWidth(_areaWidth); mi->setPenStyle(_areaStyle); @@ -331,7 +331,7 @@ int MapView::fitMapZoom() const RectC br = _tr | _rr | _wr | _ar; return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN), - br.isNull() ? _map->llBounds(_inputProjection) : br); + br.isNull() ? _map->llBounds() : br); } QPointF MapView::contentCenter() const diff --git a/src/GUI/mapview.h b/src/GUI/mapview.h index c49f9408..8e0fa323 100644 --- a/src/GUI/mapview.h +++ b/src/GUI/mapview.h @@ -98,6 +98,7 @@ public: void fitContentToSize(); RectC boundingRect() const; + const Projection &inputProjection() const {return _inputProjection;} #ifdef Q_OS_ANDROID signals: diff --git a/src/map/aqmmap.cpp b/src/map/aqmmap.cpp index 7226cde6..c26676f1 100644 --- a/src/map/aqmmap.cpp +++ b/src/map/aqmmap.cpp @@ -405,8 +405,10 @@ void AQMMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp) painter->drawPixmap(tp, pixmap); } -Map *AQMMap::create(const QString &path, bool *isDir) +Map *AQMMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/aqmmap.h b/src/map/aqmmap.h index 46cb4e43..8ce643aa 100644 --- a/src/map/aqmmap.h +++ b/src/map/aqmmap.h @@ -17,7 +17,7 @@ public: QString name() const {return _name;} QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} qreal resolution(const QRectF &rect); int zoom() const {return _zoom;} @@ -38,7 +38,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: struct File { diff --git a/src/map/atlas.cpp b/src/map/atlas.cpp index db5bf4e4..25bf5422 100644 --- a/src/map/atlas.cpp +++ b/src/map/atlas.cpp @@ -100,8 +100,9 @@ void Atlas::computeBounds() QRectF(offsets.at(i), _maps.at(i)->bounds().size())); } -Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent) - : Map(fileName, parent), _zoom(0), _mapIndex(-1), _valid(false) +Atlas::Atlas(const QString &fileName, bool TAR, const Projection &proj, + QObject *parent) : Map(fileName, parent), _zoom(0), _mapIndex(-1), + _valid(false) { QFileInfo fi(fileName); QByteArray ba; @@ -142,39 +143,39 @@ Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent) for (int i = 0; i < maps.count(); i++) { OziMap *map; if (TAR) - map = new OziMap(maps.at(i).absoluteFilePath(), tar, this); + map = new OziMap(maps.at(i).absoluteFilePath(), tar, proj, this); else { QString cf(calibrationFile(maps.at(i).absoluteFilePath())); if (cf.isNull()) { _errorString = "No calibration file found"; return; } - map = new OziMap(cf, this); + map = new OziMap(cf, proj, this); } if (map->isValid()) _maps.append(map); else { - _errorString = QString("%1: %2") - .arg(map->path(), map->errorString()); - return; + qWarning("%s: %s", qPrintable(map->path()), + qPrintable(map->errorString())); + delete map; } } } if (_maps.isEmpty()) { - _errorString = "No maps found in atlas"; + _errorString = "No usable map found in atlas"; return; } _valid = true; } -RectC Atlas::llBounds(const Projection &proj) +RectC Atlas::llBounds() { RectC bounds; for (int i = 0; i < _maps.size(); i++) - bounds |= _maps.at(i)->llBounds(proj); + bounds |= _maps.at(i)->llBounds(); return bounds; } @@ -330,18 +331,34 @@ void Atlas::unload() _bounds.clear(); } -Map *Atlas::createTAR(const QString &path, bool *isDir) +Map *Atlas::createTAR(const QString &path, const Projection &proj, bool *isDir) { if (isDir) *isDir = true; - return new Atlas(path, true); + return new Atlas(path, true, proj); } -Map *Atlas::createTBA(const QString &path, bool *isDir) +Map *Atlas::createTBA(const QString &path, const Projection &proj, bool *isDir) { if (isDir) *isDir = true; - return new Atlas(path, false); + return new Atlas(path, false, proj); } + +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug dbg, const Atlas::Bounds &bounds) +{ + dbg.nospace() << "Bounds(" << bounds.xy << ", " << bounds.pp << ")"; + + return dbg.space(); +} + +QDebug operator<<(QDebug dbg, const Atlas::Zoom &zoom) +{ + dbg.nospace() << "Zoom(" << zoom.first << ", " << zoom.last << ")"; + + return dbg.space(); +} +#endif // QT_NO_DEBUG diff --git a/src/map/atlas.h b/src/map/atlas.h index 5a2306bc..23964854 100644 --- a/src/map/atlas.h +++ b/src/map/atlas.h @@ -12,12 +12,13 @@ class Atlas : public Map Q_OBJECT public: - Atlas(const QString &fileName, bool TAR, QObject *parent = 0); + Atlas(const QString &fileName, bool TAR, const Projection &proj, + QObject *parent = 0); QString name() const {return _name;} QRectF bounds(); - RectC llBounds(const Projection &proj); + RectC llBounds(); int zoom() const {return _zoom;} void setZoom(int zoom); @@ -37,8 +38,10 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *createTAR(const QString &path, bool *isDir); - static Map *createTBA(const QString &path, bool *isDir); + static Map *createTAR(const QString &path, const Projection &proj, + bool *isDir); + static Map *createTBA(const QString &path, const Projection &proj, + bool *isDir); private: struct Zoom { @@ -61,6 +64,9 @@ private: void computeZooms(); void computeBounds(); + friend QDebug operator<<(QDebug dbg, const Bounds &bounds); + friend QDebug operator<<(QDebug dbg, const Zoom &zoom); + QString _name; QList _maps; @@ -73,4 +79,9 @@ private: QString _errorString; }; +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug dbg, const Atlas::Zoom &zoom); +QDebug operator<<(QDebug dbg, const Atlas::Bounds &bounds); +#endif // QT_NO_DEBUG + #endif // ATLAS_H diff --git a/src/map/bsbmap.cpp b/src/map/bsbmap.cpp index f7a4b18e..861f4bd7 100644 --- a/src/map/bsbmap.cpp +++ b/src/map/bsbmap.cpp @@ -462,8 +462,10 @@ void BSBMap::unload() _img = 0; } -Map *BSBMap::create(const QString &path, bool *isMap) +Map *BSBMap::create(const QString &path, const Projection &proj, bool *isMap) { + Q_UNUSED(proj); + if (isMap) *isMap = false; diff --git a/src/map/bsbmap.h b/src/map/bsbmap.h index b2db5afa..8bdffebd 100644 --- a/src/map/bsbmap.h +++ b/src/map/bsbmap.h @@ -32,7 +32,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isMap); + static Map *create(const QString &path, const Projection &proj, bool *isMap); private: bool parseBSB(const QByteArray &line); diff --git a/src/map/encatlas.cpp b/src/map/encatlas.cpp index 8107a83d..2e08625f 100644 --- a/src/map/encatlas.cpp +++ b/src/map/encatlas.cpp @@ -378,8 +378,10 @@ void ENCAtlas::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map *ENCAtlas::create(const QString &path, bool *isDir) +Map *ENCAtlas::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = true; diff --git a/src/map/encatlas.h b/src/map/encatlas.h index c1b6b351..8b6ae655 100644 --- a/src/map/encatlas.h +++ b/src/map/encatlas.h @@ -22,7 +22,7 @@ public: QString name() const {return _name;} QRectF bounds() {return _bounds;} - RectC llBounds(const Projection &) {return _llBounds;} + RectC llBounds() {return _llBounds;} int zoom() const {return _zoom;} void setZoom(int zoom); @@ -44,7 +44,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private slots: void jobFinished(ENCJob *job); diff --git a/src/map/encmap.cpp b/src/map/encmap.cpp index 3a5c5d2e..e37f67a1 100644 --- a/src/map/encmap.cpp +++ b/src/map/encmap.cpp @@ -345,8 +345,10 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map *ENCMap::create(const QString &path, bool *isMap) +Map *ENCMap::create(const QString &path, const Projection &proj, bool *isMap) { + Q_UNUSED(proj); + if (isMap) *isMap = false; diff --git a/src/map/encmap.h b/src/map/encmap.h index 2243cdbb..5b8045ca 100644 --- a/src/map/encmap.h +++ b/src/map/encmap.h @@ -23,7 +23,7 @@ public: QString name() const {return _name;} QRectF bounds() {return _bounds;} - RectC llBounds(const Projection &) {return _llBounds;} + RectC llBounds() {return _llBounds;} int zoom() const {return _zoom;} void setZoom(int zoom); @@ -45,7 +45,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isMap); + static Map *create(const QString &path, const Projection &proj, bool *isMap); private slots: void jobFinished(ENCJob *job); diff --git a/src/map/gemfmap.cpp b/src/map/gemfmap.cpp index 3af63c8b..4b8e4946 100644 --- a/src/map/gemfmap.cpp +++ b/src/map/gemfmap.cpp @@ -301,8 +301,10 @@ void GEMFMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp) painter->drawPixmap(tp, pixmap); } -Map *GEMFMap::create(const QString &path, bool *isDir) +Map *GEMFMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/gemfmap.h b/src/map/gemfmap.h index 9b82fe5e..303a1831 100644 --- a/src/map/gemfmap.h +++ b/src/map/gemfmap.h @@ -14,7 +14,7 @@ public: GEMFMap(const QString &fileName, QObject *parent = 0); QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} int zoom() const {return _zi;} void setZoom(int zoom) {_zi = zoom;} @@ -35,7 +35,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: struct Region { diff --git a/src/map/geotiffmap.cpp b/src/map/geotiffmap.cpp index 6d139f0d..c0548bac 100644 --- a/src/map/geotiffmap.cpp +++ b/src/map/geotiffmap.cpp @@ -73,8 +73,10 @@ void GeoTIFFMap::unload() _img = 0; } -Map *GeoTIFFMap::create(const QString &path, bool *isDir) +Map *GeoTIFFMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/geotiffmap.h b/src/map/geotiffmap.h index 1bf0f33f..26fd986a 100644 --- a/src/map/geotiffmap.h +++ b/src/map/geotiffmap.h @@ -29,7 +29,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: Projection _projection; diff --git a/src/map/gmifile.cpp b/src/map/gmifile.cpp index 71505dc8..aeb5d80b 100644 --- a/src/map/gmifile.cpp +++ b/src/map/gmifile.cpp @@ -1,5 +1,3 @@ -#include "common/csv.h" -#include "pcs.h" #include "gmifile.h" static CalibrationPoint calibrationPoint(const QByteArray line) @@ -19,7 +17,7 @@ static CalibrationPoint calibrationPoint(const QByteArray line) : CalibrationPoint(); } -bool GmiFile::parse(QIODevice &device, QList &points) +bool GmiFile::parse(QIODevice &device) { int ln = 1; int width, height; @@ -56,7 +54,7 @@ bool GmiFile::parse(QIODevice &device, QList &points) } else { CalibrationPoint cp(calibrationPoint(line)); if (cp.isValid()) - points.append(cp); + _points.append(cp); else break; } @@ -66,32 +64,10 @@ bool GmiFile::parse(QIODevice &device, QList &points) device.close(); - return (points.size() >= 2); -} - -bool GmiFile::computeTransformation(const QList &points) -{ - QList rp; - Projection proj(GCS::WGS84()); - - for (int i = 0; i < points.size(); i++) - rp.append(points.at(i).rp(proj)); - - _transform = Transform(rp); - if (!_transform.isValid()) { - _errorString = _transform.errorString(); - return false; - } - - return true; + return (_points.size() >= 2); } GmiFile::GmiFile(QIODevice &file) { - QList points; - - if (!parse(file, points)) - return; - if (!computeTransformation(points)) - return; + _valid = parse(file); } diff --git a/src/map/gmifile.h b/src/map/gmifile.h index f93bb2ef..4d907b09 100644 --- a/src/map/gmifile.h +++ b/src/map/gmifile.h @@ -1,32 +1,30 @@ #ifndef GMIFILE_H #define GMIFILE_H -#include "transform.h" #include "calibrationpoint.h" class QIODevice; -class GCS; class GmiFile { public: GmiFile(QIODevice &file); - bool isValid() const {return !_image.isNull() && _transform.isValid();} + bool isValid() const {return _valid;} const QString &errorString() const {return _errorString;} - const Transform &transform() const {return _transform;} const QString &image() const {return _image;} const QSize &size() const {return _size;} + const QList &calibrationPoints() const {return _points;} private: - bool parse(QIODevice &device, QList &points); - bool computeTransformation(const QList &points); + bool parse(QIODevice &device); QString _image; QSize _size; - Transform _transform; + QList _points; + bool _valid; QString _errorString; }; diff --git a/src/map/imgmap.cpp b/src/map/imgmap.cpp index be4d242d..305a98a4 100644 --- a/src/map/imgmap.cpp +++ b/src/map/imgmap.cpp @@ -264,16 +264,20 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map* IMGMap::createIMG(const QString &path, bool *isDir) +Map* IMGMap::createIMG(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; return new IMGMap(path, false); } -Map* IMGMap::createGMAP(const QString &path, bool *isDir) +Map* IMGMap::createGMAP(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = true; diff --git a/src/map/imgmap.h b/src/map/imgmap.h index 0a699669..8b96ab60 100644 --- a/src/map/imgmap.h +++ b/src/map/imgmap.h @@ -55,7 +55,7 @@ public: QString name() const {return _data.first()->name();} QRectF bounds() {return _bounds;} - RectC llBounds(const Projection &) {return _data.first()->bounds();} + RectC llBounds() {return _data.first()->bounds();} int zoom() const {return _zoom;} void setZoom(int zoom); @@ -77,8 +77,10 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map* createIMG(const QString &path, bool *isDir); - static Map* createGMAP(const QString &path, bool *isDir); + static Map* createIMG(const QString &path, const Projection &proj, + bool *isDir); + static Map* createGMAP(const QString &path, const Projection &proj, + bool *isDir); private slots: void jobFinished(IMGMapJob *job); diff --git a/src/map/jnxmap.cpp b/src/map/jnxmap.cpp index 95f706c1..b361d2be 100644 --- a/src/map/jnxmap.cpp +++ b/src/map/jnxmap.cpp @@ -274,8 +274,10 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags) tree.Search(min, max, cb, &ctx); } -Map *JNXMap::create(const QString &path, bool *isDir) +Map *JNXMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/jnxmap.h b/src/map/jnxmap.h index 46e20171..303483ad 100644 --- a/src/map/jnxmap.h +++ b/src/map/jnxmap.h @@ -19,7 +19,7 @@ public: ~JNXMap(); QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} int zoom() const {return _zoom;} void setZoom(int zoom) {_zoom = zoom;} @@ -39,7 +39,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: struct Tile { diff --git a/src/map/kmzmap.cpp b/src/map/kmzmap.cpp index 8685800d..1f0e5a4d 100644 --- a/src/map/kmzmap.cpp +++ b/src/map/kmzmap.cpp @@ -484,8 +484,10 @@ void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex) painter->restore(); } -Map *KMZMap::create(const QString &path, bool *isDir) +Map *KMZMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/kmzmap.h b/src/map/kmzmap.h index c6d76473..4a4f2d79 100644 --- a/src/map/kmzmap.h +++ b/src/map/kmzmap.h @@ -18,7 +18,7 @@ public: KMZMap(const QString &fileName, QObject *parent = 0); ~KMZMap(); - RectC llBounds(const Projection &) {return _llbounds;} + RectC llBounds() {return _llbounds;} QRectF bounds(); int zoom() const {return _zoom;} @@ -39,7 +39,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: class Overlay { diff --git a/src/map/map.cpp b/src/map/map.cpp index fde95e08..2ade9b9e 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -30,12 +30,8 @@ static void growBottom(const Coordinates &c, RectC &rect) rect.setBottom(c.lat()); } -RectC Map::llBounds(const Projection &proj) +RectC Map::llBounds() { - Q_UNUSED(proj); - - /* We use bounds() and xy2ll() here as this fallback implementation is - used ONLY for maps providing those functions since map creation. */ QRectF b(bounds()); double dx = b.width() / SAMPLES; double dy = b.height() / SAMPLES; diff --git a/src/map/map.h b/src/map/map.h index 30a99be6..68101d9e 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -28,19 +28,19 @@ public: : QObject(parent), _path(path) {} virtual ~Map() {} - /* Functions available since map creation */ const QString &path() const {return _path;} virtual QString name() const {return Util::file2name(path());} - virtual RectC llBounds(const Projection &proj); virtual bool isValid() const {return true;} virtual bool isReady() const {return true;} virtual QString errorString() const {return QString();} - /* Functions that shall be called after load() */ virtual void load(const Projection &, const Projection &, qreal, bool) {} virtual void unload() {} + /* llBounds() is mandatory for maps that do not provide bounds() until + load() is called! */ + virtual RectC llBounds(); virtual QRectF bounds() = 0; virtual qreal resolution(const QRectF &rect); diff --git a/src/map/maplist.cpp b/src/map/maplist.cpp index 2ed37571..61867c75 100644 --- a/src/map/maplist.cpp +++ b/src/map/maplist.cpp @@ -65,7 +65,7 @@ MapList::ParserMap MapList::parsers() MapList::ParserMap MapList::_parsers = parsers(); -Map *MapList::loadFile(const QString &path, bool *isDir) +Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir) { ParserMap::iterator it; QFileInfo fi(Util::displayName(path)); @@ -76,7 +76,7 @@ Map *MapList::loadFile(const QString &path, bool *isDir) if ((it = _parsers.find(suffix)) != _parsers.end()) { while (it != _parsers.end() && it.key() == suffix) { delete map; - map = it.value()(path, isDir); + map = it.value()(path, proj, isDir); if (map->isValid()) return map; else @@ -85,7 +85,7 @@ Map *MapList::loadFile(const QString &path, bool *isDir) } } else { for (it = _parsers.begin(); it != _parsers.end(); it++) { - map = it.value()(path, isDir); + map = it.value()(path, proj, isDir); if (map->isValid()) return map; else { @@ -103,7 +103,8 @@ Map *MapList::loadFile(const QString &path, bool *isDir) return map ? map : new InvalidMap(path, "Unknown file format"); } -TreeNode MapList::loadDir(const QString &path, TreeNode *parent) +TreeNode MapList::loadDir(const QString &path, const Projection &proj, + TreeNode *parent) { QDir md(path); md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); @@ -120,12 +121,12 @@ TreeNode MapList::loadDir(const QString &path, TreeNode *parent) QString suffix = fi.suffix().toLower(); if (fi.isDir()) { - TreeNode child(loadDir(fi.absoluteFilePath(), &tree)); + TreeNode child(loadDir(fi.absoluteFilePath(), proj, &tree)); if (!child.isEmpty()) tree.addChild(child); } else if (filter().contains("*." + suffix)) { bool isDir = false; - Map *map = loadFile(fi.absoluteFilePath(), &isDir); + Map *map = loadFile(fi.absoluteFilePath(), proj, &isDir); if (isDir) { if (parent) parent->addItem(map); @@ -140,13 +141,13 @@ TreeNode MapList::loadDir(const QString &path, TreeNode *parent) return tree; } -TreeNode MapList::loadMaps(const QString &path) +TreeNode MapList::loadMaps(const QString &path, const Projection &proj) { if (QFileInfo(path).isDir()) - return loadDir(path); + return loadDir(path, proj); else { TreeNode tree; - tree.addItem(loadFile(path)); + tree.addItem(loadFile(path, proj)); return tree; } } diff --git a/src/map/maplist.h b/src/map/maplist.h index 8129b16a..7985d6b1 100644 --- a/src/map/maplist.h +++ b/src/map/maplist.h @@ -10,16 +10,18 @@ class Projection; class MapList { public: - static TreeNode loadMaps(const QString &path); + static TreeNode loadMaps(const QString &path, const Projection &proj); static QString formats(); static QStringList filter(); private: - typedef Map*(*ParserCb)(const QString &, bool *isDir); + typedef Map*(*ParserCb)(const QString &, const Projection &, bool *); typedef QMultiMap ParserMap; - static Map *loadFile(const QString &path, bool *isDir = 0); - static TreeNode loadDir(const QString &path, TreeNode *parent = 0); + static Map *loadFile(const QString &path, const Projection &proj, + bool *isDir = 0); + static TreeNode loadDir(const QString &path, const Projection &proj, + TreeNode *parent = 0); static ParserMap parsers(); static ParserMap _parsers; diff --git a/src/map/mapsforgemap.cpp b/src/map/mapsforgemap.cpp index 766f2c34..ef7c1aa3 100644 --- a/src/map/mapsforgemap.cpp +++ b/src/map/mapsforgemap.cpp @@ -209,8 +209,11 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map *MapsforgeMap::create(const QString &path, bool *isMap) +Map *MapsforgeMap::create(const QString &path, const Projection &proj, + bool *isMap) { + Q_UNUSED(proj); + if (isMap) *isMap = false; diff --git a/src/map/mapsforgemap.h b/src/map/mapsforgemap.h index 72169aa0..5baf2456 100644 --- a/src/map/mapsforgemap.h +++ b/src/map/mapsforgemap.h @@ -52,7 +52,7 @@ public: MapsforgeMap(const QString &fileName, QObject *parent = 0); QRectF bounds() {return _bounds;} - RectC llBounds(const Projection &) {return _data.bounds();} + RectC llBounds() {return _data.bounds();} int zoom() const {return _zoom;} void setZoom(int zoom); @@ -74,7 +74,7 @@ public: bool isValid() const {return _data.isValid();} QString errorString() const {return _data.errorString();} - static Map *create(const QString &path, bool *isMap); + static Map *create(const QString &path, const Projection &proj, bool *isMap); private slots: void jobFinished(MapsforgeMapJob *job); diff --git a/src/map/mapsource.cpp b/src/map/mapsource.cpp index 5569611d..2641a47d 100644 --- a/src/map/mapsource.cpp +++ b/src/map/mapsource.cpp @@ -214,8 +214,9 @@ void MapSource::map(QXmlStreamReader &reader, Config &config) } } -Map *MapSource::create(const QString &path, bool *isDir) +Map *MapSource::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); Config config; QFile file(path); diff --git a/src/map/mapsource.h b/src/map/mapsource.h index 97542a28..c9ad98a7 100644 --- a/src/map/mapsource.h +++ b/src/map/mapsource.h @@ -15,7 +15,7 @@ class Projection; class MapSource { public: - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: enum Type { diff --git a/src/map/mbtilesmap.cpp b/src/map/mbtilesmap.cpp index 9b5224c5..8bad9983 100644 --- a/src/map/mbtilesmap.cpp +++ b/src/map/mbtilesmap.cpp @@ -338,8 +338,10 @@ Coordinates MBTilesMap::xy2ll(const QPointF &p) * coordinatesRatio()); } -Map *MBTilesMap::create(const QString &path, bool *isDir) +Map *MBTilesMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/mbtilesmap.h b/src/map/mbtilesmap.h index 0b3a8b41..28511739 100644 --- a/src/map/mbtilesmap.h +++ b/src/map/mbtilesmap.h @@ -13,7 +13,7 @@ public: QString name() const {return _name;} QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} qreal resolution(const QRectF &rect); int zoom() const {return _zi;} @@ -34,7 +34,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: qreal tileSize() const; diff --git a/src/map/oruxmap.cpp b/src/map/oruxmap.cpp index 03653dea..7d82fb1a 100644 --- a/src/map/oruxmap.cpp +++ b/src/map/oruxmap.cpp @@ -590,8 +590,10 @@ Coordinates OruxMap::xy2ll(const QPointF &p) return z.projection.xy2ll(z.transform.img2proj(p * _mapRatio)); } -Map *OruxMap::create(const QString &path, bool *isDir) +Map *OruxMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = true; diff --git a/src/map/oruxmap.h b/src/map/oruxmap.h index fc3f36f7..ca3a76be 100644 --- a/src/map/oruxmap.h +++ b/src/map/oruxmap.h @@ -40,7 +40,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: struct Zoom { diff --git a/src/map/osmdroidmap.cpp b/src/map/osmdroidmap.cpp index 47fb0559..8c803fbd 100644 --- a/src/map/osmdroidmap.cpp +++ b/src/map/osmdroidmap.cpp @@ -309,8 +309,11 @@ Coordinates OsmdroidMap::xy2ll(const QPointF &p) return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio); } -Map *OsmdroidMap::create(const QString &path, bool *isDir) +Map *OsmdroidMap::create(const QString &path, const Projection &proj, + bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/osmdroidmap.h b/src/map/osmdroidmap.h index 6344b2a0..63c27faf 100644 --- a/src/map/osmdroidmap.h +++ b/src/map/osmdroidmap.h @@ -11,7 +11,7 @@ public: OsmdroidMap(const QString &fileName, QObject *parent = 0); QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} qreal resolution(const QRectF &rect); int zoom() const {return _zoom;} @@ -32,7 +32,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: int limitZoom(int zoom) const; diff --git a/src/map/ozimap.cpp b/src/map/ozimap.cpp index 8d414308..f11eef47 100644 --- a/src/map/ozimap.cpp +++ b/src/map/ozimap.cpp @@ -17,6 +17,21 @@ #include "ozimap.h" +static QString tarFile(const QString &path) +{ + QDir dir(path); + QFileInfoList files = dir.entryInfoList(QDir::Files); + + for (int i = 0; i < files.size(); i++) { + const QFileInfo &fi = files.at(i); + + if (fi.suffix().toLower() == "tar") + return fi.absoluteFilePath(); + } + + return QString(); +} + QString OziMap::calibrationFile(const QStringList &files, const QString path, CalibrationType &type) { @@ -39,9 +54,9 @@ QString OziMap::calibrationFile(const QStringList &files, const QString path, return QString(); } -OziMap::OziMap(const QString &fileName, QObject *parent) +OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent) : Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0), - _hasProj(true), _valid(false) + _valid(false) { QFileInfo fi(fileName); QString suffix(fi.suffix().toLower()); @@ -68,9 +83,9 @@ OziMap::OziMap(const QString &fileName, QObject *parent) _name = Util::file2name(fileName); _map.size = gmi.size(); _map.path = gmi.image(); - _transform = gmi.transform(); - _projection = Projection(GCS::WGS84()); - _hasProj = false; + _calibrationPoints = gmi.calibrationPoints(); + _projection = proj; + computeTransform(); } } else if (type == MAP) { QByteArray ba(_tar->file(cf)); @@ -119,9 +134,9 @@ OziMap::OziMap(const QString &fileName, QObject *parent) _name = Util::file2name(fileName); _map.size = gmi.size(); _map.path = gmi.image(); - _transform = gmi.transform(); - _projection = Projection(GCS::WGS84()); - _hasProj = false; + _calibrationPoints = gmi.calibrationPoints(); + _projection = proj; + computeTransform(); } } else { _errorString = "Unknown file type"; @@ -141,9 +156,9 @@ OziMap::OziMap(const QString &fileName, QObject *parent) _valid = true; } -OziMap::OziMap(const QString &dirName, Tar &tar, QObject *parent) - : Map(dirName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0), - _hasProj(true), _valid(false) +OziMap::OziMap(const QString &dirName, Tar &tar, const Projection &proj, + QObject *parent) : Map(dirName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), + _mapRatio(1.0), _valid(false) { CalibrationType type; QString cf(calibrationFile(tar.files(), dirName, type)); @@ -172,18 +187,20 @@ OziMap::OziMap(const QString &dirName, Tar &tar, QObject *parent) _name = Util::file2name(cf); _map.size = gmi.size(); - _transform = gmi.transform(); - _projection = Projection(GCS::WGS84()); - _hasProj = false; + _calibrationPoints = gmi.calibrationPoints(); + _projection = proj; + computeTransform(); } else { _errorString = "No calibration file found"; return; } - QFileInfo fi(cf); - QDir dir(dirName); - _tar = new Tar(dir.absoluteFilePath(fi.completeBaseName() + ".tar")); - + QString tf(tarFile(dirName)); + if (tf.isNull()) { + _errorString = "No map tar file found"; + return; + } + _tar = new Tar(tf); if (!_tar->open()) { _errorString = _tar->fileName() + ": error reading tar file"; return; @@ -288,8 +305,10 @@ void OziMap::load(const Projection &in, const Projection &out, Q_UNUSED(out); _mapRatio = hidpi ? deviceRatio : 1.0; - if (!_hasProj) + if (!_calibrationPoints.isEmpty()) { _projection = in; + computeTransform(); + } if (_tar) { Q_ASSERT(!_tar->isOpen()); @@ -473,18 +492,28 @@ void OziMap::rescale(int zoom) _scale = _ozf->scale(zoom); } -Map *OziMap::createTAR(const QString &path, bool *isDir) +void OziMap::computeTransform() +{ + QList rp; + + for (int i = 0; i < _calibrationPoints.size(); i++) + rp.append(_calibrationPoints.at(i).rp(_projection)); + + _transform = Transform(rp); +} + +Map *OziMap::createTAR(const QString &path, const Projection &proj, bool *isDir) { if (isDir) *isDir = false; - return new OziMap(path); + return new OziMap(path, proj); } -Map *OziMap::createMAP(const QString &path, bool *isDir) +Map *OziMap::createMAP(const QString &path, const Projection &proj, bool *isDir) { if (isDir) *isDir = false; - return new OziMap(path); + return new OziMap(path, proj); } diff --git a/src/map/ozimap.h b/src/map/ozimap.h index 770fddd3..aeb9b3b0 100644 --- a/src/map/ozimap.h +++ b/src/map/ozimap.h @@ -3,6 +3,7 @@ #include "transform.h" #include "projection.h" +#include "calibrationpoint.h" #include "map.h" class Tar; @@ -14,8 +15,10 @@ class OziMap : public Map Q_OBJECT public: - OziMap(const QString &fileName, QObject *parent = 0); - OziMap(const QString &dirName, Tar &tar, QObject *parent = 0); + OziMap(const QString &fileName, const Projection &proj, + QObject *parent = 0); + OziMap(const QString &dirName, Tar &tar, const Projection &proj, + QObject *parent = 0); ~OziMap(); QString name() const {return _name;} @@ -47,8 +50,10 @@ public: QPointF pp2xy(const PointD &p) const {return _transform.proj2img(p) / _mapRatio;} - static Map *createTAR(const QString &path, bool *isDir); - static Map *createMAP(const QString &path, bool *isDir); + static Map *createTAR(const QString &path, const Projection &proj, + bool *isDir); + static Map *createMAP(const QString &path, const Projection &proj, + bool *isDir); private: enum CalibrationType { @@ -70,6 +75,7 @@ private: void drawImage(QPainter *painter, const QRectF &rect, Flags flags) const; void rescale(int zoom); + void computeTransform(); static QString calibrationFile(const QStringList &files, const QString path, CalibrationType &type); @@ -84,7 +90,7 @@ private: int _zoom; QPointF _scale; qreal _mapRatio; - bool _hasProj; + QList _calibrationPoints; bool _valid; QString _errorString; diff --git a/src/map/qctmap.cpp b/src/map/qctmap.cpp index be195cf8..e424c2d4 100644 --- a/src/map/qctmap.cpp +++ b/src/map/qctmap.cpp @@ -491,8 +491,10 @@ void QCTMap::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map *QCTMap::create(const QString &path, bool *isDir) +Map *QCTMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/qctmap.h b/src/map/qctmap.h index f2e1b498..a0acb3e0 100644 --- a/src/map/qctmap.h +++ b/src/map/qctmap.h @@ -28,7 +28,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: bool readName(QDataStream &stream); diff --git a/src/map/rmap.cpp b/src/map/rmap.cpp index 69bd2be8..2cf4767f 100644 --- a/src/map/rmap.cpp +++ b/src/map/rmap.cpp @@ -460,8 +460,10 @@ void RMap::draw(QPainter *painter, const QRectF &rect, Flags flags) } } -Map *RMap::create(const QString &path, bool *isDir) +Map *RMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/rmap.h b/src/map/rmap.h index fe02ac15..a036e478 100644 --- a/src/map/rmap.h +++ b/src/map/rmap.h @@ -34,7 +34,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: struct Header { diff --git a/src/map/sqlitemap.cpp b/src/map/sqlitemap.cpp index 6f7f4878..60e160b3 100644 --- a/src/map/sqlitemap.cpp +++ b/src/map/sqlitemap.cpp @@ -256,8 +256,10 @@ Coordinates SqliteMap::xy2ll(const QPointF &p) return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio); } -Map *SqliteMap::create(const QString &path, bool *isDir) +Map *SqliteMap::create(const QString &path, const Projection &proj, bool *isDir) { + Q_UNUSED(proj); + if (isDir) *isDir = false; diff --git a/src/map/sqlitemap.h b/src/map/sqlitemap.h index 67328fbe..3a42515b 100644 --- a/src/map/sqlitemap.h +++ b/src/map/sqlitemap.h @@ -11,7 +11,7 @@ public: SqliteMap(const QString &fileName, QObject *parent = 0); QRectF bounds(); - RectC llBounds(const Projection &) {return _bounds;} + RectC llBounds() {return _bounds;} qreal resolution(const QRectF &rect); int zoom() const {return _zoom;} @@ -32,7 +32,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: int limitZoom(int zoom) const; diff --git a/src/map/worldfilemap.cpp b/src/map/worldfilemap.cpp index e5dcd572..d1c6dbdf 100644 --- a/src/map/worldfilemap.cpp +++ b/src/map/worldfilemap.cpp @@ -9,8 +9,9 @@ #include "worldfilemap.h" -WorldFileMap::WorldFileMap(const QString &fileName, QObject *parent) - : Map(fileName, parent), _img(0), _mapRatio(1.0), _hasPRJ(false), _valid(false) +WorldFileMap::WorldFileMap(const QString &fileName, const Projection &proj, + QObject *parent) : Map(fileName, parent), _img(0), _mapRatio(1.0), + _hasPRJ(false), _valid(false) { QFileInfo fi(fileName); QDir dir(fi.absoluteDir()); @@ -37,7 +38,8 @@ WorldFileMap::WorldFileMap(const QString &fileName, QObject *parent) _errorString = prjFile + ": " + prj.errorString(); return; } - } + } else + _projection = proj; // Find the corresponding image file QList formats(QImageReader::supportedImageFormats()); @@ -81,14 +83,6 @@ Coordinates WorldFileMap::xy2ll(const QPointF &p) return _projection.xy2ll(_transform.img2proj(p * _mapRatio)); } -RectC WorldFileMap::llBounds(const Projection &proj) -{ - if (_projection.isNull()) - _projection = proj; - - return Map::llBounds(proj); -} - QRectF WorldFileMap::bounds() { return QRectF(QPointF(0, 0), _size / _mapRatio); @@ -122,10 +116,11 @@ void WorldFileMap::unload() _img = 0; } -Map *WorldFileMap::create(const QString &path, bool *isDir) +Map *WorldFileMap::create(const QString &path, const Projection &proj, + bool *isDir) { if (isDir) *isDir = false; - return new WorldFileMap(path); + return new WorldFileMap(path, proj); } diff --git a/src/map/worldfilemap.h b/src/map/worldfilemap.h index 4de84397..32f2b05a 100644 --- a/src/map/worldfilemap.h +++ b/src/map/worldfilemap.h @@ -12,10 +12,10 @@ class WorldFileMap : public Map Q_OBJECT public: - WorldFileMap(const QString &fileName, QObject *parent = 0); + WorldFileMap(const QString &fileName, const Projection &proj, + QObject *parent = 0); ~WorldFileMap(); - RectC llBounds(const Projection &proj); QRectF bounds(); QPointF ll2xy(const Coordinates &c); Coordinates xy2ll(const QPointF &p); @@ -29,7 +29,7 @@ public: bool isValid() const {return _valid;} QString errorString() const {return _errorString;} - static Map *create(const QString &path, bool *isDir); + static Map *create(const QString &path, const Projection &proj, bool *isDir); private: Projection _projection;