6 #include <QImageReader>
7 #include <QPixmapCache>
8 #include <QRegularExpression>
9 #include "common/coordinates.h"
10 #include "common/rectc.h"
20 QString
OziMap::calibrationFile(const QStringList
&files
, const QString path
,
21 CalibrationType
&type
)
23 for (int i
= 0; i
< files
.size(); i
++) {
24 QFileInfo
fi(files
.at(i
));
25 QString
suffix(fi
.suffix().toLower());
27 if (path
.endsWith(fi
.path())) {
28 if (suffix
== "map") {
31 } else if (suffix
== "gmi") {
42 OziMap::OziMap(const QString
&fileName
, QObject
*parent
)
43 : Map(fileName
, parent
), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
44 _hasProj(true), _valid(false)
46 QFileInfo
fi(fileName
);
47 QString
suffix(fi
.suffix().toLower());
49 if (suffix
== "tar") {
52 _tar
= new Tar(fileName
);
54 _errorString
= "Error reading tar file";
57 QStringList
files(_tar
->files());
58 QString
cf(calibrationFile(files
, ".", type
));
61 QByteArray
ba(_tar
->file(cf
));
65 _errorString
= gmi
.errorString();
68 _name
= Util::file2name(fileName
);
69 _map
.size
= gmi
.size();
70 _map
.path
= gmi
.image();
71 _transform
= gmi
.transform();
72 _projection
= Projection(GCS::WGS84());
75 } else if (type
== MAP
) {
76 QByteArray
ba(_tar
->file(cf
));
80 _errorString
= mf
.errorString();
84 _map
.size
= mf
.size();
85 _map
.path
= mf
.image();
86 _projection
= mf
.projection();
87 _transform
= mf
.transform();
90 _errorString
= "No calibration file found";
94 if (!setTileInfo(files
))
101 if (suffix
== "map") {
104 _errorString
= mf
.errorString();
108 _map
.size
= mf
.size();
109 _map
.path
= mf
.image();
110 _projection
= mf
.projection();
111 _transform
= mf
.transform();
113 } else if (suffix
== "gmi") {
115 if (!gmi
.isValid()) {
116 _errorString
= gmi
.errorString();
119 _name
= Util::file2name(fileName
);
120 _map
.size
= gmi
.size();
121 _map
.path
= gmi
.image();
122 _transform
= gmi
.transform();
123 _projection
= Projection(GCS::WGS84());
127 _errorString
= "Unknown file type";
131 QDir
set(fi
.absolutePath() + "/" + "set");
133 if (!setTileInfo(set
.entryList(), set
.absolutePath()))
136 if (!setImageInfo(fi
.absolutePath()))
144 OziMap::OziMap(const QString
&dirName
, Tar
&tar
, QObject
*parent
)
145 : Map(dirName
, parent
), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
146 _hasProj(true), _valid(false)
148 CalibrationType type
;
149 QString
cf(calibrationFile(tar
.files(), dirName
, type
));
152 QByteArray ba
= tar
.file(cf
);
156 _errorString
= mf
.errorString();
161 _map
.size
= mf
.size();
162 _projection
= mf
.projection();
163 _transform
= mf
.transform();
164 } else if (type
== GMI
) {
165 QByteArray ba
= tar
.file(cf
);
168 if (!gmi
.isValid()) {
169 _errorString
= gmi
.errorString();
173 _name
= Util::file2name(cf
);
174 _map
.size
= gmi
.size();
175 _transform
= gmi
.transform();
176 _projection
= Projection(GCS::WGS84());
179 _errorString
= "No calibration file found";
185 _tar
= new Tar(dir
.absoluteFilePath(fi
.completeBaseName() + ".tar"));
188 _errorString
= _tar
->fileName() + ": error reading tar file";
191 if (!setTileInfo(_tar
->files())) {
192 _errorString
= _tar
->fileName() + ": " + _errorString
;
207 bool OziMap::setImageInfo(const QString
&path
)
209 QFileInfo
ii(_map
.path
);
212 ii
.setFile(path
+ "/" + _map
.path
);
215 int last
= _map
.path
.lastIndexOf('\\');
216 if (last
>= 0 && last
< _map
.path
.length() - 1) {
217 QString
fn(_map
.path
.mid(last
+ 1, _map
.path
.length() - last
- 1));
218 ii
.setFile(path
+ "/" + fn
);
223 _map
.path
= ii
.absoluteFilePath();
225 _errorString
= QString("%1: No such image file").arg(_map
.path
);
229 if (OZF::isOZF(_map
.path
)) {
230 _ozf
= new OZF(_map
.path
);
231 if (!_ozf
|| !_ozf
->open()) {
232 _errorString
= QString("%1: Error loading OZF file").arg(_map
.path
);
235 _scale
= _ozf
->scale(_zoom
);
238 QImageReader
ir(_map
.path
);
240 _errorString
= QString("%1: Unsupported/invalid image file")
244 _map
.size
= ir
.size();
250 bool OziMap::setTileInfo(const QStringList
&tiles
, const QString
&path
)
252 if (!_map
.size
.isValid()) {
253 _errorString
= "Missing total image size (IWH)";
257 QRegularExpression
rx("_[0-9]+_[0-9]+\\.");
258 for (int i
= 0; i
< tiles
.size(); i
++) {
259 if (tiles
.at(i
).contains(rx
)) {
260 _tile
.path
= QString(tiles
.at(i
)).replace(rx
, "_%1_%2.");
263 QByteArray ba
= _tar
->file(tiles
.at(i
));
265 _tile
.size
= QImageReader(&buffer
).size();
267 _tile
.path
= path
+ "/" + _tile
.path
;
268 _tile
.size
= QImageReader(path
+ "/" + tiles
.at(i
)).size();
270 if (!_tile
.size
.isValid()) {
271 _errorString
= QString("Error retrieving tile size: "
272 "%1: Invalid image").arg(QFileInfo(tiles
.at(i
)).fileName());
276 _map
.path
= QString();
281 _errorString
= "Invalid/missing tile set";
285 void OziMap::load(const Projection
&in
, const Projection
&out
,
286 qreal deviceRatio
, bool hidpi
)
290 _mapRatio
= hidpi
? deviceRatio
: 1.0;
295 Q_ASSERT(!_tar
->isOpen());
300 Q_ASSERT(!_ozf
->isOpen());
304 if (!_tile
.isValid() && !_ozf
) {
306 _img
= new Image(_map
.path
);
308 _img
->setDevicePixelRatio(_mapRatio
);
312 void OziMap::unload()
317 if (_tar
&& _tar
->isOpen())
320 if (_ozf
&& _ozf
->isOpen())
324 void OziMap::drawTiled(QPainter
*painter
, const QRectF
&rect
) const
326 QSizeF
ts(_tile
.size
.width() / _mapRatio
, _tile
.size
.height() / _mapRatio
);
327 QPointF
tl(floor(rect
.left() / ts
.width()) * ts
.width(),
328 floor(rect
.top() / ts
.height()) * ts
.height());
330 QSizeF
s(rect
.right() - tl
.x(), rect
.bottom() - tl
.y());
331 for (int i
= 0; i
< ceil(s
.width() / ts
.width()); i
++) {
332 for (int j
= 0; j
< ceil(s
.height() / ts
.height()); j
++) {
333 int x
= round(tl
.x() * _mapRatio
+ i
* _tile
.size
.width());
334 int y
= round(tl
.y() * _mapRatio
+ j
* _tile
.size
.height());
336 QString
tileName(_tile
.path
.arg(QString::number(x
),
337 QString::number(y
)));
341 QString key
= _tar
->fileName() + "/" + tileName
;
342 if (!QPixmapCache::find(key
, &pixmap
)) {
343 QByteArray ba
= _tar
->file(tileName
);
344 pixmap
= QPixmap::fromImage(QImage::fromData(ba
));
345 if (!pixmap
.isNull())
346 QPixmapCache::insert(key
, pixmap
);
349 pixmap
= QPixmap(tileName
);
352 qWarning("%s: error loading tile image", qPrintable(
353 _tile
.path
.arg(QString::number(x
), QString::number(y
))));
355 pixmap
.setDevicePixelRatio(_mapRatio
);
356 QPointF
tp(tl
.x() + i
* ts
.width(), tl
.y() + j
* ts
.height());
357 painter
->drawPixmap(tp
, pixmap
);
363 void OziMap::drawOZF(QPainter
*painter
, const QRectF
&rect
) const
365 QSizeF
ts(_ozf
->tileSize().width() / _mapRatio
, _ozf
->tileSize().height()
367 QPointF
tl(floor(rect
.left() / ts
.width()) * ts
.width(),
368 floor(rect
.top() / ts
.height()) * ts
.height());
370 QSizeF
s(rect
.right() - tl
.x(), rect
.bottom() - tl
.y());
371 for (int i
= 0; i
< ceil(s
.width() / ts
.width()); i
++) {
372 for (int j
= 0; j
< ceil(s
.height() / ts
.height()); j
++) {
373 int x
= round(tl
.x() * _mapRatio
+ i
* _ozf
->tileSize().width());
374 int y
= round(tl
.y() * _mapRatio
+ j
* _ozf
->tileSize().height());
377 QString key
= _ozf
->fileName() + "/" + QString::number(_zoom
) + "_"
378 + QString::number(x
) + "_" + QString::number(y
);
379 if (!QPixmapCache::find(key
, &pixmap
)) {
380 pixmap
= _ozf
->tile(_zoom
, x
, y
);
381 if (!pixmap
.isNull())
382 QPixmapCache::insert(key
, pixmap
);
386 qWarning("%s: error loading tile image", qPrintable(key
));
388 pixmap
.setDevicePixelRatio(_mapRatio
);
389 QPointF
tp(tl
.x() + i
* ts
.width(), tl
.y() + j
* ts
.height());
390 painter
->drawPixmap(tp
, pixmap
);
396 void OziMap::draw(QPainter
*painter
, const QRectF
&rect
, Flags flags
)
401 drawOZF(painter
, rect
);
403 _img
->draw(painter
, rect
, flags
);
404 else if (_tile
.isValid())
405 drawTiled(painter
, rect
);
408 QPointF
OziMap::ll2xy(const Coordinates
&c
)
410 QPointF
p(_transform
.proj2img(_projection
.ll2xy(c
)));
412 ? QPointF(p
.x() * _scale
.x(), p
.y() * _scale
.y()) / _mapRatio
416 Coordinates
OziMap::xy2ll(const QPointF
&p
)
419 ? _projection
.xy2ll(_transform
.img2proj(QPointF(p
.x() / _scale
.x(),
420 p
.y() / _scale
.y()) * _mapRatio
))
421 : _projection
.xy2ll(_transform
.img2proj(p
* _mapRatio
));
424 QRectF
OziMap::bounds()
427 ? QRectF(QPointF(0, 0), _ozf
->size(_zoom
) / _mapRatio
)
428 : QRectF(QPointF(0, 0), _map
.size
/ _mapRatio
);
431 int OziMap::zoomFit(const QSize
&size
, const RectC
&rect
)
439 RectD
prect(rect
, _projection
);
440 QRectF
sbr(_transform
.proj2img(prect
.topLeft()),
441 _transform
.proj2img(prect
.bottomRight()));
443 for (int i
= 0; i
< _ozf
->zooms(); i
++) {
445 if (sbr
.size().width() * _scale
.x() <= size
.width()
446 && sbr
.size().height() * _scale
.y() <= size
.height())
457 rescale(qMax(_zoom
- 1, 0));
462 int OziMap::zoomOut()
465 rescale(qMin(_zoom
+ 1, _ozf
->zooms() - 1));
470 void OziMap::rescale(int zoom
)
473 _scale
= _ozf
->scale(zoom
);
476 Map
*OziMap::createTAR(const QString
&path
, bool *isDir
)
481 return new OziMap(path
);
484 Map
*OziMap::createMAP(const QString
&path
, bool *isDir
)
489 return new OziMap(path
);