7 #include <QImageReader>
8 #include <QPixmapCache>
9 #include "common/coordinates.h"
10 #include "common/rectc.h"
15 #include "offlinemap.h"
18 bool OfflineMap::setImageInfo(const QString
&path
)
20 QFileInfo
ii(_map
.path
);
23 ii
.setFile(path
+ "/" + _map
.path
);
26 int last
= _map
.path
.lastIndexOf('\\');
27 if (last
>= 0 && last
< _map
.path
.length() - 1) {
28 QStringRef
fn(&_map
.path
, last
+ 1, _map
.path
.length() - last
- 1);
29 ii
.setFile(path
+ "/" + fn
.toString());
34 _map
.path
= ii
.absoluteFilePath();
36 _errorString
= QString("%1: No such image file").arg(_map
.path
);
40 if (OZF::isOZF(_map
.path
)) {
41 _ozf
= new OZF(_map
.path
);
43 _errorString
= QString("%1: Error loading OZF file")
44 .arg(_ozf
->fileName());
47 _scale
= _ozf
->scale(_zoom
);
49 QImageReader
img(_map
.path
);
50 _map
.size
= img
.size();
51 if (!_map
.size
.isValid()) {
52 _errorString
= QString("%1: Error reading map image")
53 .arg(QFileInfo(_map
.path
).fileName());
61 bool OfflineMap::setTileInfo(const QStringList
&tiles
, const QString
&path
)
63 if (!_map
.size
.isValid()) {
64 _errorString
= "Missing total image size (IWH)";
68 QRegExp
rx("_[0-9]+_[0-9]+\\.");
69 for (int i
= 0; i
< tiles
.size(); i
++) {
70 if (tiles
.at(i
).contains(rx
)) {
71 _tile
.path
= QString(tiles
.at(i
)).replace(rx
, "_%1_%2.");
74 QByteArray ba
= _tar
->file(tiles
.at(i
));
76 _tile
.size
= QImageReader(&buffer
).size();
78 _tile
.path
= path
+ "/" + _tile
.path
;
79 _tile
.size
= QImageReader(path
+ "/" + tiles
.at(i
)).size();
81 if (!_tile
.size
.isValid()) {
82 _errorString
= QString("Error retrieving tile size: "
83 "%1: Invalid image").arg(QFileInfo(tiles
.at(i
)).fileName());
87 _map
.path
= QString();
92 _errorString
= "Invalid/missing tile set";
96 OfflineMap::OfflineMap(const QString
&fileName
, QObject
*parent
)
97 : Map(parent
), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
99 QFileInfo
fi(fileName
);
100 QString suffix
= fi
.suffix().toLower();
103 if (suffix
== "tar") {
104 _tar
= new Tar(fileName
);
106 _errorString
= "Error reading tar file";
110 QString mapFileName
= fi
.completeBaseName() + ".map";
111 QByteArray ba
= _tar
->file(mapFileName
);
113 _errorString
= "Map file not found";
119 _errorString
= mf
.errorString();
123 _map
.size
= mf
.size();
124 _map
.path
= mf
.image();
125 _projection
= mf
.projection();
126 _transform
= mf
.transform();
128 } else if (suffix
== "map") {
129 QFile
file(fileName
);
132 _errorString
= mf
.errorString();
136 _map
.size
= mf
.size();
137 _map
.path
= mf
.image();
138 _projection
= mf
.projection();
139 _transform
= mf
.transform();
141 } else if (suffix
== "tif" || suffix
== "tiff") {
142 GeoTIFF
gt(fileName
);
144 _errorString
= gt
.errorString();
147 _name
= fi
.fileName();
148 _map
.path
= fileName
;
149 _projection
= gt
.projection();
150 _transform
= gt
.transform();
153 _errorString
= "Not a map file";
158 if (!setTileInfo(_tar
->files()))
161 QDir
set(fi
.absolutePath() + "/" + "set");
163 if (!setTileInfo(set
.entryList(), set
.absolutePath()))
166 if (!setImageInfo(fi
.absolutePath()))
174 OfflineMap::OfflineMap(const QString
&fileName
, Tar
&tar
, QObject
*parent
)
175 : Map(parent
), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
177 QFileInfo
fi(fileName
);
178 QFileInfo
map(fi
.absolutePath());
179 QFileInfo
layer(map
.absolutePath());
180 QString mapFile
= layer
.fileName() + "/" + map
.fileName() + "/"
183 QByteArray ba
= tar
.file(mapFile
);
185 _errorString
= "Map file not found";
191 _errorString
= mf
.errorString();
196 _map
.size
= mf
.size();
197 _projection
= mf
.projection();
198 _transform
= mf
.transform();
199 _tar
= new Tar(fi
.absolutePath() + "/" + fi
.completeBaseName() + ".tar");
204 OfflineMap::~OfflineMap()
211 void OfflineMap::load()
213 if (_tar
&& !_tar
->isOpen()) {
215 qWarning("%s: error loading tar file",
216 qPrintable(_tar
->fileName()));
219 if (!setTileInfo(_tar
->files()))
220 qWarning("%s: %s", qPrintable(_tar
->fileName()),
221 qPrintable(_errorString
));
225 if (!_ozf
&& !_img
&& _map
.isValid()) {
226 _img
= new QImage(_map
.path
);
228 qWarning("%s: error loading map image", qPrintable(_map
.path
));
232 void OfflineMap::unload()
238 void OfflineMap::drawTiled(QPainter
*painter
, const QRectF
&rect
) const
240 QPoint tl
= QPoint((int)floor(rect
.left() / (qreal
)_tile
.size
.width())
241 * _tile
.size
.width(), (int)floor(rect
.top() / _tile
.size
.height())
242 * _tile
.size
.height());
244 QSizeF
s(rect
.right() - tl
.x(), rect
.bottom() - tl
.y());
245 for (int i
= 0; i
< ceil(s
.width() / _tile
.size
.width()); i
++) {
246 for (int j
= 0; j
< ceil(s
.height() / _tile
.size
.height()); j
++) {
247 int x
= tl
.x() + i
* _tile
.size
.width();
248 int y
= tl
.y() + j
* _tile
.size
.height();
250 QString
tileName(_tile
.path
.arg(QString::number(x
),
251 QString::number(y
)));
255 QString key
= _tar
->fileName() + "/" + tileName
;
256 if (!QPixmapCache::find(key
, &pixmap
)) {
257 QByteArray ba
= _tar
->file(tileName
);
258 pixmap
= QPixmap::fromImage(QImage::fromData(ba
));
259 if (!pixmap
.isNull())
260 QPixmapCache::insert(key
, pixmap
);
263 pixmap
= QPixmap(tileName
);
266 qWarning("%s: error loading tile image", qPrintable(
267 _tile
.path
.arg(QString::number(x
), QString::number(y
))));
269 painter
->drawPixmap(QPoint(x
, y
), pixmap
);
274 void OfflineMap::drawOZF(QPainter
*painter
, const QRectF
&rect
) const
276 QPoint tl
= QPoint((int)floor(rect
.left() / _ozf
->tileSize().width())
277 * _ozf
->tileSize().width(), (int)floor(rect
.top()
278 / _ozf
->tileSize().height()) * _ozf
->tileSize().height());
280 QSizeF
s(rect
.right() - tl
.x(), rect
.bottom() - tl
.y());
281 for (int i
= 0; i
< ceil(s
.width() / _ozf
->tileSize().width()); i
++) {
282 for (int j
= 0; j
< ceil(s
.height() / _ozf
->tileSize().height()); j
++) {
283 int x
= tl
.x() + i
* _ozf
->tileSize().width();
284 int y
= tl
.y() + j
* _ozf
->tileSize().height();
287 QString key
= _ozf
->fileName() + "/" + QString::number(_zoom
) + "_"
288 + QString::number(x
) + "_" + QString::number(y
);
289 if (!QPixmapCache::find(key
, &pixmap
)) {
290 pixmap
= _ozf
->tile(_zoom
, x
, y
);
291 if (!pixmap
.isNull())
292 QPixmapCache::insert(key
, pixmap
);
296 qWarning("%s: error loading tile image", qPrintable(key
));
298 painter
->drawPixmap(QPoint(x
, y
), pixmap
);
303 void OfflineMap::drawImage(QPainter
*painter
, const QRectF
&rect
) const
305 QRect
r(rect
.toRect());
306 painter
->drawImage(r
.left(), r
.top(), *_img
, r
.left(), r
.top(),
307 r
.width(), r
.height());
310 void OfflineMap::draw(QPainter
*painter
, const QRectF
&rect
, bool block
)
315 drawOZF(painter
, rect
);
316 else if (_tile
.isValid())
317 drawTiled(painter
, rect
);
318 else if (_img
&& !_img
->isNull())
319 drawImage(painter
, rect
);
322 QPointF
OfflineMap::ll2xy(const Coordinates
&c
)
324 QPointF
p(_transform
.proj2img(_projection
.ll2xy(c
)));
325 return _ozf
? QPointF(p
.x() * _scale
.x(), p
.y() * _scale
.y()) : p
;
328 Coordinates
OfflineMap::xy2ll(const QPointF
&p
)
331 ? _projection
.xy2ll(_transform
.img2proj(QPointF(p
.x() / _scale
.x(),
332 p
.y() / _scale
.y())))
333 : _projection
.xy2ll(_transform
.img2proj(p
));
336 QRectF
OfflineMap::bounds() const
339 ? QRectF(QPointF(0, 0), _ozf
->size(_zoom
))
340 : QRectF(QPointF(0, 0), _map
.size
);
343 int OfflineMap::zoomFit(const QSize
&size
, const RectC
&rect
)
351 QPointF
tl(_transform
.proj2img(_projection
.ll2xy(rect
.topLeft())));
352 QPointF
br(_transform
.proj2img(_projection
.ll2xy(rect
.bottomRight())));
353 QRect
sbr(QRectF(tl
, br
).toRect().normalized());
355 for (int i
= 0; i
< _ozf
->zooms(); i
++) {
357 if (sbr
.size().width() * _scale
.x() <= size
.width()
358 && sbr
.size().height() * _scale
.y() <= size
.height())
366 int OfflineMap::zoomIn()
369 rescale(qMax(_zoom
- 1, 0));
374 int OfflineMap::zoomOut()
377 rescale(qMin(_zoom
+ 1, _ozf
->zooms() - 1));
382 void OfflineMap::rescale(int zoom
)
385 _scale
= _ozf
->scale(zoom
);