1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-04-21 20:59:11 +02:00

Compare commits

..

No commits in common. "d310399b4f8b0283fbabc4e45f8186687abb8d7b" and "00fff55cd35abb60ec72a844b252f25cc85ece3a" have entirely different histories.

51 changed files with 175 additions and 246 deletions

View File

@ -1750,7 +1750,7 @@ bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError) bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError)
{ {
TreeNode<Map*> maps(MapList::loadMaps(fileName, _mapView->inputProjection())); TreeNode<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions()); QList<QAction*> existingActions(_mapsActionGroup->actions());
return loadMapNode(maps, action, existingActions, showError); return loadMapNode(maps, action, existingActions, showError);
@ -1854,7 +1854,7 @@ void GUI::loadMapDir()
return; return;
QFileInfo fi(dir); QFileInfo fi(dir);
TreeNode<Map*> maps(MapList::loadMaps(dir, _mapView->inputProjection())); TreeNode<Map*> maps(MapList::loadMaps(dir));
QList<QAction*> existingActions(_mapsActionGroup->actions()); QList<QAction*> existingActions(_mapsActionGroup->actions());
QList<MapAction*> actions; QList<MapAction*> actions;
QMenu *menu = new QMenu(maps.name()); QMenu *menu = new QMenu(maps.name());
@ -2985,7 +2985,7 @@ void GUI::loadInitialMaps(const QString &selected)
if (mapDir.isNull()) if (mapDir.isNull())
return; return;
TreeNode<Map*> maps(MapList::loadMaps(mapDir, _mapView->inputProjection())); TreeNode<Map*> maps(MapList::loadMaps(mapDir));
createMapNodeMenu(createMapActionsNode(maps), _mapMenu, _mapsEnd); createMapNodeMenu(createMapActionsNode(maps), _mapMenu, _mapsEnd);
// Select the active map according to the user settings // Select the active map according to the user settings

View File

@ -81,15 +81,15 @@ ToolTip MapItem::info() const
return tt; return tt;
} }
MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent) MapItem::MapItem(MapAction *action, Map *map, const Projection &proj,
: PlaneItem(parent) GraphicsItem *parent) : PlaneItem(parent)
{ {
Map *src = action->data().value<Map*>(); Map *src = action->data().value<Map*>();
Q_ASSERT(map->isReady()); Q_ASSERT(map->isReady());
_name = src->name(); _name = src->name();
_fileName = src->path(); _fileName = src->path();
_bounds = src->llBounds(); _bounds = src->llBounds(proj);
connect(this, &MapItem::triggered, action, &MapAction::trigger); connect(this, &MapItem::triggered, action, &MapAction::trigger);

View File

@ -11,7 +11,8 @@ class MapItem : public QObject, public PlaneItem
Q_OBJECT Q_OBJECT
public: public:
MapItem(MapAction *action, Map *map, GraphicsItem *parent = 0); MapItem(MapAction *action, Map *map, const Projection &proj,
GraphicsItem *parent = 0);
QPainterPath shape() const {return _painterPath;} QPainterPath shape() const {return _painterPath;}
QRectF boundingRect() const {return _painterPath.boundingRect();} QRectF boundingRect() const {return _painterPath.boundingRect();}

View File

@ -250,7 +250,7 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
MapItem *MapView::addMap(MapAction *map) MapItem *MapView::addMap(MapAction *map)
{ {
MapItem *mi = new MapItem(map, _map); MapItem *mi = new MapItem(map, _map, _inputProjection);
mi->setColor(_palette.nextColor()); mi->setColor(_palette.nextColor());
mi->setWidth(_areaWidth); mi->setWidth(_areaWidth);
mi->setPenStyle(_areaStyle); mi->setPenStyle(_areaStyle);
@ -331,7 +331,7 @@ int MapView::fitMapZoom() const
RectC br = _tr | _rr | _wr | _ar; RectC br = _tr | _rr | _wr | _ar;
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN), return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
br.isNull() ? _map->llBounds() : br); br.isNull() ? _map->llBounds(_inputProjection) : br);
} }
QPointF MapView::contentCenter() const QPointF MapView::contentCenter() const

View File

@ -98,7 +98,6 @@ public:
void fitContentToSize(); void fitContentToSize();
RectC boundingRect() const; RectC boundingRect() const;
const Projection &inputProjection() const {return _inputProjection;}
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
signals: signals:

View File

