2017-03-18 01:30:31 +01:00
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QMap>
|
|
|
|
#include <QDir>
|
2017-03-21 01:15:29 +01:00
|
|
|
#include <QBuffer>
|
2017-03-21 19:02:29 +01:00
|
|
|
#include <QImage>
|
2017-03-21 20:51:23 +01:00
|
|
|
#include <QImageReader>
|
2017-03-21 09:01:30 +01:00
|
|
|
#include <QPixmapCache>
|
2017-03-18 01:30:31 +01:00
|
|
|
#include "misc.h"
|
|
|
|
#include "rd.h"
|
|
|
|
#include "wgs84.h"
|
|
|
|
#include "coordinates.h"
|
|
|
|
#include "matrix.h"
|
2017-03-21 09:27:44 +01:00
|
|
|
#include "offlinemap.h"
|
2017-03-18 01:30:31 +01:00
|
|
|
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
int OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
bool res;
|
|
|
|
int ln = 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (!device.open(QIODevice::ReadOnly))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
while (!device.atEnd()) {
|
|
|
|
QByteArray line = device.readLine();
|
|
|
|
|
|
|
|
if (ln == 1) {
|
|
|
|
if (line.trimmed() != "OziExplorer Map Data File Version 2.2")
|
|
|
|
return ln;
|
2017-03-20 10:05:07 +01:00
|
|
|
} else if (ln == 3)
|
2017-03-18 01:30:31 +01:00
|
|
|
_imgPath = line.trimmed();
|
2017-03-20 22:52:39 +01:00
|
|
|
else {
|
2017-03-18 01:30:31 +01:00
|
|
|
QList<QByteArray> list = line.split(',');
|
2017-03-20 22:52:39 +01:00
|
|
|
QString key(list.at(0).trimmed());
|
|
|
|
|
|
|
|
if (key.startsWith("Point") && list.count() == 17
|
|
|
|
&& !list.at(2).trimmed().isEmpty()) {
|
2017-03-18 01:30:31 +01:00
|
|
|
int x = list.at(2).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
int y = list.at(3).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
int latd = list.at(6).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
qreal latm = list.at(7).trimmed().toFloat(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
int lond = list.at(9).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
qreal lonm = list.at(10).trimmed().toFloat(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
|
|
|
|
if (list.at(8).trimmed() == "S")
|
|
|
|
latd = -latd;
|
|
|
|
if (list.at(11).trimmed() == "W")
|
|
|
|
lond = -lond;
|
|
|
|
points.append(QPair<QPoint, Coordinates>(QPoint(x, y),
|
|
|
|
Coordinates(lond + lonm/60.0, latd + latm/60.0)));
|
2017-03-20 22:52:39 +01:00
|
|
|
} else if (key == "IWH") {
|
2017-03-18 01:30:31 +01:00
|
|
|
int w = list.at(2).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
int h = list.at(3).trimmed().toInt(&res);
|
|
|
|
if (!res)
|
|
|
|
return ln;
|
|
|
|
_size = QSize(w, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ln++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-27 02:41:30 +02:00
|
|
|
if (points.count() < 2) {
|
|
|
|
qWarning("%s: insufficient number of reference points",
|
|
|
|
qPrintable(_name));
|
2017-03-18 01:30:31 +01:00
|
|
|
return false;
|
2017-03-27 02:41:30 +02:00
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
|
|
|
|
Matrix c(3, 2);
|
|
|
|
c.zeroize();
|
|
|
|
for (size_t j = 0; j < c.w(); j++) {
|
|
|
|
for (size_t k = 0; k < c.h(); k++) {
|
|
|
|
for (int i = 0; i < points.size(); i++) {
|
|
|
|
double f[3], t[2];
|
2017-03-20 22:52:39 +01:00
|
|
|
QPointF p = points.at(i).second.toMercator();
|
2017-03-18 01:30:31 +01:00
|
|
|
|
2017-03-20 22:52:39 +01:00
|
|
|
f[0] = p.x();
|
|
|
|
f[1] = p.y();
|
2017-03-18 01:30:31 +01:00
|
|
|
f[2] = 1.0;
|
|
|
|
t[0] = points.at(i).first.x();
|
|
|
|
t[1] = points.at(i).first.y();
|
|
|
|
c.m(k,j) += f[k] * t[j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix Q(3, 3);
|
|
|
|
Q.zeroize();
|
|
|
|
for (int qi = 0; qi < points.size(); qi++) {
|
|
|
|
double v[3];
|
2017-03-20 22:52:39 +01:00
|
|
|
QPointF p = points.at(qi).second.toMercator();
|
2017-03-18 01:30:31 +01:00
|
|
|
|
2017-03-20 22:52:39 +01:00
|
|
|
v[0] = p.x();
|
|
|
|
v[1] = p.y();
|
2017-03-18 01:30:31 +01:00
|
|
|
v[2] = 1.0;
|
|
|
|
for (size_t i = 0; i < Q.h(); i++)
|
|
|
|
for (size_t j = 0; j < Q.w(); j++)
|
|
|
|
Q.m(i,j) += v[i] * v[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix M = Q.augemented(c);
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!M.eliminate()) {
|
|
|
|
qWarning("%s: singular transformation matrix", qPrintable(_name));
|
2017-03-18 01:30:31 +01:00
|
|
|
return false;
|
2017-03-27 02:41:30 +02:00
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
|
|
|
|
_transform = QTransform(M.m(0,3), M.m(1,3), M.m(0,4), M.m(1,4),
|
|
|
|
M.m(2,3), M.m(2,4));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
bool OfflineMap::computeResolution(QList<ReferencePoint> &points)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-27 02:41:30 +02:00
|
|
|
Q_ASSERT(points.count() >= 2);
|
2017-03-18 01:30:31 +01:00
|
|
|
|
|
|
|
int maxLon = 0, minLon = 0, maxLat = 0, minLat = 0;
|
|
|
|
qreal dLon, pLon, dLat, pLat;
|
|
|
|
|
|
|
|
for (int i = 1; i < points.size(); i++) {
|
|
|
|
if (points.at(i).second.lon() < points.at(minLon).second.lon())
|
|
|
|
minLon = i;
|
|
|
|
if (points.at(i).second.lon() > points.at(maxLon).second.lon())
|
|
|
|
maxLon = i;
|
|
|
|
if (points.at(i).second.lat() < points.at(minLat).second.lon())
|
|
|
|
minLat = i;
|
|
|
|
if (points.at(i).second.lat() > points.at(maxLat).second.lon())
|
|
|
|
maxLat = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
dLon = points.at(minLon).second.distanceTo(points.at(maxLon).second);
|
|
|
|
pLon = QLineF(points.at(minLon).first, points.at(maxLon).first).length();
|
|
|
|
dLat = points.at(minLat).second.distanceTo(points.at(maxLat).second);
|
|
|
|
pLat = QLineF(points.at(minLat).first, points.at(maxLat).first).length();
|
|
|
|
|
|
|
|
_resolution = (dLon/pLon + dLat/pLat) / 2.0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-21 19:02:29 +01:00
|
|
|
bool OfflineMap::getImageInfo(const QString &path)
|
2017-03-20 10:05:07 +01:00
|
|
|
{
|
2017-03-21 19:02:29 +01:00
|
|
|
QFileInfo ii(_imgPath);
|
|
|
|
if (ii.isRelative())
|
|
|
|
_imgPath = path + "/" + _imgPath;
|
|
|
|
|
2017-03-21 20:51:23 +01:00
|
|
|
QImageReader img(_imgPath);
|
|
|
|
_size = img.size();
|
|
|
|
if (!_size.isValid()) {
|
|
|
|
qWarning("%s: %s: error reading map image", qPrintable(_name),
|
2017-03-21 19:02:29 +01:00
|
|
|
qPrintable(ii.absoluteFilePath()));
|
2017-03-20 10:05:07 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-21 01:15:29 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-27 10:31:41 +02:00
|
|
|
bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
|
2017-03-21 01:15:29 +01:00
|
|
|
{
|
2017-03-21 19:02:29 +01:00
|
|
|
if (tiles.isEmpty()) {
|
|
|
|
qWarning("%s: empty tile set", qPrintable(_name));
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-21 01:15:29 +01:00
|
|
|
|
2017-03-21 19:02:29 +01:00
|
|
|
QRegExp rx("_[0-9]+_[0-9]+\\.");
|
|
|
|
for (int i = 0; i < tiles.size(); i++) {
|
|
|
|
if (tiles.at(i).contains(rx)) {
|
|
|
|
_tileName = QString(tiles.at(i)).replace(rx, "_%1_%2.");
|
|
|
|
|
2017-03-27 02:41:30 +02:00
|
|
|
if (path.isNull()) {
|
2017-03-21 19:02:29 +01:00
|
|
|
QByteArray ba = _tar.file(tiles.at(i));
|
2017-03-21 20:51:23 +01:00
|
|
|
QBuffer buffer(&ba);
|
|
|
|
_tileSize = QImageReader(&buffer).size();
|
2017-03-21 19:02:29 +01:00
|
|
|
} else {
|
|
|
|
_tileName = path + "/" + _tileName;
|
2017-03-21 20:51:23 +01:00
|
|
|
_tileSize = QImageReader(path + "/" + tiles.at(i)).size();
|
2017-03-21 19:02:29 +01:00
|
|
|
}
|
2017-03-21 20:51:23 +01:00
|
|
|
if (!_tileSize.isValid()) {
|
2017-03-21 19:02:29 +01:00
|
|
|
qWarning("%s: error retrieving tile size: %s: invalid image",
|
|
|
|
qPrintable(_name), qPrintable(QFileInfo(tiles.at(i))
|
|
|
|
.fileName()));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-20 10:05:07 +01:00
|
|
|
}
|
2017-03-21 01:15:29 +01:00
|
|
|
|
2017-03-21 19:02:29 +01:00
|
|
|
qWarning("%s: invalid tile names", qPrintable(_name));
|
2017-03-20 10:05:07 +01:00
|
|
|
|
2017-03-21 19:02:29 +01:00
|
|
|
return false;
|
2017-03-20 10:05:07 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 02:41:30 +02:00
|
|
|
bool OfflineMap::mapLoaded(int res)
|
|
|
|
{
|
|
|
|
if (res) {
|
|
|
|
if (res == -2)
|
|
|
|
qWarning("%s: no map file found", qPrintable(_name));
|
|
|
|
else if (res == -1)
|
|
|
|
qWarning("%s: error opening map file", qPrintable(_name));
|
|
|
|
else
|
|
|
|
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
|
|
|
|
res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-27 10:31:41 +02:00
|
|
|
bool OfflineMap::totalSizeSet()
|
|
|
|
{
|
|
|
|
if (!_size.isValid()) {
|
|
|
|
qWarning("%s: missing total image size (IWH)", qPrintable(_name));
|
|
|
|
return false;
|
|
|
|
} else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-21 01:15:29 +01:00
|
|
|
int errorLine = -2;
|
2017-03-18 01:30:31 +01:00
|
|
|
QList<ReferencePoint> points;
|
|
|
|
|
|
|
|
_valid = false;
|
|
|
|
|
|
|
|
QFileInfo fi(path);
|
2017-03-21 01:15:29 +01:00
|
|
|
_name = fi.fileName();
|
2017-03-18 01:30:31 +01:00
|
|
|
|
|
|
|
QDir dir(path);
|
2017-03-21 01:15:29 +01:00
|
|
|
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
|
|
|
|
for (int i = 0; i < mapFiles.count(); i++) {
|
|
|
|
const QString &fileName = mapFiles.at(i).fileName();
|
|
|
|
if (fileName.endsWith(".tar")) {
|
2017-03-21 19:02:29 +01:00
|
|
|
if (!_tar.load(mapFiles.at(i).absoluteFilePath())) {
|
2017-03-21 01:15:29 +01:00
|
|
|
qWarning("%s: %s: error loading tar file", qPrintable(_name),
|
|
|
|
qPrintable(fileName));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QStringList tarFiles = _tar.files();
|
|
|
|
for (int j = 0; j < tarFiles.size(); j++) {
|
|
|
|
if (tarFiles.at(j).endsWith(".map")) {
|
|
|
|
QByteArray ba = _tar.file(tarFiles.at(j));
|
|
|
|
QBuffer buffer(&ba);
|
|
|
|
errorLine = parseMapFile(buffer, points);
|
2017-03-27 02:41:30 +02:00
|
|
|
_imgPath = QString();
|
2017-03-21 01:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else if (fileName.endsWith(".map")) {
|
|
|
|
QFile mapFile(mapFiles.at(i).absoluteFilePath());
|
|
|
|
errorLine = parseMapFile(mapFile, points);
|
|
|
|
break;
|
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!mapLoaded(errorLine))
|
2017-03-18 01:30:31 +01:00
|
|
|
return;
|
|
|
|
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!computeTransformation(points))
|
2017-03-18 01:30:31 +01:00
|
|
|
return;
|
|
|
|
computeResolution(points);
|
|
|
|
|
2017-03-21 01:15:29 +01:00
|
|
|
if (_tar.isOpen()) {
|
2017-03-27 10:31:41 +02:00
|
|
|
if (!totalSizeSet())
|
|
|
|
return;
|
2017-03-21 19:02:29 +01:00
|
|
|
if (!getTileInfo(_tar.files()))
|
2017-03-20 10:05:07 +01:00
|
|
|
return;
|
2017-03-21 01:15:29 +01:00
|
|
|
} else {
|
|
|
|
QDir set(fi.absoluteFilePath() + "/" + "set");
|
|
|
|
if (set.exists()) {
|
2017-03-27 10:31:41 +02:00
|
|
|
if (!totalSizeSet())
|
|
|
|
return;
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!getTileInfo(set.entryList(), set.canonicalPath()))
|
2017-03-21 01:15:29 +01:00
|
|
|
return;
|
2017-03-27 02:41:30 +02:00
|
|
|
_imgPath = QString();
|
2017-03-21 01:15:29 +01:00
|
|
|
} else {
|
2017-03-21 19:02:29 +01:00
|
|
|
if (!getImageInfo(fi.absoluteFilePath()))
|
2017-03-21 01:15:29 +01:00
|
|
|
return;
|
2017-03-20 10:05:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-18 01:30:31 +01:00
|
|
|
_img = 0;
|
|
|
|
_valid = true;
|
|
|
|
}
|
|
|
|
|
2017-03-27 02:41:30 +02:00
|
|
|
OfflineMap::OfflineMap(Tar &tar, const QString &path, QObject *parent)
|
|
|
|
: Map(parent)
|
|
|
|
{
|
|
|
|
int errorLine = -2;
|
|
|
|
QList<ReferencePoint> points;
|
|
|
|
|
|
|
|
_valid = false;
|
|
|
|
|
|
|
|
QFileInfo fi(path);
|
|
|
|
_name = fi.fileName();
|
|
|
|
|
|
|
|
QFileInfo li(fi.absoluteDir().dirName());
|
|
|
|
QString prefix = li.fileName() + "/" + fi.fileName() + "/";
|
|
|
|
QStringList tarFiles = tar.files();
|
|
|
|
for (int j = 0; j < tarFiles.size(); j++) {
|
|
|
|
if (tarFiles.at(j).startsWith(prefix)) {
|
|
|
|
QByteArray ba = tar.file(tarFiles.at(j));
|
|
|
|
QBuffer buffer(&ba);
|
|
|
|
errorLine = parseMapFile(buffer, points);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!mapLoaded(errorLine))
|
|
|
|
return;
|
2017-03-27 10:31:41 +02:00
|
|
|
if (!totalSizeSet())
|
|
|
|
return;
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!computeTransformation(points))
|
|
|
|
return;
|
|
|
|
computeResolution(points);
|
|
|
|
|
|
|
|
QDir dir(path);
|
|
|
|
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
|
|
|
|
for (int i = 0; i < mapFiles.count(); i++) {
|
|
|
|
const QString &fileName = mapFiles.at(i).absoluteFilePath();
|
|
|
|
if (fileName.endsWith(".tar"))
|
|
|
|
_tarPath = fileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
_imgPath = QString();
|
|
|
|
_img = 0;
|
|
|
|
_valid = true;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
void OfflineMap::load()
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!_tarPath.isNull() && !_tileSize.isValid()) {
|
|
|
|
if (!_tar.load(_tarPath)) {
|
|
|
|
qWarning("%s: %s: error loading tar file", qPrintable(_name),
|
|
|
|
qPrintable(_tarPath));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getTileInfo(_tar.files());
|
2017-03-20 10:05:07 +01:00
|
|
|
return;
|
2017-03-27 02:41:30 +02:00
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!_img && !_imgPath.isNull()) {
|
|
|
|
_img = new QImage(_imgPath);
|
|
|
|
if (_img->isNull())
|
|
|
|
qWarning("%s: error loading map image", qPrintable(_imgPath));
|
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
void OfflineMap::unload()
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-27 02:41:30 +02:00
|
|
|
if (_img) {
|
2017-03-20 10:05:07 +01:00
|
|
|
delete _img;
|
2017-03-27 02:41:30 +02:00
|
|
|
_img = 0;
|
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
QRectF OfflineMap::bounds() const
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
return QRectF(QPointF(0, 0), _size);
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
qreal OfflineMap::zoomFit(const QSize &size, const QRectF &br)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
Q_UNUSED(size);
|
|
|
|
Q_UNUSED(br);
|
|
|
|
|
|
|
|
return 1.0;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
qreal OfflineMap::resolution(const QPointF &p) const
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
Q_UNUSED(p);
|
|
|
|
|
|
|
|
return _resolution;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
qreal OfflineMap::zoomIn()
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
return 1.0;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
qreal OfflineMap::zoomOut()
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
|
|
|
return 1.0;
|
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-20 10:05:07 +01:00
|
|
|
if (_tileSize.isValid()) {
|
|
|
|
QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tileSize.width())
|
|
|
|
* _tileSize.width(), (int)floor(rect.top() / _tileSize.height())
|
|
|
|
* _tileSize.height());
|
|
|
|
|
|
|
|
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
|
|
|
|
for (int i = 0; i < ceil(s.width() / _tileSize.width()); i++) {
|
|
|
|
for (int j = 0; j < ceil(s.height() / _tileSize.height()); j++) {
|
|
|
|
int x = tl.x() + i * _tileSize.width();
|
|
|
|
int y = tl.y() + j * _tileSize.height();
|
2017-03-21 01:15:29 +01:00
|
|
|
QString tileName(_tileName.arg(QString::number(x),
|
2017-03-20 10:05:07 +01:00
|
|
|
QString::number(y)));
|
2017-03-21 01:15:29 +01:00
|
|
|
QPixmap pixmap;
|
|
|
|
|
|
|
|
if (_tar.isOpen()) {
|
2017-03-21 09:01:30 +01:00
|
|
|
QString key = _tar.fileName() + "/" + tileName;
|
|
|
|
if (!QPixmapCache::find(key, &pixmap)) {
|
|
|
|
QByteArray ba = _tar.file(tileName);
|
|
|
|
pixmap = QPixmap::fromImage(QImage::fromData(ba));
|
2017-03-26 15:32:55 +02:00
|
|
|
if (!pixmap.isNull())
|
|
|
|
QPixmapCache::insert(key, pixmap);
|
2017-03-21 09:01:30 +01:00
|
|
|
}
|
2017-03-21 01:15:29 +01:00
|
|
|
} else
|
|
|
|
pixmap = QPixmap(tileName);
|
|
|
|
|
2017-03-20 10:05:07 +01:00
|
|
|
if (pixmap.isNull()) {
|
|
|
|
qWarning("%s: error loading tile image", qPrintable(
|
|
|
|
_tileName.arg(QString::number(x), QString::number(y))));
|
|
|
|
painter->fillRect(QRectF(QPoint(x, y), _tileSize),
|
|
|
|
Qt::white);
|
|
|
|
} else
|
|
|
|
painter->drawPixmap(QPoint(x, y), pixmap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-03-27 02:41:30 +02:00
|
|
|
if (!_img || _img->isNull())
|
2017-03-20 10:05:07 +01:00
|
|
|
painter->fillRect(rect, Qt::white);
|
|
|
|
else {
|
|
|
|
QPoint p = rect.topLeft().toPoint();
|
|
|
|
QImage crop = _img->copy(QRect(p, rect.size().toSize()));
|
|
|
|
painter->drawImage(rect.topLeft(), crop);
|
|
|
|
}
|
|
|
|
}
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
QPointF OfflineMap::ll2xy(const Coordinates &c) const
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-20 22:52:39 +01:00
|
|
|
return _transform.map(c.toMercator());
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|
|
|
|
|
2017-03-21 09:27:44 +01:00
|
|
|
Coordinates OfflineMap::xy2ll(const QPointF &p) const
|
2017-03-18 01:30:31 +01:00
|
|
|
{
|
2017-03-20 22:52:39 +01:00
|
|
|
return Coordinates::fromMercator(_transform.inverted().map(p));
|
2017-03-18 01:30:31 +01:00
|
|
|
}
|