@ -405,10 +405,8 @@ void AQMMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp)
painter->drawPixmap(tp, pixmap); painter->drawPixmap(tp, pixmap);
} }
Map *AQMMap::create(const QString &path, const Projection &proj, bool *isDir) Map *AQMMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -17,7 +17,7 @@ public:
QString name() const {return _name;} QString name() const {return _name;}
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
qreal resolution(const QRectF &rect); qreal resolution(const QRectF &rect);
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
@ -38,7 +38,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
struct File { struct File {

View File

@ -100,9 +100,8 @@ void Atlas::computeBounds()
QRectF(offsets.at(i), _maps.at(i)->bounds().size())); QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
} }
Atlas::Atlas(const QString &fileName, bool TAR, const Projection &proj, Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
QObject *parent) : Map(fileName, parent), _zoom(0), _mapIndex(-1), : Map(fileName, parent), _zoom(0), _mapIndex(-1), _valid(false)
_valid(false)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
QByteArray ba; QByteArray ba;
@ -143,39 +142,39 @@ Atlas::Atlas(const QString &fileName, bool TAR, const Projection &proj,
for (int i = 0; i < maps.count(); i++) { for (int i = 0; i < maps.count(); i++) {
OziMap *map; OziMap *map;
if (TAR) if (TAR)
map = new OziMap(maps.at(i).absoluteFilePath(), tar, proj, this); map = new OziMap(maps.at(i).absoluteFilePath(), tar, this);
else { else {
QString cf(calibrationFile(maps.at(i).absoluteFilePath())); QString cf(calibrationFile(maps.at(i).absoluteFilePath()));
if (cf.isNull()) { if (cf.isNull()) {
_errorString = "No calibration file found"; _errorString = "No calibration file found";
return; return;
} }
map = new OziMap(cf, proj, this); map = new OziMap(cf, this);
} }
if (map->isValid()) if (map->isValid())
_maps.append(map); _maps.append(map);
else { else {
qWarning("%s: %s", qPrintable(map->path()), _errorString = QString("%1: %2")
qPrintable(map->errorString())); .arg(map->path(), map->errorString());
delete map; return;
} }
} }
} }
if (_maps.isEmpty()) { if (_maps.isEmpty()) {
_errorString = "No usable map found in atlas"; _errorString = "No maps found in atlas";
return; return;
} }
_valid = true; _valid = true;
} }
RectC Atlas::llBounds() RectC Atlas::llBounds(const Projection &proj)
{ {
RectC bounds; RectC bounds;
for (int i = 0; i < _maps.size(); i++) for (int i = 0; i < _maps.size(); i++)
bounds |= _maps.at(i)->llBounds(); bounds |= _maps.at(i)->llBounds(proj);
return bounds; return bounds;
} }
@ -331,34 +330,18 @@ void Atlas::unload()
_bounds.clear(); _bounds.clear();
} }
Map *Atlas::createTAR(const QString &path, const Projection &proj, bool *isDir) Map *Atlas::createTAR(const QString &path, bool *isDir)
{ {
if (isDir) if (isDir)
*isDir = true; *isDir = true;
return new Atlas(path, true, proj); return new Atlas(path, true);
} }
Map *Atlas::createTBA(const QString &path, const Projection &proj, bool *isDir) Map *Atlas::createTBA(const QString &path, bool *isDir)
{ {
if (isDir) if (isDir)
*isDir = true; *isDir = true;
return new Atlas(path, false, proj); return new Atlas(path, false);
} }
#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

View File

@ -12,13 +12,12 @@ class Atlas : public Map
Q_OBJECT Q_OBJECT
public: public:
Atlas(const QString &fileName, bool TAR, const Projection &proj, Atlas(const QString &fileName, bool TAR, QObject *parent = 0);
QObject *parent = 0);
QString name() const {return _name;} QString name() const {return _name;}
QRectF bounds(); QRectF bounds();
RectC llBounds(); RectC llBounds(const Projection &proj);
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom); void setZoom(int zoom);
@ -38,10 +37,8 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *createTAR(const QString &path, const Projection &proj, static Map *createTAR(const QString &path, bool *isDir);
bool *isDir); static Map *createTBA(const QString &path, bool *isDir);
static Map *createTBA(const QString &path, const Projection &proj,
bool *isDir);
private: private:
struct Zoom { struct Zoom {
@ -64,9 +61,6 @@ private:
void computeZooms(); void computeZooms();
void computeBounds(); void computeBounds();
friend QDebug operator<<(QDebug dbg, const Bounds &bounds);
friend QDebug operator<<(QDebug dbg, const Zoom &zoom);
QString _name; QString _name;
QList<OziMap*> _maps; QList<OziMap*> _maps;
@ -79,9 +73,4 @@ private:
QString _errorString; 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 #endif // ATLAS_H

View File

@ -462,10 +462,8 @@ void BSBMap::unload()
_img = 0; _img = 0;
} }
Map *BSBMap::create(const QString &path, const Projection &proj, bool *isMap) Map *BSBMap::create(const QString &path, bool *isMap)
{ {
Q_UNUSED(proj);
if (isMap) if (isMap)
*isMap = false; *isMap = false;

View File

@ -32,7 +32,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isMap); static Map *create(const QString &path, bool *isMap);
private: private:
bool parseBSB(const QByteArray &line); bool parseBSB(const QByteArray &line);

View File

@ -378,10 +378,8 @@ void ENCAtlas::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map *ENCAtlas::create(const QString &path, const Projection &proj, bool *isDir) Map *ENCAtlas::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = true; *isDir = true;

View File

@ -22,7 +22,7 @@ public:
QString name() const {return _name;} QString name() const {return _name;}
QRectF bounds() {return _bounds;} QRectF bounds() {return _bounds;}
RectC llBounds() {return _llBounds;} RectC llBounds(const Projection &) {return _llBounds;}
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom); void setZoom(int zoom);
@ -44,7 +44,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private slots: private slots:
void jobFinished(ENCJob *job); void jobFinished(ENCJob *job);

View File

@ -345,10 +345,8 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map *ENCMap::create(const QString &path, const Projection &proj, bool *isMap) Map *ENCMap::create(const QString &path, bool *isMap)
{ {
Q_UNUSED(proj);
if (isMap) if (isMap)
*isMap = false; *isMap = false;

View File

@ -23,7 +23,7 @@ public:
QString name() const {return _name;} QString name() const {return _name;}
QRectF bounds() {return _bounds;} QRectF bounds() {return _bounds;}
RectC llBounds() {return _llBounds;} RectC llBounds(const Projection &) {return _llBounds;}
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom); void setZoom(int zoom);
@ -45,7 +45,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isMap); static Map *create(const QString &path, bool *isMap);
private slots: private slots:
void jobFinished(ENCJob *job); void jobFinished(ENCJob *job);

View File

@ -301,10 +301,8 @@ void GEMFMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp)
painter->drawPixmap(tp, pixmap); painter->drawPixmap(tp, pixmap);
} }
Map *GEMFMap::create(const QString &path, const Projection &proj, bool *isDir) Map *GEMFMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -14,7 +14,7 @@ public:
GEMFMap(const QString &fileName, QObject *parent = 0); GEMFMap(const QString &fileName, QObject *parent = 0);
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
int zoom() const {return _zi;} int zoom() const {return _zi;}
void setZoom(int zoom) {_zi = zoom;} void setZoom(int zoom) {_zi = zoom;}
@ -35,7 +35,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
struct Region { struct Region {

View File

@ -73,10 +73,8 @@ void GeoTIFFMap::unload()
_img = 0; _img = 0;
} }
Map *GeoTIFFMap::create(const QString &path, const Projection &proj, bool *isDir) Map *GeoTIFFMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -29,7 +29,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
Projection _projection; Projection _projection;

View File

@ -1,4 +1,5 @@
#include <QIODevice> #include "common/csv.h"
#include "pcs.h"
#include "gmifile.h" #include "gmifile.h"
static CalibrationPoint calibrationPoint(const QByteArray line) static CalibrationPoint calibrationPoint(const QByteArray line)
@ -18,7 +19,7 @@ static CalibrationPoint calibrationPoint(const QByteArray line)
: CalibrationPoint(); : CalibrationPoint();
} }
bool GmiFile::parse(QIODevice &device) bool GmiFile::parse(QIODevice &device, QList<CalibrationPoint> &points)
{ {
int ln = 1; int ln = 1;
int width, height; int width, height;
@ -55,7 +56,7 @@ bool GmiFile::parse(QIODevice &device)
} else { } else {
CalibrationPoint cp(calibrationPoint(line)); CalibrationPoint cp(calibrationPoint(line));
if (cp.isValid()) if (cp.isValid())
_points.append(cp); points.append(cp);
else else
break; break;
} }
@ -65,10 +66,32 @@ bool GmiFile::parse(QIODevice &device)
device.close(); device.close();
return (_points.size() >= 2); return (points.size() >= 2);
}
bool GmiFile::computeTransformation(const QList<CalibrationPoint> &points)
{
QList<ReferencePoint> 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;
} }
GmiFile::GmiFile(QIODevice &file) GmiFile::GmiFile(QIODevice &file)
{ {
_valid = parse(file); QList<CalibrationPoint> points;
if (!parse(file, points))
return;
if (!computeTransformation(points))
return;
} }

View File

@ -1,30 +1,32 @@
#ifndef GMIFILE_H #ifndef GMIFILE_H
#define GMIFILE_H #define GMIFILE_H
#include "transform.h"
#include "calibrationpoint.h" #include "calibrationpoint.h"
class QIODevice; class QIODevice;
class GCS;
class GmiFile class GmiFile
{ {
public: public:
GmiFile(QIODevice &file); GmiFile(QIODevice &file);
bool isValid() const {return _valid;} bool isValid() const {return !_image.isNull() && _transform.isValid();}
const QString &errorString() const {return _errorString;} const QString &errorString() const {return _errorString;}
const Transform &transform() const {return _transform;}
const QString &image() const {return _image;} const QString &image() const {return _image;}
const QSize &size() const {return _size;} const QSize &size() const {return _size;}
const QList<CalibrationPoint> &calibrationPoints() const {return _points;}
private: private:
bool parse(QIODevice &device); bool parse(QIODevice &device, QList<CalibrationPoint> &points);
bool computeTransformation(const QList<CalibrationPoint> &points);
QString _image; QString _image;
QSize _size; QSize _size;
QList<CalibrationPoint> _points; Transform _transform;
bool _valid;
QString _errorString; QString _errorString;
}; };

View File

@ -264,20 +264,16 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map* IMGMap::createIMG(const QString &path, const Projection &proj, bool *isDir) Map* IMGMap::createIMG(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;
return new IMGMap(path, false); return new IMGMap(path, false);
} }
Map* IMGMap::createGMAP(const QString &path, const Projection &proj, bool *isDir) Map* IMGMap::createGMAP(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = true; *isDir = true;

View File

@ -55,7 +55,7 @@ public:
QString name() const {return _data.first()->name();} QString name() const {return _data.first()->name();}
QRectF bounds() {return _bounds;} QRectF bounds() {return _bounds;}
RectC llBounds() {return _data.first()->bounds();} RectC llBounds(const Projection &) {return _data.first()->bounds();}
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom); void setZoom(int zoom);
@ -77,10 +77,8 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map* createIMG(const QString &path, const Projection &proj, static Map* createIMG(const QString &path, bool *isDir);
bool *isDir); static Map* createGMAP(const QString &path, bool *isDir);
static Map* createGMAP(const QString &path, const Projection &proj,
bool *isDir);
private slots: private slots:
void jobFinished(IMGMapJob *job); void jobFinished(IMGMapJob *job);

View File

@ -274,10 +274,8 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
tree.Search(min, max, cb, &ctx); tree.Search(min, max, cb, &ctx);
} }
Map *JNXMap::create(const QString &path, const Projection &proj, bool *isDir) Map *JNXMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -19,7 +19,7 @@ public:
~JNXMap(); ~JNXMap();
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom) {_zoom = zoom;} void setZoom(int zoom) {_zoom = zoom;}
@ -39,7 +39,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
struct Tile { struct Tile {

View File

@ -484,10 +484,8 @@ void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex)
painter->restore(); painter->restore();
} }
Map *KMZMap::create(const QString &path, const Projection &proj, bool *isDir) Map *KMZMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -18,7 +18,7 @@ public:
KMZMap(const QString &fileName, QObject *parent = 0); KMZMap(const QString &fileName, QObject *parent = 0);
~KMZMap(); ~KMZMap();
RectC llBounds() {return _llbounds;} RectC llBounds(const Projection &) {return _llbounds;}
QRectF bounds(); QRectF bounds();
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
@ -39,7 +39,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
class Overlay { class Overlay {

View File

@ -30,8 +30,12 @@ static void growBottom(const Coordinates &c, RectC &rect)
rect.setBottom(c.lat()); rect.setBottom(c.lat());
} }
RectC Map::llBounds() RectC Map::llBounds(const Projection &proj)
{ {
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()); QRectF b(bounds());
double dx = b.width() / SAMPLES; double dx = b.width() / SAMPLES;
double dy = b.height() / SAMPLES; double dy = b.height() / SAMPLES;

View File

@ -28,19 +28,19 @@ public:
: QObject(parent), _path(path) {} : QObject(parent), _path(path) {}
virtual ~Map() {} virtual ~Map() {}
/* Functions available since map creation */
const QString &path() const {return _path;} const QString &path() const {return _path;}
virtual QString name() const {return Util::file2name(path());} virtual QString name() const {return Util::file2name(path());}
virtual RectC llBounds(const Projection &proj);
virtual bool isValid() const {return true;} virtual bool isValid() const {return true;}
virtual bool isReady() const {return true;} virtual bool isReady() const {return true;}
virtual QString errorString() const {return QString();} virtual QString errorString() const {return QString();}
/* Functions that shall be called after load() */
virtual void load(const Projection &, const Projection &, qreal, bool) {} virtual void load(const Projection &, const Projection &, qreal, bool) {}
virtual void unload() {} 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 QRectF bounds() = 0;
virtual qreal resolution(const QRectF &rect); virtual qreal resolution(const QRectF &rect);

View File

@ -65,7 +65,7 @@ MapList::ParserMap MapList::parsers()
MapList::ParserMap MapList::_parsers = parsers(); MapList::ParserMap MapList::_parsers = parsers();
Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir) Map *MapList::loadFile(const QString &path, bool *isDir)
{ {
ParserMap::iterator it; ParserMap::iterator it;
QFileInfo fi(Util::displayName(path)); QFileInfo fi(Util::displayName(path));
@ -76,7 +76,7 @@ Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir)
if ((it = _parsers.find(suffix)) != _parsers.end()) { if ((it = _parsers.find(suffix)) != _parsers.end()) {
while (it != _parsers.end() && it.key() == suffix) { while (it != _parsers.end() && it.key() == suffix) {
delete map; delete map;
map = it.value()(path, proj, isDir); map = it.value()(path, isDir);
if (map->isValid()) if (map->isValid())
return map; return map;
else else
@ -85,7 +85,7 @@ Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir)
} }
} else { } else {
for (it = _parsers.begin(); it != _parsers.end(); it++) { for (it = _parsers.begin(); it != _parsers.end(); it++) {
map = it.value()(path, proj, isDir); map = it.value()(path, isDir);
if (map->isValid()) if (map->isValid())
return map; return map;
else { else {
@ -103,8 +103,7 @@ Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir)
return map ? map : new InvalidMap(path, "Unknown file format"); return map ? map : new InvalidMap(path, "Unknown file format");
} }
TreeNode<Map*> MapList::loadDir(const QString &path, const Projection &proj, TreeNode<Map*> MapList::loadDir(const QString &path, TreeNode<Map*> *parent)
TreeNode<Map*> *parent)
{ {
QDir md(path); QDir md(path);
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
@ -121,12 +120,12 @@ TreeNode<Map*> MapList::loadDir(const QString &path, const Projection &proj,
QString suffix = fi.suffix().toLower(); QString suffix = fi.suffix().toLower();
if (fi.isDir()) { if (fi.isDir()) {
TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), proj, &tree)); TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), &tree));
if (!child.isEmpty()) if (!child.isEmpty())
tree.addChild(child); tree.addChild(child);
} else if (filter().contains("*." + suffix)) { } else if (filter().contains("*." + suffix)) {
bool isDir = false; bool isDir = false;
Map *map = loadFile(fi.absoluteFilePath(), proj, &isDir); Map *map = loadFile(fi.absoluteFilePath(), &isDir);
if (isDir) { if (isDir) {
if (parent) if (parent)
parent->addItem(map); parent->addItem(map);
@ -141,13 +140,13 @@ TreeNode<Map*> MapList::loadDir(const QString &path, const Projection &proj,
return tree; return tree;
} }
TreeNode<Map *> MapList::loadMaps(const QString &path, const Projection &proj) TreeNode<Map *> MapList::loadMaps(const QString &path)
{ {
if (QFileInfo(path).isDir()) if (QFileInfo(path).isDir())
return loadDir(path, proj); return loadDir(path);
else { else {
TreeNode<Map*> tree; TreeNode<Map*> tree;
tree.addItem(loadFile(path, proj)); tree.addItem(loadFile(path));
return tree; return tree;
} }
} }

View File

@ -10,18 +10,16 @@ class Projection;
class MapList class MapList
{ {
public: public:
static TreeNode<Map*> loadMaps(const QString &path, const Projection &proj); static TreeNode<Map*> loadMaps(const QString &path);
static QString formats(); static QString formats();
static QStringList filter(); static QStringList filter();
private: private:
typedef Map*(*ParserCb)(const QString &, const Projection &, bool *); typedef Map*(*ParserCb)(const QString &, bool *isDir);
typedef QMultiMap<QString, ParserCb> ParserMap; typedef QMultiMap<QString, ParserCb> ParserMap;
static Map *loadFile(const QString &path, const Projection &proj, static Map *loadFile(const QString &path, bool *isDir = 0);
bool *isDir = 0); static TreeNode<Map*> loadDir(const QString &path, TreeNode<Map*> *parent = 0);
static TreeNode<Map*> loadDir(const QString &path, const Projection &proj,
TreeNode<Map*> *parent = 0);
static ParserMap parsers(); static ParserMap parsers();
static ParserMap _parsers; static ParserMap _parsers;

View File

@ -209,11 +209,8 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map *MapsforgeMap::create(const QString &path, const Projection &proj, Map *MapsforgeMap::create(const QString &path, bool *isMap)
bool *isMap)
{ {
Q_UNUSED(proj);
if (isMap) if (isMap)
*isMap = false; *isMap = false;

View File

@ -52,7 +52,7 @@ public:
MapsforgeMap(const QString &fileName, QObject *parent = 0); MapsforgeMap(const QString &fileName, QObject *parent = 0);
QRectF bounds() {return _bounds;} QRectF bounds() {return _bounds;}
RectC llBounds() {return _data.bounds();} RectC llBounds(const Projection &) {return _data.bounds();}
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
void setZoom(int zoom); void setZoom(int zoom);
@ -74,7 +74,7 @@ public:
bool isValid() const {return _data.isValid();} bool isValid() const {return _data.isValid();}
QString errorString() const {return _data.errorString();} QString errorString() const {return _data.errorString();}
static Map *create(const QString &path, const Projection &proj, bool *isMap); static Map *create(const QString &path, bool *isMap);
private slots: private slots:
void jobFinished(MapsforgeMapJob *job); void jobFinished(MapsforgeMapJob *job);

View File

@ -214,9 +214,8 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
} }
} }
Map *MapSource::create(const QString &path, const Projection &proj, bool *isDir) Map *MapSource::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
Config config; Config config;
QFile file(path); QFile file(path);

View File

@ -15,7 +15,7 @@ class Projection;
class MapSource class MapSource
{ {
public: public:
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
enum Type { enum Type {

View File

@ -338,10 +338,8 @@ Coordinates MBTilesMap::xy2ll(const QPointF &p)
* coordinatesRatio()); * coordinatesRatio());
} }
Map *MBTilesMap::create(const QString &path, const Projection &proj, bool *isDir) Map *MBTilesMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -13,7 +13,7 @@ public:
QString name() const {return _name;} QString name() const {return _name;}
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
qreal resolution(const QRectF &rect); qreal resolution(const QRectF &rect);
int zoom() const {return _zi;} int zoom() const {return _zi;}
@ -34,7 +34,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
qreal tileSize() const; qreal tileSize() const;

View File

@ -590,10 +590,8 @@ Coordinates OruxMap::xy2ll(const QPointF &p)
return z.projection.xy2ll(z.transform.img2proj(p * _mapRatio)); return z.projection.xy2ll(z.transform.img2proj(p * _mapRatio));
} }
Map *OruxMap::create(const QString &path, const Projection &proj, bool *isDir) Map *OruxMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = true; *isDir = true;

View File

@ -40,7 +40,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
struct Zoom { struct Zoom {

View File

@ -309,11 +309,8 @@ Coordinates OsmdroidMap::xy2ll(const QPointF &p)
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio); return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
} }
Map *OsmdroidMap::create(const QString &path, const Projection &proj, Map *OsmdroidMap::create(const QString &path, bool *isDir)
bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -11,7 +11,7 @@ public:
OsmdroidMap(const QString &fileName, QObject *parent = 0); OsmdroidMap(const QString &fileName, QObject *parent = 0);
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
qreal resolution(const QRectF &rect); qreal resolution(const QRectF &rect);
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
@ -32,7 +32,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
int limitZoom(int zoom) const; int limitZoom(int zoom) const;

View File

@ -17,21 +17,6 @@
#include "ozimap.h" #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, QString OziMap::calibrationFile(const QStringList &files, const QString path,
CalibrationType &type) CalibrationType &type)
{ {
@ -54,9 +39,9 @@ QString OziMap::calibrationFile(const QStringList &files, const QString path,
return QString(); return QString();
} }
OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent) OziMap::OziMap(const QString &fileName, QObject *parent)
: Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0), : Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
_valid(false) _hasProj(true), _valid(false)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
QString suffix(fi.suffix().toLower()); QString suffix(fi.suffix().toLower());
@ -83,9 +68,9 @@ OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent)
_name = Util::file2name(fileName); _name = Util::file2name(fileName);
_map.size = gmi.size(); _map.size = gmi.size();
_map.path = gmi.image(); _map.path = gmi.image();
_calibrationPoints = gmi.calibrationPoints(); _transform = gmi.transform();
_projection = proj; _projection = Projection(GCS::WGS84());
computeTransform(); _hasProj = false;
} }
} else if (type == MAP) { } else if (type == MAP) {
QByteArray ba(_tar->file(cf)); QByteArray ba(_tar->file(cf));
@ -134,9 +119,9 @@ OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent)
_name = Util::file2name(fileName); _name = Util::file2name(fileName);
_map.size = gmi.size(); _map.size = gmi.size();
_map.path = gmi.image(); _map.path = gmi.image();
_calibrationPoints = gmi.calibrationPoints(); _transform = gmi.transform();
_projection = proj; _projection = Projection(GCS::WGS84());
computeTransform(); _hasProj = false;
} }
} else { } else {
_errorString = "Unknown file type"; _errorString = "Unknown file type";
@ -156,9 +141,9 @@ OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent)
_valid = true; _valid = true;
} }
OziMap::OziMap(const QString &dirName, Tar &tar, const Projection &proj, OziMap::OziMap(const QString &dirName, Tar &tar, QObject *parent)
QObject *parent) : Map(dirName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), : Map(dirName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
_mapRatio(1.0), _valid(false) _hasProj(true), _valid(false)
{ {
CalibrationType type; CalibrationType type;
QString cf(calibrationFile(tar.files(), dirName, type)); QString cf(calibrationFile(tar.files(), dirName, type));
@ -187,20 +172,18 @@ OziMap::OziMap(const QString &dirName, Tar &tar, const Projection &proj,
_name = Util::file2name(cf); _name = Util::file2name(cf);
_map.size = gmi.size(); _map.size = gmi.size();
_calibrationPoints = gmi.calibrationPoints(); _transform = gmi.transform();
_projection = proj; _projection = Projection(GCS::WGS84());
computeTransform(); _hasProj = false;
} else { } else {
_errorString = "No calibration file found"; _errorString = "No calibration file found";
return; return;
} }
QString tf(tarFile(dirName)); QFileInfo fi(cf);
if (tf.isNull()) { QDir dir(dirName);
_errorString = "No map tar file found"; _tar = new Tar(dir.absoluteFilePath(fi.completeBaseName() + ".tar"));
return;
}
_tar = new Tar(tf);
if (!_tar->open()) { if (!_tar->open()) {
_errorString = _tar->fileName() + ": error reading tar file"; _errorString = _tar->fileName() + ": error reading tar file";
return; return;
@ -305,10 +288,8 @@ void OziMap::load(const Projection &in, const Projection &out,
Q_UNUSED(out); Q_UNUSED(out);
_mapRatio = hidpi ? deviceRatio : 1.0; _mapRatio = hidpi ? deviceRatio : 1.0;
if (!_calibrationPoints.isEmpty()) { if (!_hasProj)
_projection = in; _projection = in;
computeTransform();
}
if (_tar) { if (_tar) {
Q_ASSERT(!_tar->isOpen()); Q_ASSERT(!_tar->isOpen());
@ -492,28 +473,18 @@ void OziMap::rescale(int zoom)
_scale = _ozf->scale(zoom); _scale = _ozf->scale(zoom);
} }
void OziMap::computeTransform() Map *OziMap::createTAR(const QString &path, bool *isDir)
{
QList<ReferencePoint> 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) if (isDir)
*isDir = false; *isDir = false;
return new OziMap(path, proj); return new OziMap(path);
} }
Map *OziMap::createMAP(const QString &path, const Projection &proj, bool *isDir) Map *OziMap::createMAP(const QString &path, bool *isDir)
{ {
if (isDir) if (isDir)
*isDir = false; *isDir = false;
return new OziMap(path, proj); return new OziMap(path);
} }

View File

@ -3,7 +3,6 @@
#include "transform.h" #include "transform.h"
#include "projection.h" #include "projection.h"
#include "calibrationpoint.h"
#include "map.h" #include "map.h"
class Tar; class Tar;
@ -15,10 +14,8 @@ class OziMap : public Map
Q_OBJECT Q_OBJECT
public: public:
OziMap(const QString &fileName, const Projection &proj, OziMap(const QString &fileName, QObject *parent = 0);
QObject *parent = 0); OziMap(const QString &dirName, Tar &tar, QObject *parent = 0);
OziMap(const QString &dirName, Tar &tar, const Projection &proj,
QObject *parent = 0);
~OziMap(); ~OziMap();
QString name() const {return _name;} QString name() const {return _name;}
@ -50,10 +47,8 @@ public:
QPointF pp2xy(const PointD &p) const QPointF pp2xy(const PointD &p) const
{return _transform.proj2img(p) / _mapRatio;} {return _transform.proj2img(p) / _mapRatio;}
static Map *createTAR(const QString &path, const Projection &proj, static Map *createTAR(const QString &path, bool *isDir);
bool *isDir); static Map *createMAP(const QString &path, bool *isDir);
static Map *createMAP(const QString &path, const Projection &proj,
bool *isDir);
private: private:
enum CalibrationType { enum CalibrationType {
@ -75,7 +70,6 @@ private:
void drawImage(QPainter *painter, const QRectF &rect, Flags flags) const; void drawImage(QPainter *painter, const QRectF &rect, Flags flags) const;
void rescale(int zoom); void rescale(int zoom);
void computeTransform();
static QString calibrationFile(const QStringList &files, const QString path, static QString calibrationFile(const QStringList &files, const QString path,
CalibrationType &type); CalibrationType &type);
@ -90,7 +84,7 @@ private:
int _zoom; int _zoom;
QPointF _scale; QPointF _scale;
qreal _mapRatio; qreal _mapRatio;
QList<CalibrationPoint> _calibrationPoints; bool _hasProj;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -491,10 +491,8 @@ void QCTMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map *QCTMap::create(const QString &path, const Projection &proj, bool *isDir) Map *QCTMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -28,7 +28,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
bool readName(QDataStream &stream); bool readName(QDataStream &stream);

View File

@ -460,10 +460,8 @@ void RMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
Map *RMap::create(const QString &path, const Projection &proj, bool *isDir) Map *RMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -34,7 +34,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
struct Header { struct Header {

View File

@ -256,10 +256,8 @@ Coordinates SqliteMap::xy2ll(const QPointF &p)
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio); return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
} }
Map *SqliteMap::create(const QString &path, const Projection &proj, bool *isDir) Map *SqliteMap::create(const QString &path, bool *isDir)
{ {
Q_UNUSED(proj);
if (isDir) if (isDir)
*isDir = false; *isDir = false;

View File

@ -11,7 +11,7 @@ public:
SqliteMap(const QString &fileName, QObject *parent = 0); SqliteMap(const QString &fileName, QObject *parent = 0);
QRectF bounds(); QRectF bounds();
RectC llBounds() {return _bounds;} RectC llBounds(const Projection &) {return _bounds;}
qreal resolution(const QRectF &rect); qreal resolution(const QRectF &rect);
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
@ -32,7 +32,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
int limitZoom(int zoom) const; int limitZoom(int zoom) const;

View File

@ -9,9 +9,8 @@
#include "worldfilemap.h" #include "worldfilemap.h"
WorldFileMap::WorldFileMap(const QString &fileName, const Projection &proj, WorldFileMap::WorldFileMap(const QString &fileName, QObject *parent)
QObject *parent) : Map(fileName, parent), _img(0), _mapRatio(1.0), : Map(fileName, parent), _img(0), _mapRatio(1.0), _hasPRJ(false), _valid(false)
_hasPRJ(false), _valid(false)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
QDir dir(fi.absoluteDir()); QDir dir(fi.absoluteDir());
@ -38,8 +37,7 @@ WorldFileMap::WorldFileMap(const QString &fileName, const Projection &proj,
_errorString = prjFile + ": " + prj.errorString(); _errorString = prjFile + ": " + prj.errorString();
return; return;
} }
} else }
_projection = proj;
// Find the corresponding image file // Find the corresponding image file
QList<QByteArray> formats(QImageReader::supportedImageFormats()); QList<QByteArray> formats(QImageReader::supportedImageFormats());
@ -83,6 +81,14 @@ Coordinates WorldFileMap::xy2ll(const QPointF &p)
return _projection.xy2ll(_transform.img2proj(p * _mapRatio)); 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() QRectF WorldFileMap::bounds()
{ {
return QRectF(QPointF(0, 0), _size / _mapRatio); return QRectF(QPointF(0, 0), _size / _mapRatio);
@ -116,11 +122,10 @@ void WorldFileMap::unload()
_img = 0; _img = 0;
} }
Map *WorldFileMap::create(const QString &path, const Projection &proj, Map *WorldFileMap::create(const QString &path, bool *isDir)
bool *isDir)
{ {
if (isDir) if (isDir)
*isDir = false; *isDir = false;
return new WorldFileMap(path, proj); return new WorldFileMap(path);
} }

View File

@ -12,10 +12,10 @@ class WorldFileMap : public Map
Q_OBJECT Q_OBJECT
public: public:
WorldFileMap(const QString &fileName, const Projection &proj, WorldFileMap(const QString &fileName, QObject *parent = 0);
QObject *parent = 0);
~WorldFileMap(); ~WorldFileMap();
RectC llBounds(const Projection &proj);
QRectF bounds(); QRectF bounds();
QPointF ll2xy(const Coordinates &c); QPointF ll2xy(const Coordinates &c);
Coordinates xy2ll(const QPointF &p); Coordinates xy2ll(const QPointF &p);
@ -29,7 +29,7 @@ public:
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
static Map *create(const QString &path, const Projection &proj, bool *isDir); static Map *create(const QString &path, bool *isDir);
private: private:
Projection _projection; Projection _projection;