mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-07 16:02:51 +02:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
822a0c2866 | |||
a92d6efec6 | |||
4615709b99 | |||
8a72b20af8 | |||
f86aa8c012 | |||
e351eb6370 | |||
81e967f20d | |||
dbf5828e65 | |||
cf81a90865 | |||
37d408c953 | |||
61c3ed60d7 | |||
04c203625f | |||
d0cea97c90 | |||
ddc7eb7149 | |||
bb22ad95b7 | |||
682fcc09cc | |||
60e83b24f9 | |||
c30501185c | |||
9b3c11cc68 | |||
61f77ef19e | |||
c0834491d3 | |||
e6fdd0f53d | |||
fe444e88a3 | |||
d9c0770b51 | |||
3a0e9bb733 | |||
ca6c7247c0 | |||
0b25cb9f81 | |||
b19c3a83f3 | |||
728361ad7b | |||
f5e3e5bd21 |
@ -1,4 +1,4 @@
|
|||||||
version: 13.1.{build}
|
version: 13.3.{build}
|
||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
- Release
|
- Release
|
||||||
|
@ -3,7 +3,7 @@ unix:!macx:!android {
|
|||||||
} else {
|
} else {
|
||||||
TARGET = GPXSee
|
TARGET = GPXSee
|
||||||
}
|
}
|
||||||
VERSION = 13.1
|
VERSION = 13.3
|
||||||
|
|
||||||
QT += core \
|
QT += core \
|
||||||
gui \
|
gui \
|
||||||
|
@ -866,7 +866,7 @@
|
|||||||
<location filename="../src/GUI/gui.cpp" line="907"/>
|
<location filename="../src/GUI/gui.cpp" line="907"/>
|
||||||
<location filename="../src/GUI/gui.cpp" line="925"/>
|
<location filename="../src/GUI/gui.cpp" line="925"/>
|
||||||
<source>CRS directory:</source>
|
<source>CRS directory:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Directori CRS:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/gui.cpp" line="909"/>
|
<location filename="../src/GUI/gui.cpp" line="909"/>
|
||||||
@ -1020,6 +1020,7 @@
|
|||||||
<translation>
|
<translation>
|
||||||
<numerusform>%n fitxer</numerusform>
|
<numerusform>%n fitxer</numerusform>
|
||||||
<numerusform>%n fitxers</numerusform>
|
<numerusform>%n fitxers</numerusform>
|
||||||
|
<numerusform>%n fitxers</numerusform>
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -712,7 +712,7 @@
|
|||||||
<location filename="../src/GUI/gui.cpp" line="907"/>
|
<location filename="../src/GUI/gui.cpp" line="907"/>
|
||||||
<location filename="../src/GUI/gui.cpp" line="925"/>
|
<location filename="../src/GUI/gui.cpp" line="925"/>
|
||||||
<source>CRS directory:</source>
|
<source>CRS directory:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>CRS-katalog:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/gui.cpp" line="913"/>
|
<location filename="../src/GUI/gui.cpp" line="913"/>
|
||||||
|
@ -958,7 +958,7 @@
|
|||||||
<location filename="../src/GUI/gui.cpp" line="907"/>
|
<location filename="../src/GUI/gui.cpp" line="907"/>
|
||||||
<location filename="../src/GUI/gui.cpp" line="925"/>
|
<location filename="../src/GUI/gui.cpp" line="925"/>
|
||||||
<source>CRS directory:</source>
|
<source>CRS directory:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Dossier CRS :</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/gui.cpp" line="915"/>
|
<location filename="../src/GUI/gui.cpp" line="915"/>
|
||||||
@ -1427,12 +1427,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="70"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="70"/>
|
||||||
<source>Select the proper coordinate reference system (CRS) of maps without a CRS definition (JNX, KMZ and World file maps).</source>
|
<source>Select the proper coordinate reference system (CRS) of maps without a CRS definition (JNX, KMZ and World file maps).</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Sélectionnez le système de référence de coordonnée (CRS) approprié pour les cartes sans définition de CRS (JNX, KMZ et World file maps).</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="73"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="73"/>
|
||||||
<source>Select the desired projection of vector maps (IMG, Mapsforge and ENC maps). The projection must be valid for the whole map area.</source>
|
<source>Select the desired projection of vector maps (IMG, Mapsforge and ENC maps). The projection must be valid for the whole map area.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Sélectionnez la projection désirée de la carte vectorielle (IMG, Mapsforge et carte ENC). La projection doit être valide pour la totalité de la zone de la carte.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="77"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="77"/>
|
||||||
@ -1912,7 +1912,7 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="758"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="758"/>
|
||||||
<source>DEM cache size:</source>
|
<source>DEM cache size:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Taille du cache DEM :</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="778"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="778"/>
|
||||||
|
@ -712,7 +712,7 @@
|
|||||||
<location filename="../src/GUI/gui.cpp" line="907"/>
|
<location filename="../src/GUI/gui.cpp" line="907"/>
|
||||||
<location filename="../src/GUI/gui.cpp" line="925"/>
|
<location filename="../src/GUI/gui.cpp" line="925"/>
|
||||||
<source>CRS directory:</source>
|
<source>CRS directory:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>CRS-mappe:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/gui.cpp" line="913"/>
|
<location filename="../src/GUI/gui.cpp" line="913"/>
|
||||||
@ -1718,12 +1718,12 @@
|
|||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="70"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="70"/>
|
||||||
<source>Select the proper coordinate reference system (CRS) of maps without a CRS definition (JNX, KMZ and World file maps).</source>
|
<source>Select the proper coordinate reference system (CRS) of maps without a CRS definition (JNX, KMZ and World file maps).</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Velg riktig koordinatreferansesystem (CRS) for kart uten en CRS-definisjon (JNX, KMZ og World-file kart).</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="73"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="73"/>
|
||||||
<source>Select the desired projection of vector maps (IMG, Mapsforge and ENC maps). The projection must be valid for the whole map area.</source>
|
<source>Select the desired projection of vector maps (IMG, Mapsforge and ENC maps). The projection must be valid for the whole map area.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Velg ønsket projeksjon for vektorkart (IMG, Mapsforge og ENC-kart). Projeksjonen må være gyldig for hele kartområdet.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/GUI/optionsdialog.cpp" line="104"/>
|
<location filename="../src/GUI/optionsdialog.cpp" line="104"/>
|
||||||
|
@ -37,7 +37,7 @@ Unicode true
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "13.1"
|
!define VERSION "13.3"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
#define deg2rad(d) (((d)*M_PI)/180.0)
|
#define deg2rad(d) (((d)*M_PI)/180.0)
|
||||||
#define rad2deg(d) (((d)*180.0)/M_PI)
|
#define rad2deg(d) (((d)*180.0)/M_PI)
|
||||||
@ -48,6 +49,11 @@ inline bool operator<(const Coordinates &c1, const Coordinates &c2)
|
|||||||
return (c1.lat() < c2.lat());
|
return (c1.lat() < c2.lat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline HASH_T qHash(const Coordinates &c)
|
||||||
|
{
|
||||||
|
return qHash(QPair<double, double>(c.lon(), c.lat()));
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
QDebug operator<<(QDebug dbg, const Coordinates &c);
|
QDebug operator<<(QDebug dbg, const Coordinates &c);
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -53,7 +53,7 @@ Authorization::Authorization(const QString &username, const QString &password)
|
|||||||
{
|
{
|
||||||
QString concatenated = username + ":" + password;
|
QString concatenated = username + ":" + password;
|
||||||
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
||||||
_header = "Basic " + data;
|
_header = HTTPHeader("Authorization", "Basic " + data);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkTimeout::NetworkTimeout(int timeout, QNetworkReply *reply)
|
NetworkTimeout::NetworkTimeout(int timeout, QNetworkReply *reply)
|
||||||
@ -83,9 +83,10 @@ QNetworkAccessManager *Downloader::_manager = 0;
|
|||||||
int Downloader::_timeout = 30;
|
int Downloader::_timeout = 30;
|
||||||
bool Downloader::_http2 = true;
|
bool Downloader::_http2 = true;
|
||||||
|
|
||||||
bool Downloader::doDownload(const Download &dl, const Authorization &auth)
|
bool Downloader::doDownload(const Download &dl, const QList<HTTPHeader> &headers)
|
||||||
{
|
{
|
||||||
const QUrl &url = dl.url();
|
const QUrl &url = dl.url();
|
||||||
|
bool userAgent = false;
|
||||||
|
|
||||||
if (!url.isValid() || !(url.scheme() == QLatin1String("http")
|
if (!url.isValid() || !(url.scheme() == QLatin1String("http")
|
||||||
|| url.scheme() == QLatin1String("https"))) {
|
|| url.scheme() == QLatin1String("https"))) {
|
||||||
@ -103,9 +104,15 @@ bool Downloader::doDownload(const Download &dl, const Authorization &auth)
|
|||||||
request.setAttribute(ATTR_REDIRECT_POLICY,
|
request.setAttribute(ATTR_REDIRECT_POLICY,
|
||||||
QNetworkRequest::NoLessSafeRedirectPolicy);
|
QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||||
request.setAttribute(ATTR_HTTP2_ALLOWED, QVariant(_http2));
|
request.setAttribute(ATTR_HTTP2_ALLOWED, QVariant(_http2));
|
||||||
request.setRawHeader("User-Agent", USER_AGENT);
|
|
||||||
if (!auth.isNull())
|
for (int i = 0; i < headers.size(); i++) {
|
||||||
request.setRawHeader("Authorization", auth.header());
|
const HTTPHeader &hdr = headers.at(i);
|
||||||
|
request.setRawHeader(hdr.key(), hdr.value());
|
||||||
|
if (hdr.key() == "User-Agent")
|
||||||
|
userAgent = true;
|
||||||
|
}
|
||||||
|
if (!userAgent)
|
||||||
|
request.setRawHeader("User-Agent", USER_AGENT);
|
||||||
|
|
||||||
QFile *file = new QFile(tmpName(dl.file()));
|
QFile *file = new QFile(tmpName(dl.file()));
|
||||||
if (!file->open(QIODevice::WriteOnly)) {
|
if (!file->open(QIODevice::WriteOnly)) {
|
||||||
@ -183,12 +190,12 @@ void Downloader::downloadFinished(QNetworkReply *reply)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Downloader::get(const QList<Download> &list,
|
bool Downloader::get(const QList<Download> &list,
|
||||||
const Authorization &authorization)
|
const QList<HTTPHeader> &headers)
|
||||||
{
|
{
|
||||||
bool finishEmitted = false;
|
bool finishEmitted = false;
|
||||||
|
|
||||||
for (int i = 0; i < list.count(); i++)
|
for (int i = 0; i < list.count(); i++)
|
||||||
finishEmitted |= doDownload(list.at(i), authorization);
|
finishEmitted |= doDownload(list.at(i), headers);
|
||||||
|
|
||||||
return finishEmitted;
|
return finishEmitted;
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include "common/kv.h"
|
||||||
|
|
||||||
class QFile;
|
class QFile;
|
||||||
|
|
||||||
|
typedef KV<QByteArray, QByteArray> HTTPHeader;
|
||||||
|
|
||||||
class Download
|
class Download
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -29,11 +32,11 @@ public:
|
|||||||
Authorization() {}
|
Authorization() {}
|
||||||
Authorization(const QString &username, const QString &password);
|
Authorization(const QString &username, const QString &password);
|
||||||
|
|
||||||
bool isNull() const {return _header.isNull();}
|
const HTTPHeader &header() const {return _header;}
|
||||||
const QByteArray &header() const {return _header;}
|
bool isNull() const {return _header.key().isNull();}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray _header;
|
HTTPHeader _header;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkTimeout : public QObject
|
class NetworkTimeout : public QObject
|
||||||
@ -60,8 +63,7 @@ class Downloader : public QObject
|
|||||||
public:
|
public:
|
||||||
Downloader(QObject *parent = 0) : QObject(parent) {}
|
Downloader(QObject *parent = 0) : QObject(parent) {}
|
||||||
|
|
||||||
bool get(const QList<Download> &list, const Authorization &authorization
|
bool get(const QList<Download> &list, const QList<HTTPHeader> &headers);
|
||||||
= Authorization());
|
|
||||||
void clearErrors() {_errorDownloads.clear();}
|
void clearErrors() {_errorDownloads.clear();}
|
||||||
|
|
||||||
static void setNetworkManager(QNetworkAccessManager *manager)
|
static void setNetworkManager(QNetworkAccessManager *manager)
|
||||||
@ -80,7 +82,7 @@ private:
|
|||||||
class ReplyTimeout;
|
class ReplyTimeout;
|
||||||
|
|
||||||
void insertError(const QUrl &url, QNetworkReply::NetworkError error);
|
void insertError(const QUrl &url, QNetworkReply::NetworkError error);
|
||||||
bool doDownload(const Download &dl, const Authorization &auth);
|
bool doDownload(const Download &dl, const QList<HTTPHeader> &headers);
|
||||||
void downloadFinished(QNetworkReply *reply);
|
void downloadFinished(QNetworkReply *reply);
|
||||||
void readData(QNetworkReply *reply);
|
void readData(QNetworkReply *reply);
|
||||||
|
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
#define HASH_T uint
|
#define HASH_T uint
|
||||||
|
|
||||||
|
inline uint qHash(const QPoint &p)
|
||||||
|
{
|
||||||
|
return qHash(QPair<int, int>(p.x(), p.y()));
|
||||||
|
}
|
||||||
#else // QT6
|
#else // QT6
|
||||||
#define HASH_T size_t
|
#define HASH_T size_t
|
||||||
#endif // QT6
|
#endif // QT6
|
||||||
|
|
||||||
inline HASH_T qHash(const QPoint &p)
|
|
||||||
{
|
|
||||||
return ::qHash(p.x()) ^ ::qHash(p.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HASH_H
|
#endif // HASH_H
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
template <class KEY, class VALUE>
|
template <class KEY, class VALUE>
|
||||||
class KV {
|
class KV {
|
||||||
public:
|
public:
|
||||||
|
KV() {}
|
||||||
KV(const KEY &key, const VALUE &value) : _key(key), _value(value) {}
|
KV(const KEY &key, const VALUE &value) : _key(key), _value(value) {}
|
||||||
|
|
||||||
const KEY &key() const {return _key;}
|
const KEY &key() const {return _key;}
|
||||||
|
@ -64,7 +64,7 @@ bool DEMLoader::loadTiles(const RectC &rect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _downloader->get(dl, _authorization);
|
return _downloader->get(dl, _headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DEMLoader::checkTiles(const RectC &rect) const
|
bool DEMLoader::checkTiles(const RectC &rect) const
|
||||||
@ -97,3 +97,11 @@ QString DEMLoader::tileFile(const DEM::Tile &tile) const
|
|||||||
{
|
{
|
||||||
return _dir.absoluteFilePath(tile.baseName());
|
return _dir.absoluteFilePath(tile.baseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DEMLoader::setAuthorization(const Authorization &authorization)
|
||||||
|
{
|
||||||
|
QList<HTTPHeader> headers;
|
||||||
|
if (!authorization.isNull())
|
||||||
|
headers.append(authorization.header());
|
||||||
|
_headers = headers;
|
||||||
|
}
|
||||||
|
@ -16,8 +16,7 @@ public:
|
|||||||
DEMLoader(const QString &dir, QObject *parent = 0);
|
DEMLoader(const QString &dir, QObject *parent = 0);
|
||||||
|
|
||||||
void setUrl(const QString &url) {_url = url;}
|
void setUrl(const QString &url) {_url = url;}
|
||||||
void setAuthorization(const Authorization &authorization)
|
void setAuthorization(const Authorization &authorization);
|
||||||
{_authorization = authorization;}
|
|
||||||
|
|
||||||
bool loadTiles(const RectC &rect);
|
bool loadTiles(const RectC &rect);
|
||||||
bool checkTiles(const RectC &rect) const;
|
bool checkTiles(const RectC &rect) const;
|
||||||
@ -34,7 +33,7 @@ private:
|
|||||||
Downloader *_downloader;
|
Downloader *_downloader;
|
||||||
QString _url;
|
QString _url;
|
||||||
QDir _dir;
|
QDir _dir;
|
||||||
Authorization _authorization;
|
QList<HTTPHeader> _headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEMLOADER_H
|
#endif // DEMLOADER_H
|
||||||
|
@ -33,13 +33,16 @@ Path Route::path() const
|
|||||||
Graph Route::gpsElevation() const
|
Graph Route::gpsElevation() const
|
||||||
{
|
{
|
||||||
Graph graph;
|
Graph graph;
|
||||||
graph.append(GraphSegment(QDateTime()));
|
QDateTime date;
|
||||||
GraphSegment &gs = graph.last();
|
GraphSegment gs(date);
|
||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++)
|
for (int i = 0; i < _data.size(); i++)
|
||||||
if (_data.at(i).hasElevation())
|
if (_data.at(i).hasElevation())
|
||||||
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
|
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
|
||||||
|
|
||||||
|
if (gs.size() >= 2)
|
||||||
|
graph.append(gs);
|
||||||
|
|
||||||
if (_data.style().color().isValid())
|
if (_data.style().color().isValid())
|
||||||
graph.setColor(_data.style().color());
|
graph.setColor(_data.style().color());
|
||||||
|
|
||||||
@ -49,8 +52,8 @@ Graph Route::gpsElevation() const
|
|||||||
Graph Route::demElevation() const
|
Graph Route::demElevation() const
|
||||||
{
|
{
|
||||||
Graph graph;
|
Graph graph;
|
||||||
graph.append(GraphSegment(QDateTime()));
|
QDateTime date;
|
||||||
GraphSegment &gs = graph.last();
|
GraphSegment gs(date);
|
||||||
|
|
||||||
for (int i = 0; i < _data.size(); i++) {
|
for (int i = 0; i < _data.size(); i++) {
|
||||||
qreal dem = DEM::elevation(_data.at(i).coordinates());
|
qreal dem = DEM::elevation(_data.at(i).coordinates());
|
||||||
@ -58,6 +61,9 @@ Graph Route::demElevation() const
|
|||||||
gs.append(GraphPoint(_distance.at(i), NAN, dem));
|
gs.append(GraphPoint(_distance.at(i), NAN, dem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gs.size() >= 2)
|
||||||
|
graph.append(gs);
|
||||||
|
|
||||||
if (_data.style().color().isValid())
|
if (_data.style().color().isValid())
|
||||||
graph.setColor(_data.style().color());
|
graph.setColor(_data.style().color());
|
||||||
|
|
||||||
|
@ -893,7 +893,7 @@ void MapData::clear()
|
|||||||
_points.RemoveAll();
|
_points.RemoveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::points(const RectC &rect, QList<Point*> *points)
|
void MapData::points(const RectC &rect, QList<Point*> *points) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
@ -901,7 +901,7 @@ void MapData::points(const RectC &rect, QList<Point*> *points)
|
|||||||
_points.Search(min, max, pointCb, points);
|
_points.Search(min, max, pointCb, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::lines(const RectC &rect, QList<Line*> *lines)
|
void MapData::lines(const RectC &rect, QList<Line*> *lines) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
@ -909,7 +909,7 @@ void MapData::lines(const RectC &rect, QList<Line*> *lines)
|
|||||||
_lines.Search(min, max, lineCb, lines);
|
_lines.Search(min, max, lineCb, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::polygons(const RectC &rect, QList<Poly*> *polygons)
|
void MapData::polygons(const RectC &rect, QList<Poly*> *polygons) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
|
@ -72,9 +72,9 @@ public:
|
|||||||
RectC bounds() const {return _bounds;}
|
RectC bounds() const {return _bounds;}
|
||||||
Range zooms() const;
|
Range zooms() const;
|
||||||
|
|
||||||
void polygons(const RectC &rect, QList<Poly*> *polygons);
|
void polygons(const RectC &rect, QList<Poly*> *polygons) const;
|
||||||
void lines(const RectC &rect, QList<Line*> *lines);
|
void lines(const RectC &rect, QList<Line*> *lines) const;
|
||||||
void points(const RectC &rect, QList<Point*> *points);
|
void points(const RectC &rect, QList<Point*> *points) const;
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
#include "common/linec.h"
|
#include "common/linec.h"
|
||||||
#include "map/bitmapline.h"
|
#include "map/bitmapline.h"
|
||||||
#include "map/textpathitem.h"
|
#include "map/textpathitem.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace ENC;
|
using namespace ENC;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
|
|
||||||
#define TSSLPT_SIZE 0.005 /* ll */
|
#define TSSLPT_SIZE 0.005 /* ll */
|
||||||
#define RDOCAL_SIZE 12 /* px */
|
#define RDOCAL_SIZE 12 /* px */
|
||||||
#define CURENT_SIZE 12 /* px */
|
#define CURENT_SIZE 12 /* px */
|
||||||
@ -227,10 +230,11 @@ QPolygonF RasterTile::tsslptArrow(const Coordinates &c, qreal angle) const
|
|||||||
return polygon;
|
return polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawArrows(QPainter *painter)
|
void RasterTile::drawArrows(QPainter *painter,
|
||||||
|
const QList<MapData::Poly*> &polygons)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
|
|
||||||
if (poly->type()>>16 == TSSLPT) {
|
if (poly->type()>>16 == TSSLPT) {
|
||||||
QPolygonF polygon(tsslptArrow(centroid(poly->path().first()),
|
QPolygonF polygon(tsslptArrow(centroid(poly->path().first()),
|
||||||
@ -243,13 +247,14 @@ void RasterTile::drawArrows(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPolygons(QPainter *painter)
|
void RasterTile::drawPolygons(QPainter *painter,
|
||||||
|
const QList<MapData::Poly*> &polygons)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int n = 0; n < s.drawOrder().size(); n++) {
|
for (int n = 0; n < s.drawOrder().size(); n++) {
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
if (poly->type() != s.drawOrder().at(n))
|
if (poly->type() != s.drawOrder().at(n))
|
||||||
continue;
|
continue;
|
||||||
const Style::Polygon &style = s.polygon(poly->type());
|
const Style::Polygon &style = s.polygon(poly->type());
|
||||||
@ -267,14 +272,14 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawLines(QPainter *painter)
|
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line*> &lines)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Line *line = _lines.at(i);
|
const MapData::Line *line = lines.at(i);
|
||||||
const Style::Line &style = s.line(line->type());
|
const Style::Line &style = s.line(line->type());
|
||||||
|
|
||||||
if (!style.img().isNull()) {
|
if (!style.img().isNull()) {
|
||||||
@ -293,12 +298,13 @@ void RasterTile::drawTextItems(QPainter *painter,
|
|||||||
textItems.at(i)->paint(painter);
|
textItems.at(i)->paint(painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
void RasterTile::processPolygons(const QList<MapData::Poly*> &polygons,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
uint type = poly->type()>>16;
|
uint type = poly->type()>>16;
|
||||||
|
|
||||||
if (!(type == HRBFAC || type == I_TRNBSN
|
if (!(type == HRBFAC || type == I_TRNBSN
|
||||||
@ -319,18 +325,18 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<TextItem*> &textItems,
|
void RasterTile::processPoints(QList<MapData::Point*> &points,
|
||||||
QList<TextItem*> &lights)
|
QList<TextItem*> &textItems, QList<TextItem*> &lights)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
PointMap lightsMap, signalsMap;
|
PointMap lightsMap, signalsMap;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
std::sort(_points.begin(), _points.end(), pointLess);
|
std::sort(points.begin(), points.end(), pointLess);
|
||||||
|
|
||||||
/* Lights & Signals */
|
/* Lights & Signals */
|
||||||
for (i = 0; i < _points.size(); i++) {
|
for (i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point *point = _points.at(i);
|
const MapData::Point *point = points.at(i);
|
||||||
if (point->type()>>16 == LIGHTS)
|
if (point->type()>>16 == LIGHTS)
|
||||||
lightsMap.insert(point->pos(), point);
|
lightsMap.insert(point->pos(), point);
|
||||||
else if (point->type()>>16 == FOGSIG)
|
else if (point->type()>>16 == FOGSIG)
|
||||||
@ -340,8 +346,8 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Everything else */
|
/* Everything else */
|
||||||
for ( ; i < _points.size(); i++) {
|
for ( ; i < points.size(); i++) {
|
||||||
const MapData::Point *point = _points.at(i);
|
const MapData::Point *point = points.at(i);
|
||||||
QPoint pos(ll2xy(point->pos()).toPoint());
|
QPoint pos(ll2xy(point->pos()).toPoint());
|
||||||
const Style::Point &style = s.point(point->type());
|
const Style::Point &style = s.point(point->type());
|
||||||
|
|
||||||
@ -349,7 +355,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
QImage *rimg = style.img().isNull()
|
QImage *rimg = style.img().isNull()
|
||||||
? image(point->type(), point->param()) : 0;
|
? image(point->type(), point->param()) : 0;
|
||||||
const QImage *img = style.img().isNull() ? rimg : &style.img();
|
const QImage *img = style.img().isNull() ? rimg : &style.img();
|
||||||
const QFont *fnt = showLabel(img, _zooms, _zoom, point->type())
|
const QFont *fnt = showLabel(img, _data->zooms(), _zoom, point->type())
|
||||||
? font(style.textFontSize()) : 0;
|
? font(style.textFontSize()) : 0;
|
||||||
const QColor *color = &style.textColor();
|
const QColor *color = &style.textColor();
|
||||||
const QColor *hColor = style.haloColor().isValid()
|
const QColor *hColor = style.haloColor().isValid()
|
||||||
@ -371,12 +377,13 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processLines(QList<TextItem*> &textItems)
|
void RasterTile::processLines(const QList<MapData::Line*> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Line *line = _lines.at(i);
|
const MapData::Line *line = lines.at(i);
|
||||||
const Style::Line &style = s.line(line->type());
|
const Style::Line &style = s.line(line->type());
|
||||||
|
|
||||||
if (style.img().isNull() && style.pen() == Qt::NoPen)
|
if (style.img().isNull() && style.pen() == Qt::NoPen)
|
||||||
@ -396,25 +403,51 @@ void RasterTile::processLines(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Poly*> &polygons,
|
||||||
|
QList<MapData::Line*> &lines, QList<MapData::Point*> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
QRectF polyRect(ttl, QPointF(ttl.x() + _rect.width(), ttl.y()
|
||||||
|
+ _rect.height()));
|
||||||
|
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
||||||
|
_transform.img2proj(polyRect.bottomRight()));
|
||||||
|
RectC polyRectC(polyRectD.toRectC(_proj, 20));
|
||||||
|
_data->lines(polyRectC, &lines);
|
||||||
|
_data->polygons(polyRectC, &polygons);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), &points);
|
||||||
|
}
|
||||||
|
|
||||||
void RasterTile::render()
|
void RasterTile::render()
|
||||||
{
|
{
|
||||||
|
QList<MapData::Line*> lines;
|
||||||
|
QList<MapData::Poly*> polygons;
|
||||||
|
QList<MapData::Point*> points;
|
||||||
QList<TextItem*> textItems, lights;
|
QList<TextItem*> textItems, lights;
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
_pixmap.fill(Qt::transparent);
|
_pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
processPolygons(textItems);
|
fetchData(polygons, lines, points);
|
||||||
processPoints(textItems, lights);
|
|
||||||
processLines(textItems);
|
processPolygons(polygons, textItems);
|
||||||
|
processPoints(points, textItems, lights);
|
||||||
|
processLines(lines, textItems);
|
||||||
|
|
||||||
QPainter painter(&_pixmap);
|
QPainter painter(&_pixmap);
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
drawPolygons(&painter);
|
drawPolygons(&painter, polygons);
|
||||||
drawLines(&painter);
|
drawLines(&painter, lines);
|
||||||
drawArrows(&painter);
|
drawArrows(&painter, polygons);
|
||||||
|
|
||||||
drawTextItems(&painter, lights);
|
drawTextItems(&painter, lights);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
@ -15,13 +15,10 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform,
|
||||||
const Range &zooms, int zoom, const QRect &rect, qreal ratio,
|
const MapData *data, int zoom, const QRect &rect, qreal ratio)
|
||||||
const QList<MapData::Line*> &lines, const QList<MapData::Poly*> &polygons,
|
: _proj(proj), _transform(transform), _data(data), _zoom(zoom),
|
||||||
const QList<MapData::Point*> &points)
|
|
||||||
: _proj(proj), _transform(transform), _zooms(zooms), _zoom(zoom),
|
|
||||||
_rect(rect), _ratio(ratio),
|
_rect(rect), _ratio(ratio),
|
||||||
_pixmap(rect.width() * ratio, rect.height() * ratio), _lines(lines),
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
_polygons(polygons), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -44,31 +41,33 @@ private:
|
|||||||
const QImage *_rimg;
|
const QImage *_rimg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void fetchData(QList<MapData::Poly*> &polygons, QList<MapData::Line*> &lines,
|
||||||
|
QList<MapData::Point*> &points);
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
QPainterPath painterPath(const Polygon &polygon) const;
|
QPainterPath painterPath(const Polygon &polygon) const;
|
||||||
QPolygonF polyline(const QVector<Coordinates> &path) const;
|
QPolygonF polyline(const QVector<Coordinates> &path) const;
|
||||||
QPolygonF tsslptArrow(const Coordinates &c, qreal angle) const;
|
QPolygonF tsslptArrow(const Coordinates &c, qreal angle) const;
|
||||||
void processPoints(QList<TextItem*> &textItems, QList<TextItem *> &lights);
|
void processPoints(QList<MapData::Point *> &points,
|
||||||
void processLines(QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems, QList<TextItem *> &lights);
|
||||||
void processPolygons(QList<TextItem*> &textItems);
|
void processLines(const QList<MapData::Line *> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processPolygons(const QList<MapData::Poly *> &polygons,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
void drawBitmapPath(QPainter *painter, const QImage &img,
|
void drawBitmapPath(QPainter *painter, const QImage &img,
|
||||||
const Polygon &polygon);
|
const Polygon &polygon);
|
||||||
void drawArrows(QPainter *painter);
|
void drawArrows(QPainter *painter, const QList<MapData::Poly*> &polygons);
|
||||||
void drawPolygons(QPainter *painter);
|
void drawPolygons(QPainter *painter, const QList<MapData::Poly *> &polygons);
|
||||||
void drawLines(QPainter *painter);
|
void drawLines(QPainter *painter, const QList<MapData::Line *> &lines);
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
Range _zooms;
|
const MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Line*> _lines;
|
|
||||||
QList<MapData::Poly*> _polygons;
|
|
||||||
QList<MapData::Point*> _points;
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,14 +13,14 @@ bool MapData::polyCb(VectorTile *tile, void *context)
|
|||||||
{
|
{
|
||||||
PolyCTX *ctx = (PolyCTX*)context;
|
PolyCTX *ctx = (PolyCTX*)context;
|
||||||
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
|
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
|
||||||
ctx->polyCache);
|
ctx->polyCache, ctx->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::pointCb(VectorTile *tile, void *context)
|
bool MapData::pointCb(VectorTile *tile, void *context)
|
||||||
{
|
{
|
||||||
PointCTX *ctx = (PointCTX*)context;
|
PointCTX *ctx = (PointCTX*)context;
|
||||||
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->pointCache);
|
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->pointCache, ctx->lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ MapData::~MapData()
|
|||||||
void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||||
QList<Poly> *lines)
|
QList<Poly> *lines)
|
||||||
{
|
{
|
||||||
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache);
|
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache, &_lock);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
min[0] = rect.left();
|
min[0] = rect.left();
|
||||||
@ -58,7 +58,7 @@ void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
|||||||
|
|
||||||
void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
||||||
{
|
{
|
||||||
PointCTX ctx(rect, zoom(bits), points, &_pointCache);
|
PointCTX ctx(rect, zoom(bits), points, &_pointCache, &_lock);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
min[0] = rect.left();
|
min[0] = rect.left();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QMutex>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
@ -97,32 +98,37 @@ private:
|
|||||||
QList<Poly> lines;
|
QList<Poly> lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QCache<const SubDiv*, Polys> PolyCache;
|
||||||
|
typedef QCache<const SubDiv*, QList<Point> > PointCache;
|
||||||
|
|
||||||
struct PolyCTX
|
struct PolyCTX
|
||||||
{
|
{
|
||||||
PolyCTX(const RectC &rect, const Zoom &zoom,
|
PolyCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv*, MapData::Polys> *polyCache)
|
PolyCache *polyCache, QMutex *lock)
|
||||||
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
||||||
polyCache(polyCache) {}
|
polyCache(polyCache), lock(lock) {}
|
||||||
|
|
||||||
const RectC ▭
|
const RectC ▭
|
||||||
const Zoom &zoom;
|
const Zoom &zoom;
|
||||||
QList<MapData::Poly> *polygons;
|
QList<MapData::Poly> *polygons;
|
||||||
QList<MapData::Poly> *lines;
|
QList<MapData::Poly> *lines;
|
||||||
QCache<const SubDiv*, MapData::Polys> *polyCache;
|
PolyCache *polyCache;
|
||||||
|
QMutex *lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PointCTX
|
struct PointCTX
|
||||||
{
|
{
|
||||||
PointCTX(const RectC &rect, const Zoom &zoom,
|
PointCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points,
|
QList<MapData::Point> *points, PointCache *pointCache, QMutex *lock)
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
|
: rect(rect), zoom(zoom), points(points), pointCache(pointCache),
|
||||||
: rect(rect), zoom(zoom), points(points), pointCache(pointCache) {}
|
lock(lock) {}
|
||||||
|
|
||||||
const RectC ▭
|
const RectC ▭
|
||||||
const Zoom &zoom;
|
const Zoom &zoom;
|
||||||
QList<MapData::Point> *points;
|
QList<MapData::Point> *points;
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
|
PointCache *pointCache;
|
||||||
|
QMutex *lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Zoom &zoom(int bits) const;
|
const Zoom &zoom(int bits) const;
|
||||||
@ -130,8 +136,9 @@ private:
|
|||||||
static bool polyCb(VectorTile *tile, void *context);
|
static bool polyCb(VectorTile *tile, void *context);
|
||||||
static bool pointCb(VectorTile *tile, void *context);
|
static bool pointCb(VectorTile *tile, void *context);
|
||||||
|
|
||||||
QCache<const SubDiv*, Polys> _polyCache;
|
PolyCache _polyCache;
|
||||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
PointCache _pointCache;
|
||||||
|
QMutex _lock;
|
||||||
|
|
||||||
friend class VectorTile;
|
friend class VectorTile;
|
||||||
};
|
};
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
#include "map/textpathitem.h"
|
#include "map/textpathitem.h"
|
||||||
#include "map/textpointitem.h"
|
#include "map/textpointitem.h"
|
||||||
#include "map/bitmapline.h"
|
#include "map/bitmapline.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "lblfile.h"
|
#include "lblfile.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace IMG;
|
using namespace IMG;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
#define ICON_PADDING 2
|
#define ICON_PADDING 2
|
||||||
|
|
||||||
#define AREA(rect) \
|
#define AREA(rect) \
|
||||||
@ -147,40 +149,6 @@ static bool rectNearPolygon(const QPolygonF &polygon, const QRectF &rect)
|
|||||||
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
|
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RasterTile::render()
|
|
||||||
{
|
|
||||||
QList<TextItem*> textItems;
|
|
||||||
|
|
||||||
ll2xy(_polygons);
|
|
||||||
ll2xy(_lines);
|
|
||||||
ll2xy(_points);
|
|
||||||
|
|
||||||
processPoints(textItems);
|
|
||||||
processPolygons(textItems);
|
|
||||||
processLines(textItems);
|
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
|
||||||
_pixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter painter(&_pixmap);
|
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
|
||||||
|
|
||||||
drawPolygons(&painter);
|
|
||||||
drawLines(&painter);
|
|
||||||
drawTextItems(&painter, textItems);
|
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
|
||||||
|
|
||||||
_valid = true;
|
|
||||||
|
|
||||||
//painter.setPen(Qt::red);
|
|
||||||
//painter.setRenderHint(QPainter::Antialiasing, false);
|
|
||||||
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < polys.size(); i++) {
|
for (int i = 0; i < polys.size(); i++) {
|
||||||
@ -200,14 +168,15 @@ void RasterTile::ll2xy(QList<MapData::Point> &points)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPolygons(QPainter *painter)
|
void RasterTile::drawPolygons(QPainter *painter,
|
||||||
|
const QList<MapData::Poly> &polygons)
|
||||||
{
|
{
|
||||||
QCache<const LBLFile *, SubFile::Handle> hc(16);
|
QCache<const LBLFile *, SubFile::Handle> hc(16);
|
||||||
|
|
||||||
for (int n = 0; n < _style->drawOrder().size(); n++) {
|
for (int n = 0; n < _data->style()->drawOrder().size(); n++) {
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly &poly = _polygons.at(i);
|
const MapData::Poly &poly = polygons.at(i);
|
||||||
if (poly.type != _style->drawOrder().at(n))
|
if (poly.type != _data->style()->drawOrder().at(n))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (poly.raster.isValid()) {
|
if (poly.raster.isValid()) {
|
||||||
@ -237,7 +206,7 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
//painter->setBrush(Qt::NoBrush);
|
//painter->setBrush(Qt::NoBrush);
|
||||||
//painter->drawRect(QRectF(tl, br));
|
//painter->drawRect(QRectF(tl, br));
|
||||||
} else {
|
} else {
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
const Style::Polygon &style = _data->style()->polygon(poly.type);
|
||||||
|
|
||||||
painter->setPen(style.pen());
|
painter->setPen(style.pen());
|
||||||
painter->setBrush(style.brush());
|
painter->setBrush(style.brush());
|
||||||
@ -247,13 +216,13 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawLines(QPainter *painter)
|
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Poly> &lines)
|
||||||
{
|
{
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (style.background() == Qt::NoPen)
|
if (style.background() == Qt::NoPen)
|
||||||
continue;
|
continue;
|
||||||
@ -262,9 +231,9 @@ void RasterTile::drawLines(QPainter *painter)
|
|||||||
painter->drawPolyline(poly.points);
|
painter->drawPolyline(poly.points);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (!style.img().isNull())
|
if (!style.img().isNull())
|
||||||
BitmapLine::draw(painter, poly.points, style.img());
|
BitmapLine::draw(painter, poly.points, style.img());
|
||||||
@ -295,13 +264,14 @@ static void removeDuplicitLabel(QList<TextItem *> &labels, const QString &text,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
void RasterTile::processPolygons(const QList<MapData::Poly> &polygons,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
QSet<QString> set;
|
QSet<QString> set;
|
||||||
QList<TextItem *> labels;
|
QList<TextItem *> labels;
|
||||||
|
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly &poly = _polygons.at(i);
|
const MapData::Poly &poly = polygons.at(i);
|
||||||
bool exists = set.contains(poly.label.text());
|
bool exists = set.contains(poly.label.text());
|
||||||
|
|
||||||
if (poly.label.text().isEmpty())
|
if (poly.label.text().isEmpty())
|
||||||
@ -310,7 +280,7 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
if (_zoom <= 23 && (Style::isWaterArea(poly.type)
|
if (_zoom <= 23 && (Style::isWaterArea(poly.type)
|
||||||
|| Style::isMilitaryArea(poly.type)
|
|| Style::isMilitaryArea(poly.type)
|
||||||
|| Style::isNatureReserve(poly.type))) {
|
|| Style::isNatureReserve(poly.type))) {
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
const Style::Polygon &style = _data->style()->polygon(poly.type);
|
||||||
TextPointItem *item = new TextPointItem(
|
TextPointItem *item = new TextPointItem(
|
||||||
centroid(poly.points).toPoint(), &poly.label.text(), poiFont(),
|
centroid(poly.points).toPoint(), &poly.label.text(), poiFont(),
|
||||||
0, &style.brush().color(), &haloColor);
|
0, &style.brush().color(), &haloColor);
|
||||||
@ -331,20 +301,22 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
textItems.append(labels);
|
textItems.append(labels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processLines(QList<TextItem*> &textItems)
|
void RasterTile::processLines(QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
std::stable_sort(_lines.begin(), _lines.end());
|
std::stable_sort(lines.begin(), lines.end());
|
||||||
|
|
||||||
if (_zoom >= 22)
|
if (_zoom >= 22)
|
||||||
processStreetNames(textItems);
|
processStreetNames(lines, textItems);
|
||||||
processShields(textItems);
|
processShields(lines, textItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processStreetNames(QList<TextItem*> &textItems)
|
void RasterTile::processStreetNames(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (style.img().isNull() && style.foreground() == Qt::NoPen)
|
if (style.img().isNull() && style.foreground() == Qt::NoPen)
|
||||||
continue;
|
continue;
|
||||||
@ -366,7 +338,8 @@ void RasterTile::processStreetNames(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processShields(QList<TextItem*> &textItems)
|
void RasterTile::processShields(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
for (int type = FIRST_SHIELD; type <= LAST_SHIELD; type++) {
|
for (int type = FIRST_SHIELD; type <= LAST_SHIELD; type++) {
|
||||||
if (minShieldZoom(static_cast<Shield::Type>(type)) > _zoom)
|
if (minShieldZoom(static_cast<Shield::Type>(type)) > _zoom)
|
||||||
@ -375,8 +348,8 @@ void RasterTile::processShields(QList<TextItem*> &textItems)
|
|||||||
QHash<Shield, QPolygonF> shields;
|
QHash<Shield, QPolygonF> shields;
|
||||||
QHash<Shield, const Shield*> sp;
|
QHash<Shield, const Shield*> sp;
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Shield &shield = poly.label.shield();
|
const Shield &shield = poly.label.shield();
|
||||||
if (!shield.isValid() || shield.type() != type
|
if (!shield.isValid() || shield.type() != type
|
||||||
|| !Style::isMajorRoad(poly.type))
|
|| !Style::isMajorRoad(poly.type))
|
||||||
@ -429,13 +402,14 @@ void RasterTile::processShields(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<TextItem*> &textItems)
|
void RasterTile::processPoints(QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
std::sort(_points.begin(), _points.end());
|
std::sort(points.begin(), points.end());
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
const Style::Point &style = _style->point(point.type);
|
const Style::Point &style = _data->style()->point(point.type);
|
||||||
bool poi = Style::isPOI(point.type);
|
bool poi = Style::isPOI(point.type);
|
||||||
|
|
||||||
const QString *label = point.label.text().isEmpty()
|
const QString *label = point.label.text().isEmpty()
|
||||||
@ -446,12 +420,14 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
: font(style.textFontSize());
|
: font(style.textFontSize());
|
||||||
const QColor *color = style.textColor().isValid()
|
const QColor *color = style.textColor().isValid()
|
||||||
? &style.textColor() : &textColor;
|
? &style.textColor() : &textColor;
|
||||||
|
const QColor *hcolor = Style::isDepthPoint(point.type)
|
||||||
|
? 0 : &haloColor;
|
||||||
|
|
||||||
if ((!label || !fnt) && !img)
|
if ((!label || !fnt) && !img)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TextPointItem *item = new TextPointItem(QPoint(point.coordinates.lon(),
|
TextPointItem *item = new TextPointItem(QPoint(point.coordinates.lon(),
|
||||||
point.coordinates.lat()), label, fnt, img, color, &haloColor, 0,
|
point.coordinates.lat()), label, fnt, img, color, hcolor, 0,
|
||||||
ICON_PADDING);
|
ICON_PADDING);
|
||||||
if (item->isValid() && !item->collides(textItems))
|
if (item->isValid() && !item->collides(textItems))
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
@ -459,3 +435,60 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Poly> &polygons,
|
||||||
|
QList<MapData::Poly> &lines, QList<MapData::Point> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
QRectF polyRect(ttl, QPointF(ttl.x() + _rect.width(), ttl.y()
|
||||||
|
+ _rect.height()));
|
||||||
|
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
||||||
|
_transform.img2proj(polyRect.bottomRight()));
|
||||||
|
_data->polys(polyRectD.toRectC(_proj, 20), _zoom,
|
||||||
|
&polygons, &lines);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterTile::render()
|
||||||
|
{
|
||||||
|
QList<MapData::Poly> polygons;
|
||||||
|
QList<MapData::Poly> lines;
|
||||||
|
QList<MapData::Point> points;
|
||||||
|
QList<TextItem*> textItems;
|
||||||
|
|
||||||
|
fetchData(polygons, lines, points);
|
||||||
|
ll2xy(polygons);
|
||||||
|
ll2xy(lines);
|
||||||
|
ll2xy(points);
|
||||||
|
|
||||||
|
processPoints(points, textItems);
|
||||||
|
processPolygons(polygons, textItems);
|
||||||
|
processLines(lines, textItems);
|
||||||
|
|
||||||
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
|
_pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPainter painter(&_pixmap);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
|
drawPolygons(&painter, polygons);
|
||||||
|
drawLines(&painter, lines);
|
||||||
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
|
qDeleteAll(textItems);
|
||||||
|
|
||||||
|
_valid = true;
|
||||||
|
|
||||||
|
//painter.setPen(Qt::red);
|
||||||
|
//painter.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
||||||
|
}
|
||||||
|
@ -17,14 +17,11 @@ class Style;
|
|||||||
class RasterTile
|
class RasterTile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform, MapData *data,
|
||||||
const Style *style, int zoom, const QRect &rect, qreal ratio,
|
int zoom, const QRect &rect, qreal ratio, const QString &key)
|
||||||
const QString &key, const QList<MapData::Poly> &polygons,
|
: _proj(proj), _transform(transform), _data(data), _zoom(zoom),
|
||||||
const QList<MapData::Poly> &lines, QList<MapData::Point> &points)
|
_rect(rect), _ratio(ratio), _key(key),
|
||||||
: _proj(proj), _transform(transform), _style(style), _zoom(zoom),
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
_rect(rect), _ratio(ratio), _key(key),
|
|
||||||
_pixmap(rect.width() * ratio, rect.height() * ratio), _polygons(polygons),
|
|
||||||
_lines(lines), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
const QString &key() const {return _key;}
|
const QString &key() const {return _key;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -34,32 +31,36 @@ public:
|
|||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void fetchData(QList<MapData::Poly> &polygons, QList<MapData::Poly> &lines,
|
||||||
|
QList<MapData::Point> &points);
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void ll2xy(QList<MapData::Poly> &polys);
|
void ll2xy(QList<MapData::Poly> &polys);
|
||||||
void ll2xy(QList<MapData::Point> &points);
|
void ll2xy(QList<MapData::Point> &points);
|
||||||
|
|
||||||
void drawPolygons(QPainter *painter);
|
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons);
|
||||||
void drawLines(QPainter *painter);
|
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines);
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
|
|
||||||
void processPolygons(QList<TextItem *> &textItems);
|
void processPolygons(const QList<MapData::Poly> &polygons,
|
||||||
void processLines(QList<TextItem*> &textItems);
|
QList<TextItem *> &textItems);
|
||||||
void processPoints(QList<TextItem*> &textItems);
|
void processLines(QList<MapData::Poly> &lines,
|
||||||
void processShields(QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems);
|
||||||
void processStreetNames(QList<TextItem*> &textItems);
|
void processPoints(QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processShields(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processStreetNames(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
const Style *_style;
|
MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QString _key;
|
QString _key;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Poly> _polygons;
|
|
||||||
QList<MapData::Poly> _lines;
|
|
||||||
QList<MapData::Point> _points;
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/garmin.h"
|
#include "common/garmin.h"
|
||||||
|
#include "common/hash.h"
|
||||||
#include "deltastream.h"
|
#include "deltastream.h"
|
||||||
#include "huffmanstream.h"
|
#include "huffmanstream.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
@ -13,12 +14,10 @@ using namespace IMG;
|
|||||||
|
|
||||||
#define MASK(bits) ((1U << (bits)) - 1U)
|
#define MASK(bits) ((1U << (bits)) - 1U)
|
||||||
|
|
||||||
static quint64 pointId(const QPoint &pos, quint32 type)
|
static quint64 pointId(const QPoint &pos, quint32 type, const QString &label)
|
||||||
{
|
{
|
||||||
quint64 id;
|
quint64 hash = qHash(pos) ^ qHash(label);
|
||||||
|
quint64 id = ((quint64)type)<<40 | (hash & 0xFFFFFFFFFF);
|
||||||
uint hash = (uint)qHash(QPair<int, int>(pos.x(), pos.y()));
|
|
||||||
id = ((quint64)type)<<32 | hash;
|
|
||||||
|
|
||||||
// Increase rendering priorities for some special items
|
// Increase rendering priorities for some special items
|
||||||
if (!Style::isCountry(type) && !Style::isMarina(type))
|
if (!Style::isCountry(type) && !Style::isMarina(type))
|
||||||
@ -484,11 +483,11 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
|
|
||||||
point.type = (quint16)type<<8 | subtype;
|
point.type = (quint16)type<<8 | subtype;
|
||||||
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||||
point.id = pointId(pos, point.type);
|
|
||||||
if (lbl && (labelPtr & 0x3FFFFF))
|
if (lbl && (labelPtr & 0x3FFFFF))
|
||||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF,
|
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF,
|
||||||
labelPtr & 0x400000, !(Style::isCountry(point.type)
|
labelPtr & 0x400000, !(Style::isCountry(point.type)
|
||||||
|| Style::isState(point.type)), Style::isSpot(point.type));
|
|| Style::isState(point.type)), Style::isSpot(point.type));
|
||||||
|
point.id = pointId(pos, point.type, point.label.text());
|
||||||
|
|
||||||
points->append(point);
|
points->append(point);
|
||||||
}
|
}
|
||||||
@ -537,9 +536,9 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
point.coordinates = Coordinates(toWGS24(p.x()), toWGS24(p.y()));
|
point.coordinates = Coordinates(toWGS24(p.x()), toWGS24(p.y()));
|
||||||
point.id = pointId(p, point.type);
|
|
||||||
if (lbl && (labelPtr & 0x3FFFFF))
|
if (lbl && (labelPtr & 0x3FFFFF))
|
||||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||||
|
point.id = pointId(p, point.type, point.label.text());
|
||||||
|
|
||||||
points->append(point);
|
points->append(point);
|
||||||
}
|
}
|
||||||
|
@ -102,13 +102,18 @@ void VectorTile::clear()
|
|||||||
|
|
||||||
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
MapData::PolyCache *polyCache, QMutex *lock)
|
||||||
{
|
{
|
||||||
SubFile::Handle *rgnHdl = 0, *lblHdl = 0, *netHdl = 0, *nodHdl = 0,
|
SubFile::Handle *rgnHdl = 0, *lblHdl = 0, *netHdl = 0, *nodHdl = 0,
|
||||||
*nodHdl2 = 0;
|
*nodHdl2 = 0;
|
||||||
|
|
||||||
if (_loaded < 0)
|
lock->lock();
|
||||||
|
|
||||||
|
if (_loaded < 0) {
|
||||||
|
lock->unlock();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_loaded) {
|
if (!_loaded) {
|
||||||
rgnHdl = new SubFile::Handle(_rgn);
|
rgnHdl = new SubFile::Handle(_rgn);
|
||||||
lblHdl = new SubFile::Handle(_lbl);
|
lblHdl = new SubFile::Handle(_lbl);
|
||||||
@ -116,6 +121,7 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
|||||||
nodHdl = new SubFile::Handle(_nod);
|
nodHdl = new SubFile::Handle(_nod);
|
||||||
|
|
||||||
if (!load(*rgnHdl, *lblHdl, *netHdl, *nodHdl)) {
|
if (!load(*rgnHdl, *lblHdl, *netHdl, *nodHdl)) {
|
||||||
|
lock->unlock();
|
||||||
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl;
|
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -166,17 +172,24 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock->unlock();
|
||||||
|
|
||||||
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points, QCache<const SubDiv *,
|
QList<MapData::Point> *points, QCache<const SubDiv *,
|
||||||
QList<MapData::Point> > *pointCache)
|
QList<MapData::Point> > *pointCache, QMutex *lock)
|
||||||
{
|
{
|
||||||
SubFile::Handle *rgnHdl = 0, *lblHdl = 0;
|
SubFile::Handle *rgnHdl = 0, *lblHdl = 0;
|
||||||
|
|
||||||
if (_loaded < 0)
|
lock->lock();
|
||||||
|
|
||||||
|
if (_loaded < 0) {
|
||||||
|
lock->unlock();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_loaded) {
|
if (!_loaded) {
|
||||||
rgnHdl = new SubFile::Handle(_rgn);
|
rgnHdl = new SubFile::Handle(_rgn);
|
||||||
lblHdl = new SubFile::Handle(_lbl);
|
lblHdl = new SubFile::Handle(_lbl);
|
||||||
@ -184,6 +197,7 @@ void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
|||||||
SubFile::Handle netHdl(_net);
|
SubFile::Handle netHdl(_net);
|
||||||
|
|
||||||
if (!load(*rgnHdl, *lblHdl, netHdl, nodHdl)) {
|
if (!load(*rgnHdl, *lblHdl, netHdl, nodHdl)) {
|
||||||
|
lock->unlock();
|
||||||
delete rgnHdl; delete lblHdl;
|
delete rgnHdl; delete lblHdl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -217,6 +231,8 @@ void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
|||||||
copyPoints(rect, pl, points);
|
copyPoints(rect, pl, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock->unlock();
|
||||||
|
|
||||||
delete rgnHdl; delete lblHdl;
|
delete rgnHdl; delete lblHdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ public:
|
|||||||
|
|
||||||
void polys(const RectC &rect, const Zoom &zoom,
|
void polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
MapData::PolyCache *polyCache, QMutex *lock);
|
||||||
void points(const RectC &rect, const Zoom &zoom,
|
void points(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||||
QList<MapData::Point> > *pointCache);
|
QList<MapData::Point> > *pointCache, QMutex *lock);
|
||||||
|
|
||||||
static bool isTileFile(SubFile::Type type)
|
static bool isTileFile(SubFile::Type type)
|
||||||
{
|
{
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
#include "pcs.h"
|
#include "pcs.h"
|
||||||
#include "encmap.h"
|
#include "encmap.h"
|
||||||
|
|
||||||
#define TILE_SIZE 512
|
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
using namespace ENC;
|
using namespace ENC;
|
||||||
|
|
||||||
|
#define TILE_SIZE 512
|
||||||
|
|
||||||
ENCMap::ENCMap(const QString &fileName, QObject *parent)
|
ENCMap::ENCMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)),
|
: Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)),
|
||||||
@ -180,32 +179,9 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
QPixmap pm;
|
QPixmap pm;
|
||||||
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else
|
||||||
QList<MapData::Poly*> polygons;
|
tiles.append(RasterTile(_projection, _transform, &_data,
|
||||||
QList<MapData::Line*> lines;
|
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio));
|
||||||
QList<MapData::Point*> points;
|
|
||||||
|
|
||||||
QRectF polyRect(ttl, QPointF(ttl.x() + TILE_SIZE,
|
|
||||||
ttl.y() + TILE_SIZE));
|
|
||||||
polyRect &= _bounds;
|
|
||||||
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
|
||||||
_transform.img2proj(polyRect.bottomRight()));
|
|
||||||
RectC polyRectC(polyRectD.toRectC(_projection, 20));
|
|
||||||
_data.lines(polyRectC, &lines);
|
|
||||||
_data.polygons(polyRectC, &polygons);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
|
|
||||||
ttl.y() - TEXT_EXTENT), QPointF(ttl.x() + TILE_SIZE
|
|
||||||
+ TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.points(pointRectD.toRectC(_projection, 20), &points);
|
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, _data.zooms(),
|
|
||||||
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio,
|
|
||||||
lines, polygons, points));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
using namespace IMG;
|
using namespace IMG;
|
||||||
|
|
||||||
#define TILE_SIZE 384
|
#define TILE_SIZE 384
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
static RectC limitBounds(const RectC &bounds, const Projection &proj)
|
static RectC limitBounds(const RectC &bounds, const Projection &proj)
|
||||||
{
|
{
|
||||||
@ -241,30 +240,9 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
if (QPixmapCache::find(key, &pm))
|
if (QPixmapCache::find(key, &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else {
|
||||||
QList<MapData::Poly> polygons, lines;
|
tiles.append(RasterTile(_projection, _transform, _data.at(n),
|
||||||
QList<MapData::Point> points;
|
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio,
|
||||||
|
key));
|
||||||
QRectF polyRect(ttl, QPointF(ttl.x() + TILE_SIZE,
|
|
||||||
ttl.y() + TILE_SIZE));
|
|
||||||
polyRect &= _bounds;
|
|
||||||
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
|
||||||
_transform.img2proj(polyRect.bottomRight()));
|
|
||||||
_data.at(n)->polys(polyRectD.toRectC(_projection, 20), _zoom,
|
|
||||||
&polygons, &lines);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
|
|
||||||
ttl.y() - TEXT_EXTENT), QPointF(ttl.x() + TILE_SIZE
|
|
||||||
+ TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.at(n)->points(pointRectD.toRectC(_projection, 20),
|
|
||||||
_zoom, &points);
|
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform,
|
|
||||||
_data.at(n)->style(), _zoom,
|
|
||||||
QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio, key,
|
|
||||||
polygons, lines, points));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,34 +5,26 @@
|
|||||||
|
|
||||||
#define SAMPLES 100
|
#define SAMPLES 100
|
||||||
|
|
||||||
void Map::growLeft(const QPointF &p, RectC &rect)
|
static void growLeft(const Coordinates &c, RectC &rect)
|
||||||
{
|
{
|
||||||
Coordinates c(xy2ll(p));
|
|
||||||
|
|
||||||
if (c.lon() < rect.left())
|
if (c.lon() < rect.left())
|
||||||
rect.setLeft(c.lon());
|
rect.setLeft(c.lon());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::growRight(const QPointF &p, RectC &rect)
|
static void growRight(const Coordinates &c, RectC &rect)
|
||||||
{
|
{
|
||||||
Coordinates c(xy2ll(p));
|
|
||||||
|
|
||||||
if (c.lon() > rect.right())
|
if (c.lon() > rect.right())
|
||||||
rect.setRight(c.lon());
|
rect.setRight(c.lon());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::growTop(const QPointF &p, RectC &rect)
|
static void growTop(const Coordinates &c, RectC &rect)
|
||||||
{
|
{
|
||||||
Coordinates c(xy2ll(p));
|
|
||||||
|
|
||||||
if (c.lat() > rect.top())
|
if (c.lat() > rect.top())
|
||||||
rect.setTop(c.lat());
|
rect.setTop(c.lat());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::growBottom(const QPointF &p, RectC &rect)
|
static void growBottom(const Coordinates &c, RectC &rect)
|
||||||
{
|
{
|
||||||
Coordinates c(xy2ll(p));
|
|
||||||
|
|
||||||
if (c.lat() < rect.bottom())
|
if (c.lat() < rect.bottom())
|
||||||
rect.setBottom(c.lat());
|
rect.setBottom(c.lat());
|
||||||
}
|
}
|
||||||
@ -53,14 +45,14 @@ RectC Map::llBounds(const Projection &proj)
|
|||||||
|
|
||||||
for (int i = 0; i <= SAMPLES; i++) {
|
for (int i = 0; i <= SAMPLES; i++) {
|
||||||
double x = b.left() + i * dx;
|
double x = b.left() + i * dx;
|
||||||
growBottom(QPointF(x, b.bottom()), rect);
|
growBottom(xy2ll(QPointF(x, b.bottom())), rect);
|
||||||
growTop(QPointF(x, b.top()), rect);
|
growTop(xy2ll(QPointF(x, b.top())), rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= SAMPLES; i++) {
|
for (int i = 0; i <= SAMPLES; i++) {
|
||||||
double y = b.top() + i * dy;
|
double y = b.top() + i * dy;
|
||||||
growLeft(QPointF(b.left(), y), rect);
|
growLeft(xy2ll(QPointF(b.left(), y)), rect);
|
||||||
growRight(QPointF(b.right(), y), rect);
|
growRight(xy2ll(QPointF(b.right(), y)), rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
|
@ -62,11 +62,6 @@ signals:
|
|||||||
void mapLoaded();
|
void mapLoaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void growLeft(const QPointF &p, RectC &rect);
|
|
||||||
void growRight(const QPointF &p, RectC &rect);
|
|
||||||
void growTop(const QPointF &p, RectC &rect);
|
|
||||||
void growBottom(const QPointF &p, RectC &rect);
|
|
||||||
|
|
||||||
QString _path;
|
QString _path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -208,13 +208,15 @@ bool MapData::readTags(SubFile &subfile, int count,
|
|||||||
|
|
||||||
bool MapData::readSubFiles()
|
bool MapData::readSubFiles()
|
||||||
{
|
{
|
||||||
QDataStream stream(&_file);
|
/* both _pointFile and _pathFile can be used here */
|
||||||
|
QDataStream stream(&_pointFile);
|
||||||
|
|
||||||
for (int i = 0; i < _subFiles.size(); i++) {
|
for (int i = 0; i < _subFiles.size(); i++) {
|
||||||
const SubFileInfo &f = _subFiles.at(i);
|
const SubFileInfo &f = _subFiles.at(i);
|
||||||
quint64 offset, nextOffset;
|
quint64 offset, nextOffset;
|
||||||
|
|
||||||
stream.device()->seek(f.offset);
|
if (!stream.device()->seek(f.offset))
|
||||||
|
return false;
|
||||||
|
|
||||||
QPoint tl(OSM::ll2tile(_bounds.topLeft(), f.base));
|
QPoint tl(OSM::ll2tile(_bounds.topLeft(), f.base));
|
||||||
QPoint br(OSM::ll2tile(_bounds.bottomRight(), f.base));
|
QPoint br(OSM::ll2tile(_bounds.bottomRight(), f.base));
|
||||||
@ -359,7 +361,7 @@ bool MapData::readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readHeader()
|
bool MapData::readHeader(QFile &file)
|
||||||
{
|
{
|
||||||
char magic[MAGIC_SIZE];
|
char magic[MAGIC_SIZE];
|
||||||
quint32 hdrSize;
|
quint32 hdrSize;
|
||||||
@ -367,18 +369,18 @@ bool MapData::readHeader()
|
|||||||
bool debugMap;
|
bool debugMap;
|
||||||
|
|
||||||
|
|
||||||
if (_file.read(magic, MAGIC_SIZE) < (qint64)MAGIC_SIZE
|
if (file.read(magic, MAGIC_SIZE) < (qint64)MAGIC_SIZE
|
||||||
|| memcmp(magic, MAGIC, MAGIC_SIZE)) {
|
|| memcmp(magic, MAGIC, MAGIC_SIZE)) {
|
||||||
_errorString = "Not a Mapsforge map";
|
_errorString = "Not a Mapsforge map";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize)) {
|
if (file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize)) {
|
||||||
_errorString = "Unexpected EOF";
|
_errorString = "Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubFile hdr(_file, MAGIC_SIZE, qFromBigEndian(hdrSize));
|
SubFile hdr(file, MAGIC_SIZE, qFromBigEndian(hdrSize));
|
||||||
|
|
||||||
if (!readMapInfo(hdr, projection, debugMap)) {
|
if (!readMapInfo(hdr, projection, debugMap)) {
|
||||||
_errorString = "Error reading map info";
|
_errorString = "Error reading map info";
|
||||||
@ -407,18 +409,19 @@ bool MapData::readHeader()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::MapData(const QString &fileName) : _file(fileName), _valid(false)
|
MapData::MapData(const QString &fileName)
|
||||||
|
: _pointFile(fileName), _pathFile(fileName), _valid(false)
|
||||||
{
|
{
|
||||||
if (!_file.open(QFile::ReadOnly | QIODevice::Unbuffered)) {
|
QFile file(fileName);
|
||||||
_errorString = _file.errorString();
|
|
||||||
|
if (!file.open(QFile::ReadOnly | QIODevice::Unbuffered)) {
|
||||||
|
_errorString = file.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readHeader())
|
if (!readHeader(file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_file.close();
|
|
||||||
|
|
||||||
_pathCache.setMaxCost(256);
|
_pathCache.setMaxCost(256);
|
||||||
_pointCache.setMaxCost(256);
|
_pointCache.setMaxCost(256);
|
||||||
|
|
||||||
@ -444,13 +447,16 @@ RectC MapData::bounds() const
|
|||||||
|
|
||||||
void MapData::load()
|
void MapData::load()
|
||||||
{
|
{
|
||||||
if (_file.open(QIODevice::ReadOnly | QIODevice::Unbuffered))
|
_pointFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
readSubFiles();
|
_pathFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
|
|
||||||
|
readSubFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::clear()
|
void MapData::clear()
|
||||||
{
|
{
|
||||||
_file.close();
|
_pointFile.close();
|
||||||
|
_pathFile.close();
|
||||||
|
|
||||||
_pathCache.clear();
|
_pathCache.clear();
|
||||||
_pointCache.clear();
|
_pointCache.clear();
|
||||||
@ -497,6 +503,9 @@ int MapData::level(int zoom) const
|
|||||||
|
|
||||||
void MapData::points(const RectC &rect, int zoom, QList<Point> *list)
|
void MapData::points(const RectC &rect, int zoom, QList<Point> *list)
|
||||||
{
|
{
|
||||||
|
if (!rect.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
int l(level(zoom));
|
int l(level(zoom));
|
||||||
PointCTX ctx(this, rect, zoom, list);
|
PointCTX ctx(this, rect, zoom, list);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
@ -513,6 +522,9 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
QList<Point> *list)
|
QList<Point> *list)
|
||||||
{
|
{
|
||||||
Key key(tile, zoom);
|
Key key(tile, zoom);
|
||||||
|
|
||||||
|
_pointLock.lock();
|
||||||
|
|
||||||
QList<Point> *cached = _pointCache.object(key);
|
QList<Point> *cached = _pointCache.object(key);
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
@ -524,10 +536,15 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
delete p;
|
delete p;
|
||||||
} else
|
} else
|
||||||
copyPoints(rect, cached, list);
|
copyPoints(rect, cached, list);
|
||||||
|
|
||||||
|
_pointLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::paths(const RectC &rect, int zoom, QList<Path> *list)
|
void MapData::paths(const RectC &rect, int zoom, QList<Path> *list)
|
||||||
{
|
{
|
||||||
|
if (!rect.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
int l(level(zoom));
|
int l(level(zoom));
|
||||||
PathCTX ctx(this, rect, zoom, list);
|
PathCTX ctx(this, rect, zoom, list);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
@ -544,6 +561,9 @@ void MapData::paths(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
QList<Path> *list)
|
QList<Path> *list)
|
||||||
{
|
{
|
||||||
Key key(tile, zoom);
|
Key key(tile, zoom);
|
||||||
|
|
||||||
|
_pathLock.lock();
|
||||||
|
|
||||||
QList<Path> *cached = _pathCache.object(key);
|
QList<Path> *cached = _pathCache.object(key);
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
@ -555,12 +575,14 @@ void MapData::paths(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
delete p;
|
delete p;
|
||||||
} else
|
} else
|
||||||
copyPaths(rect, cached, list);
|
copyPaths(rect, cached, list);
|
||||||
|
|
||||||
|
_pathLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
||||||
{
|
{
|
||||||
const SubFileInfo &info = _subFiles.at(level(zoom));
|
const SubFileInfo &info = _subFiles.at(level(zoom));
|
||||||
SubFile subfile(_file, info.offset, info.size);
|
SubFile subfile(_pathFile, info.offset, info.size);
|
||||||
int rows = info.max - info.min + 1;
|
int rows = info.max - info.min + 1;
|
||||||
QVector<unsigned> paths(rows);
|
QVector<unsigned> paths(rows);
|
||||||
quint32 blocks, unused, val, cnt = 0;
|
quint32 blocks, unused, val, cnt = 0;
|
||||||
@ -584,8 +606,10 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
if (!subfile.seek(subfile.pos() + val))
|
if (!subfile.seek(subfile.pos() + val))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
paths.reserve(paths[zoom - info.min]);
|
||||||
|
|
||||||
for (unsigned i = 0; i < paths[zoom - info.min]; i++) {
|
for (unsigned i = 0; i < paths[zoom - info.min]; i++) {
|
||||||
Path p(subfile.offset() + subfile.pos());
|
Path p;
|
||||||
qint32 lon = 0, lat = 0;
|
qint32 lon = 0, lat = 0;
|
||||||
|
|
||||||
if (!(subfile.readVUInt32(unused) && subfile.readUInt16(bitmap)
|
if (!(subfile.readVUInt32(unused) && subfile.readUInt16(bitmap)
|
||||||
@ -644,7 +668,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
||||||
{
|
{
|
||||||
const SubFileInfo &info = _subFiles.at(level(zoom));
|
const SubFileInfo &info = _subFiles.at(level(zoom));
|
||||||
SubFile subfile(_file, info.offset, info.size);
|
SubFile subfile(_pointFile, info.offset, info.size);
|
||||||
int rows = info.max - info.min + 1;
|
int rows = info.max - info.min + 1;
|
||||||
QVector<unsigned> points(rows);
|
QVector<unsigned> points(rows);
|
||||||
quint32 val, unused, cnt = 0;
|
quint32 val, unused, cnt = 0;
|
||||||
@ -665,6 +689,8 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
|||||||
if (!subfile.readVUInt32(unused))
|
if (!subfile.readVUInt32(unused))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
list->reserve(points[zoom - info.min]);
|
||||||
|
|
||||||
for (unsigned i = 0; i < points[zoom - info.min]; i++) {
|
for (unsigned i = 0; i < points[zoom - info.min]; i++) {
|
||||||
qint32 lat, lon;
|
qint32 lat, lon;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QMutex>
|
||||||
#include "common/hash.h"
|
#include "common/hash.h"
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
@ -36,10 +37,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Point {
|
struct Point {
|
||||||
Point(const Coordinates &c) : coordinates(c)
|
Point(const Coordinates &c) : id(qHash(c)), coordinates(c) {}
|
||||||
{
|
|
||||||
id = (quint64)qHash(QPair<double, double>(c.lon(), c.lat()));
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 id;
|
quint64 id;
|
||||||
Coordinates coordinates;
|
Coordinates coordinates;
|
||||||
@ -48,9 +46,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Path {
|
struct Path {
|
||||||
Path(quint64 id) : id(id) {}
|
|
||||||
|
|
||||||
quint64 id;
|
|
||||||
Polygon poly;
|
Polygon poly;
|
||||||
QVector<Tag> tags;
|
QVector<Tag> tags;
|
||||||
Coordinates labelPos;
|
Coordinates labelPos;
|
||||||
@ -59,8 +54,6 @@ public:
|
|||||||
|
|
||||||
bool operator<(const Path &other) const
|
bool operator<(const Path &other) const
|
||||||
{return layer < other.layer;}
|
{return layer < other.layer;}
|
||||||
bool operator==(const Path &other) const
|
|
||||||
{return (id == other.id);}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RectC bounds() const;
|
RectC bounds() const;
|
||||||
@ -146,7 +139,7 @@ private:
|
|||||||
bool readTagInfo(SubFile &hdr);
|
bool readTagInfo(SubFile &hdr);
|
||||||
bool readTagInfo(SubFile &hdr, QVector<TagSource> &tags);
|
bool readTagInfo(SubFile &hdr, QVector<TagSource> &tags);
|
||||||
bool readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap);
|
bool readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap);
|
||||||
bool readHeader();
|
bool readHeader(QFile &file);
|
||||||
bool readSubFiles();
|
bool readSubFiles();
|
||||||
void clearTiles();
|
void clearTiles();
|
||||||
|
|
||||||
@ -165,7 +158,7 @@ private:
|
|||||||
|
|
||||||
friend HASH_T qHash(const MapData::Key &key);
|
friend HASH_T qHash(const MapData::Key &key);
|
||||||
|
|
||||||
QFile _file;
|
QFile _pointFile, _pathFile;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
quint16 _tileSize;
|
quint16 _tileSize;
|
||||||
QVector<SubFileInfo> _subFiles;
|
QVector<SubFileInfo> _subFiles;
|
||||||
@ -175,6 +168,7 @@ private:
|
|||||||
|
|
||||||
QCache<Key, QList<Path> > _pathCache;
|
QCache<Key, QList<Path> > _pathCache;
|
||||||
QCache<Key, QList<Point> > _pointCache;
|
QCache<Key, QList<Point> > _pointCache;
|
||||||
|
QMutex _pathLock, _pointLock;
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
@ -190,11 +184,6 @@ inline HASH_T qHash(const MapData::Tag &tag)
|
|||||||
return ::qHash(tag.key) ^ ::qHash(tag.value);
|
return ::qHash(tag.key) ^ ::qHash(tag.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HASH_T qHash(const MapData::Path &path)
|
|
||||||
{
|
|
||||||
return ::qHash(path.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
#include "common/programpaths.h"
|
#include "common/programpaths.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
|
|
||||||
static qreal area(const QPainterPath &polygon)
|
static qreal area(const QPainterPath &polygon)
|
||||||
{
|
{
|
||||||
qreal area = 0;
|
qreal area = 0;
|
||||||
@ -52,14 +55,15 @@ static const QColor *haloColor(const Style::TextRender *ti)
|
|||||||
? &ti->strokeColor() : 0;
|
? &ti->strokeColor() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
void RasterTile::processPointLabels(const QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
||||||
QList<PainterPoint> points;
|
QList<PainterPoint> painterPoints;
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
const QByteArray *lbl = 0;
|
const QByteArray *lbl = 0;
|
||||||
const Style::TextRender *ti = 0;
|
const Style::TextRender *ti = 0;
|
||||||
const Style::Symbol *si = 0;
|
const Style::Symbol *si = 0;
|
||||||
@ -83,13 +87,13 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ti || si)
|
if (ti || si)
|
||||||
points.append(PainterPoint(&point, lbl, si, ti));
|
painterPoints.append(PainterPoint(&point, lbl, si, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(points.begin(), points.end());
|
std::sort(painterPoints.begin(), painterPoints.end());
|
||||||
|
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < painterPoints.size(); i++) {
|
||||||
const PainterPoint &p = points.at(i);
|
const PainterPoint &p = painterPoints.at(i);
|
||||||
const QImage *img = p.si ? &p.si->img() : 0;
|
const QImage *img = p.si ? &p.si->img() : 0;
|
||||||
const QFont *font = p.ti ? &p.ti->font() : 0;
|
const QFont *font = p.ti ? &p.ti->font() : 0;
|
||||||
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
||||||
@ -200,17 +204,17 @@ QPainterPath RasterTile::painterPath(const Polygon &polygon, bool curve) const
|
|||||||
{
|
{
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
|
|
||||||
|
if (curve) {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int i = 0; i < polygon.size(); i++)
|
for (int i = 0; i < polygon.size(); i++)
|
||||||
size += polygon.at(i).size();
|
size += polygon.at(i).size();
|
||||||
path.reserve(size);
|
path.reserve(size);
|
||||||
#endif // QT 5.13
|
#endif // QT 5.13
|
||||||
|
|
||||||
for (int i = 0; i < polygon.size(); i++) {
|
for (int i = 0; i < polygon.size(); i++) {
|
||||||
const QVector<Coordinates> &subpath = polygon.at(i);
|
const QVector<Coordinates> &subpath = polygon.at(i);
|
||||||
|
|
||||||
if (curve) {
|
|
||||||
QPointF p1(ll2xy(subpath.first()));
|
QPointF p1(ll2xy(subpath.first()));
|
||||||
QPointF p2(0, 0);
|
QPointF p2(0, 0);
|
||||||
QPointF p3(0, 0);
|
QPointF p3(0, 0);
|
||||||
@ -223,25 +227,31 @@ QPainterPath RasterTile::painterPath(const Polygon &polygon, bool curve) const
|
|||||||
p1 = p3;
|
p1 = p3;
|
||||||
}
|
}
|
||||||
path.quadTo(p2, p3);
|
path.quadTo(p2, p3);
|
||||||
} else {
|
}
|
||||||
path.moveTo(ll2xy(subpath.first()));
|
} else {
|
||||||
for (int j = 1; j < subpath.size(); j++)
|
for (int i = 0; i < polygon.size(); i++) {
|
||||||
path.lineTo(ll2xy(subpath.at(j)));
|
const QVector<Coordinates> &subpath = polygon.at(i);
|
||||||
|
|
||||||
|
QVector<QPointF> p(subpath.size());
|
||||||
|
for (int j = 0; j < subpath.size(); j++)
|
||||||
|
p[j] = ll2xy(subpath.at(j));
|
||||||
|
path.addPolygon(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
void RasterTile::pathInstructions(const QList<MapData::Path> &paths,
|
||||||
|
QVector<PainterPath> &painterPaths,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
||||||
QList<const Style::PathRender*> *ri;
|
QList<const Style::PathRender*> *ri;
|
||||||
|
|
||||||
for (int i = 0; i < _paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
const MapData::Path &path = _paths.at(i);
|
const MapData::Path &path = paths.at(i);
|
||||||
PainterPath &rp = paths[i];
|
PainterPath &rp = painterPaths[i];
|
||||||
PathKey key(_zoom, path.closed, path.tags);
|
PathKey key(_zoom, path.closed, path.tags);
|
||||||
|
|
||||||
rp.path = &path;
|
rp.path = &path;
|
||||||
@ -259,14 +269,14 @@ void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::circleInstructions(
|
void RasterTile::circleInstructions(const QList<MapData::Point> &points,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
||||||
QList<const Style::CircleRender*> *ri;
|
QList<const Style::CircleRender*> *ri;
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
PointKey key(_zoom, point.tags);
|
PointKey key(_zoom, point.tags);
|
||||||
|
|
||||||
if (!(ri = cache.object(key))) {
|
if (!(ri = cache.object(key))) {
|
||||||
@ -282,11 +292,12 @@ void RasterTile::circleInstructions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPaths(QPainter *painter, QVector<PainterPath> &paths)
|
void RasterTile::drawPaths(QPainter *painter, const QList<MapData::Path> &paths,
|
||||||
|
const QList<MapData::Point> &points, QVector<PainterPath> &painterPaths)
|
||||||
{
|
{
|
||||||
QVector<RenderInstruction> instructions;
|
QVector<RenderInstruction> instructions;
|
||||||
pathInstructions(paths, instructions);
|
pathInstructions(paths, painterPaths, instructions);
|
||||||
circleInstructions(instructions);
|
circleInstructions(points, instructions);
|
||||||
std::sort(instructions.begin(), instructions.end());
|
std::sort(instructions.begin(), instructions.end());
|
||||||
|
|
||||||
for (int i = 0; i < instructions.size(); i++) {
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
@ -313,10 +324,37 @@ void RasterTile::drawPaths(QPainter *painter, QVector<PainterPath> &paths)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Path> &paths,
|
||||||
|
QList<MapData::Point> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
/* Add a "sub-pixel" margin to assure the tile areas do not
|
||||||
|
overlap on the border lines. This prevents areas overlap
|
||||||
|
artifacts at least when using the EPSG:3857 projection. */
|
||||||
|
QRectF pathRect(QPointF(ttl.x() + 0.5, ttl.y() + 0.5),
|
||||||
|
QPointF(ttl.x() + _rect.width() - 0.5, ttl.y() + _rect.height() - 0.5));
|
||||||
|
RectD pathRectD(_transform.img2proj(pathRect.topLeft()),
|
||||||
|
_transform.img2proj(pathRect.bottomRight()));
|
||||||
|
_data->paths(pathRectD.toRectC(_proj, 20), _zoom, &paths);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
|
||||||
|
}
|
||||||
|
|
||||||
void RasterTile::render()
|
void RasterTile::render()
|
||||||
{
|
{
|
||||||
|
QList<MapData::Path> paths;
|
||||||
|
QList<MapData::Point> points;
|
||||||
|
|
||||||
|
fetchData(paths, points);
|
||||||
|
|
||||||
QList<TextItem*> textItems;
|
QList<TextItem*> textItems;
|
||||||
QVector<PainterPath> renderPaths(_paths.size());
|
QVector<PainterPath> renderPaths(paths.size());
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
_pixmap.fill(Qt::transparent);
|
_pixmap.fill(Qt::transparent);
|
||||||
@ -325,9 +363,9 @@ void RasterTile::render()
|
|||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
drawPaths(&painter, renderPaths);
|
drawPaths(&painter, paths, points, renderPaths);
|
||||||
|
|
||||||
processPointLabels(textItems);
|
processPointLabels(points, textItems);
|
||||||
processAreaLabels(textItems, renderPaths);
|
processAreaLabels(textItems, renderPaths);
|
||||||
processLineLabels(textItems, renderPaths);
|
processLineLabels(textItems, renderPaths);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
@ -15,11 +15,10 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform,
|
||||||
const Style *style, int zoom, const QRect &rect, qreal ratio,
|
const Style *style, MapData *data, int zoom, const QRect &rect,
|
||||||
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
|
qreal ratio) : _proj(proj), _transform(transform), _style(style),
|
||||||
: _proj(proj), _transform(transform), _style(style),
|
_data(data), _zoom(zoom), _rect(rect), _ratio(ratio),
|
||||||
_zoom(zoom), _rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio,
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
rect.height() * ratio), _paths(paths), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -147,31 +146,33 @@ private:
|
|||||||
friend HASH_T qHash(const RasterTile::PathKey &key);
|
friend HASH_T qHash(const RasterTile::PathKey &key);
|
||||||
friend HASH_T qHash(const RasterTile::PointKey &key);
|
friend HASH_T qHash(const RasterTile::PointKey &key);
|
||||||
|
|
||||||
void pathInstructions(QVector<PainterPath> &paths,
|
void fetchData(QList<MapData::Path> &paths, QList<MapData::Point> &points);
|
||||||
|
void pathInstructions(const QList<MapData::Path> &paths,
|
||||||
|
QVector<PainterPath> &painterPaths,
|
||||||
|
QVector<RasterTile::RenderInstruction> &instructions);
|
||||||
|
void circleInstructions(const QList<MapData::Point> &points,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions);
|
QVector<RasterTile::RenderInstruction> &instructions);
|
||||||
void circleInstructions(QVector<RasterTile::RenderInstruction> &instructions);
|
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void processPointLabels(QList<TextItem*> &textItems);
|
void processPointLabels(const QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
void processAreaLabels(QList<TextItem*> &textItems,
|
void processAreaLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths);
|
QVector<PainterPath> &paths);
|
||||||
void processLineLabels(QList<TextItem*> &textItems,
|
void processLineLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths);
|
QVector<PainterPath> &paths);
|
||||||
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
void drawPaths(QPainter *painter, QVector<PainterPath> &paths);
|
void drawPaths(QPainter *painter, const QList<MapData::Path> &paths,
|
||||||
|
const QList<MapData::Point> &points, QVector<PainterPath> &painterPaths);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
const Style *_style;
|
const Style *_style;
|
||||||
|
MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Path> _paths;
|
|
||||||
QList<MapData::Point> _points;
|
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,6 +154,13 @@ void Style::area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (attr.hasAttribute("scale")) {
|
||||||
|
QString scale(attr.value("scale").toString());
|
||||||
|
if (scale == "all")
|
||||||
|
ri._scale = PathRender::Scale::All;
|
||||||
|
else if (scale == "none")
|
||||||
|
ri._scale = PathRender::Scale::None;
|
||||||
|
}
|
||||||
if (attr.hasAttribute("src"))
|
if (attr.hasAttribute("src"))
|
||||||
file = resourcePath(attr.value("src").toString(), dir);
|
file = resourcePath(attr.value("src").toString(), dir);
|
||||||
if (attr.hasAttribute("symbol-height")) {
|
if (attr.hasAttribute("symbol-height")) {
|
||||||
@ -226,6 +233,13 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
|
|||||||
else if (join == "bevel")
|
else if (join == "bevel")
|
||||||
ri._strokeJoin = Qt::BevelJoin;
|
ri._strokeJoin = Qt::BevelJoin;
|
||||||
}
|
}
|
||||||
|
if (attr.hasAttribute("scale")) {
|
||||||
|
QString scale(attr.value("scale").toString());
|
||||||
|
if (scale == "all")
|
||||||
|
ri._scale = PathRender::Scale::All;
|
||||||
|
else if (scale == "none")
|
||||||
|
ri._scale = PathRender::Scale::None;
|
||||||
|
}
|
||||||
if (attr.hasAttribute("curve")) {
|
if (attr.hasAttribute("curve")) {
|
||||||
QString curve(attr.value("curve").toString());
|
QString curve(attr.value("curve").toString());
|
||||||
if (curve == "cubic")
|
if (curve == "cubic")
|
||||||
@ -656,14 +670,18 @@ QList<const Style::Symbol*> Style::areaSymbols(int zoom) const
|
|||||||
QPen Style::PathRender::pen(int zoom) const
|
QPen Style::PathRender::pen(int zoom) const
|
||||||
{
|
{
|
||||||
if (_strokeColor.isValid()) {
|
if (_strokeColor.isValid()) {
|
||||||
qreal width = (zoom >= 12)
|
qreal width = (_scale > None && zoom >= 12)
|
||||||
? pow(1.5, zoom - 12) * _strokeWidth : _strokeWidth;
|
? pow(1.5, zoom - 12) * _strokeWidth : _strokeWidth;
|
||||||
QPen p(QBrush(_strokeColor), width, Qt::SolidLine, _strokeCap,
|
QPen p(QBrush(_strokeColor), width, Qt::SolidLine, _strokeCap,
|
||||||
_strokeJoin);
|
_strokeJoin);
|
||||||
if (!_strokeDasharray.isEmpty()) {
|
if (!_strokeDasharray.isEmpty()) {
|
||||||
QVector<qreal>pattern(_strokeDasharray);
|
QVector<qreal>pattern(_strokeDasharray);
|
||||||
for (int i = 0; i < _strokeDasharray.size(); i++)
|
for (int i = 0; i < _strokeDasharray.size(); i++) {
|
||||||
|
if (_scale > Stroke && zoom >= 12)
|
||||||
|
pattern[i] = (pow(1.5, zoom - 12) * pattern[i]);
|
||||||
|
// QPainter pattern is specified in units of the pens width!
|
||||||
pattern[i] /= width;
|
pattern[i] /= width;
|
||||||
|
}
|
||||||
p.setDashPattern(pattern);
|
p.setDashPattern(pattern);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
|
@ -136,7 +136,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
PathRender(const Rule &rule, int zOrder) : Render(rule),
|
PathRender(const Rule &rule, int zOrder) : Render(rule),
|
||||||
_zOrder(zOrder), _strokeWidth(0), _strokeCap(Qt::RoundCap),
|
_zOrder(zOrder), _strokeWidth(0), _strokeCap(Qt::RoundCap),
|
||||||
_strokeJoin(Qt::RoundJoin), _area(false), _curve(false) {}
|
_strokeJoin(Qt::RoundJoin), _area(false), _curve(false),
|
||||||
|
_scale(Stroke) {}
|
||||||
|
|
||||||
int zOrder() const {return _zOrder;}
|
int zOrder() const {return _zOrder;}
|
||||||
QPen pen(int zoom) const;
|
QPen pen(int zoom) const;
|
||||||
@ -147,6 +148,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class Style;
|
friend class Style;
|
||||||
|
|
||||||
|
enum Scale {None, Stroke, All};
|
||||||
|
|
||||||
int _zOrder;
|
int _zOrder;
|
||||||
QColor _strokeColor;
|
QColor _strokeColor;
|
||||||
qreal _strokeWidth;
|
qreal _strokeWidth;
|
||||||
@ -155,6 +158,7 @@ public:
|
|||||||
Qt::PenJoinStyle _strokeJoin;
|
Qt::PenJoinStyle _strokeJoin;
|
||||||
QBrush _brush;
|
QBrush _brush;
|
||||||
bool _area, _curve;
|
bool _area, _curve;
|
||||||
|
Scale _scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CircleRender : public Render
|
class CircleRender : public Render
|
||||||
|
@ -14,7 +14,6 @@ public:
|
|||||||
: _file(file), _offset(offset), _size(size), _pos(-1),
|
: _file(file), _offset(offset), _size(size), _pos(-1),
|
||||||
_blockNum(-1), _blockPos(-1) {}
|
_blockNum(-1), _blockPos(-1) {}
|
||||||
|
|
||||||
quint64 offset() const {return _offset;}
|
|
||||||
quint64 pos() const {return _pos;}
|
quint64 pos() const {return _pos;}
|
||||||
bool seek(quint64 pos);
|
bool seek(quint64 pos);
|
||||||
|
|
||||||
|
@ -2,15 +2,13 @@
|
|||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include "common/wgs84.h"
|
#include "common/wgs84.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "pcs.h"
|
|
||||||
#include "rectd.h"
|
#include "rectd.h"
|
||||||
|
#include "pcs.h"
|
||||||
#include "mapsforgemap.h"
|
#include "mapsforgemap.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
|
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _data(fileName), _zoom(0),
|
: Map(fileName, parent), _data(fileName), _zoom(0),
|
||||||
_projection(PCS::pcs(3857)), _tileRatio(1.0)
|
_projection(PCS::pcs(3857)), _tileRatio(1.0)
|
||||||
@ -188,32 +186,9 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else {
|
||||||
QList<MapData::Path> paths;
|
tiles.append(RasterTile(_projection, _transform, &_style, &_data,
|
||||||
QList<MapData::Point> points;
|
_zoom, QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||||
|
_tileRatio));
|
||||||
/* Add a "sub-pixel" margin to assure the tile areas do not
|
|
||||||
overlap on the border lines. This prevents areas overlap
|
|
||||||
artifacts at least when using the EPSG:3857 projection. */
|
|
||||||
QRectF pathRect(QPointF(ttl.x() + 0.5, ttl.y() + 0.5),
|
|
||||||
QPointF(ttl.x() + _data.tileSize() - 0.5, ttl.y()
|
|
||||||
+ _data.tileSize() - 0.5));
|
|
||||||
pathRect &= _bounds;
|
|
||||||
RectD pathRectD(_transform.img2proj(pathRect.topLeft()),
|
|
||||||
_transform.img2proj(pathRect.bottomRight()));
|
|
||||||
_data.paths(pathRectD.toRectC(_projection, 20), _zoom, &paths);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y()
|
|
||||||
- TEXT_EXTENT), QPointF(ttl.x() + _data.tileSize()
|
|
||||||
+ TEXT_EXTENT, ttl.y() + _data.tileSize() + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.points(pointRectD.toRectC(_projection, 20), _zoom,
|
|
||||||
&points);
|
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, &_style, _zoom,
|
|
||||||
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
|
||||||
_tileRatio, paths, points));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,14 +189,22 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
|
|||||||
else
|
else
|
||||||
config.dimensions.append(KV<QString, QString>
|
config.dimensions.append(KV<QString, QString>
|
||||||
(attr.value("id").toString(), reader.readElementText()));
|
(attr.value("id").toString(), reader.readElementText()));
|
||||||
|
} else if (reader.name() == QLatin1String("header")) {
|
||||||
|
QXmlStreamAttributes attr = reader.attributes();
|
||||||
|
if (!attr.hasAttribute("name"))
|
||||||
|
reader.raiseError("Missing header name");
|
||||||
|
else
|
||||||
|
config.headers.append(HTTPHeader(
|
||||||
|
attr.value("name").toString().toLatin1(),
|
||||||
|
reader.readElementText().toLatin1()));
|
||||||
} else if (reader.name() == QLatin1String("crs")) {
|
} else if (reader.name() == QLatin1String("crs")) {
|
||||||
config.coordinateSystem = coordinateSystem(reader);
|
config.coordinateSystem = coordinateSystem(reader);
|
||||||
config.crs = reader.readElementText();
|
config.crs = reader.readElementText();
|
||||||
} else if (reader.name() == QLatin1String("authorization")) {
|
} else if (reader.name() == QLatin1String("authorization")) {
|
||||||
QXmlStreamAttributes attr = reader.attributes();
|
QXmlStreamAttributes attr = reader.attributes();
|
||||||
config.authorization = Authorization(
|
Authorization auth(attr.value("username").toString(),
|
||||||
attr.value("username").toString(),
|
|
||||||
attr.value("password").toString());
|
attr.value("password").toString());
|
||||||
|
config.headers.append(auth.header());
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
} else if (reader.name() == QLatin1String("tile")) {
|
} else if (reader.name() == QLatin1String("tile")) {
|
||||||
tile(reader, config);
|
tile(reader, config);
|
||||||
@ -252,24 +260,24 @@ Map *MapSource::create(const QString &path, bool *isDir)
|
|||||||
case WMTS:
|
case WMTS:
|
||||||
return new WMTSMap(path, config.name, WMTS::Setup(config.url,
|
return new WMTSMap(path, config.name, WMTS::Setup(config.url,
|
||||||
config.layer, config.set, config.style, config.format, config.rest,
|
config.layer, config.set, config.style, config.format, config.rest,
|
||||||
config.coordinateSystem, config.dimensions, config.authorization),
|
config.coordinateSystem, config.dimensions, config.headers),
|
||||||
config.tileRatio);
|
config.tileRatio);
|
||||||
case WMS:
|
case WMS:
|
||||||
return new WMSMap(path, config.name, WMS::Setup(config.url,
|
return new WMSMap(path, config.name, WMS::Setup(config.url,
|
||||||
config.layer, config.style, config.format, config.crs,
|
config.layer, config.style, config.format, config.crs,
|
||||||
config.coordinateSystem, config.dimensions, config.authorization),
|
config.coordinateSystem, config.dimensions, config.headers),
|
||||||
config.tileSize);
|
config.tileSize);
|
||||||
case TMS:
|
case TMS:
|
||||||
return new OnlineMap(path, config.name, config.url, config.zooms,
|
return new OnlineMap(path, config.name, config.url, config.zooms,
|
||||||
config.bounds, config.tileRatio, config.authorization,
|
config.bounds, config.tileRatio, config.headers,
|
||||||
config.tileSize, config.scalable, true, false);
|
config.tileSize, config.scalable, true, false);
|
||||||
case OSM:
|
case OSM:
|
||||||
return new OnlineMap(path, config.name, config.url, config.zooms,
|
return new OnlineMap(path, config.name, config.url, config.zooms,
|
||||||
config.bounds, config.tileRatio, config.authorization,
|
config.bounds, config.tileRatio, config.headers,
|
||||||
config.tileSize, config.scalable, false, false);
|
config.tileSize, config.scalable, false, false);
|
||||||
case QuadTiles:
|
case QuadTiles:
|
||||||
return new OnlineMap(path, config.name, config.url, config.zooms,
|
return new OnlineMap(path, config.name, config.url, config.zooms,
|
||||||
config.bounds, config.tileRatio, config.authorization,
|
config.bounds, config.tileRatio, config.headers,
|
||||||
config.tileSize, config.scalable, false, true);
|
config.tileSize, config.scalable, false, true);
|
||||||
default:
|
default:
|
||||||
return new InvalidMap(path, "Invalid map type");
|
return new InvalidMap(path, "Invalid map type");
|
||||||
|
@ -40,7 +40,7 @@ private:
|
|||||||
CoordinateSystem coordinateSystem;
|
CoordinateSystem coordinateSystem;
|
||||||
bool rest;
|
bool rest;
|
||||||
QList<KV<QString, QString> > dimensions;
|
QList<KV<QString, QString> > dimensions;
|
||||||
Authorization authorization;
|
QList<HTTPHeader> headers;
|
||||||
qreal tileRatio;
|
qreal tileRatio;
|
||||||
int tileSize;
|
int tileSize;
|
||||||
bool scalable;
|
bool scalable;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
OnlineMap::OnlineMap(const QString &fileName, const QString &name,
|
OnlineMap::OnlineMap(const QString &fileName, const QString &name,
|
||||||
const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio,
|
const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio,
|
||||||
const Authorization &authorization, int tileSize, bool scalable, bool invertY,
|
const QList<HTTPHeader> &headers, int tileSize, bool scalable, bool invertY,
|
||||||
bool quadTiles, QObject *parent)
|
bool quadTiles, QObject *parent)
|
||||||
: Map(fileName, parent), _name(name), _zooms(zooms), _bounds(bounds),
|
: Map(fileName, parent), _name(name), _zooms(zooms), _bounds(bounds),
|
||||||
_zoom(_zooms.max()), _tileSize(tileSize), _mapRatio(1.0),
|
_zoom(_zooms.max()), _tileSize(tileSize), _mapRatio(1.0),
|
||||||
@ -19,7 +19,7 @@ OnlineMap::OnlineMap(const QString &fileName, const QString &name,
|
|||||||
_tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name),
|
_tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name),
|
||||||
this);
|
this);
|
||||||
_tileLoader->setUrl(url);
|
_tileLoader->setUrl(url);
|
||||||
_tileLoader->setAuthorization(authorization);
|
_tileLoader->setHeaders(headers);
|
||||||
_tileLoader->setQuadTiles(quadTiles);
|
_tileLoader->setQuadTiles(quadTiles);
|
||||||
connect(_tileLoader, &TileLoader::finished, this, &OnlineMap::tilesLoaded);
|
connect(_tileLoader, &TileLoader::finished, this, &OnlineMap::tilesLoaded);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class OnlineMap : public Map
|
|||||||
public:
|
public:
|
||||||
OnlineMap(const QString &fileName, const QString &name, const QString &url,
|
OnlineMap(const QString &fileName, const QString &name, const QString &url,
|
||||||
const Range &zooms, const RectC &bounds, qreal tileRatio,
|
const Range &zooms, const RectC &bounds, qreal tileRatio,
|
||||||
const Authorization &authorization, int tileSize, bool scalable,
|
const QList<HTTPHeader> &headers, int tileSize, bool scalable,
|
||||||
bool invertY, bool quadTiles, QObject *parent = 0);
|
bool invertY, bool quadTiles, QObject *parent = 0);
|
||||||
|
|
||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
const QVariant &zoom() const {return _zoom;}
|
const QVariant &zoom() const {return _zoom;}
|
||||||
const QPoint &xy() const {return _xy;}
|
const QPoint &xy() const {return _xy;}
|
||||||
const RectD &bbox() const {return _bbox;}
|
const RectD &bbox() const {return _bbox;}
|
||||||
QPixmap& pixmap() {return _pixmap;}
|
QPixmap &pixmap() {return _pixmap;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPoint _xy;
|
QPoint _xy;
|
||||||
|
@ -61,6 +61,7 @@ TileLoader::TileLoader(const QString &dir, QObject *parent)
|
|||||||
connect(_downloader, &Downloader::finished, this, &TileLoader::finished);
|
connect(_downloader, &Downloader::finished, this, &TileLoader::finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TileLoader::loadTilesAsync(QVector<FetchTile> &list)
|
void TileLoader::loadTilesAsync(QVector<FetchTile> &list)
|
||||||
{
|
{
|
||||||
QList<Download> dl;
|
QList<Download> dl;
|
||||||
@ -87,7 +88,7 @@ void TileLoader::loadTilesAsync(QVector<FetchTile> &list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!dl.empty())
|
if (!dl.empty())
|
||||||
_downloader->get(dl, _authorization);
|
_downloader->get(dl, _headers);
|
||||||
|
|
||||||
QFuture<void> future = QtConcurrent::map(imgs, &TileImage::load);
|
QFuture<void> future = QtConcurrent::map(imgs, &TileImage::load);
|
||||||
future.waitForFinished();
|
future.waitForFinished();
|
||||||
@ -129,7 +130,7 @@ void TileLoader::loadTilesSync(QVector<FetchTile> &list)
|
|||||||
if (!dl.empty()) {
|
if (!dl.empty()) {
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
connect(_downloader, &Downloader::finished, &wait, &QEventLoop::quit);
|
connect(_downloader, &Downloader::finished, &wait, &QEventLoop::quit);
|
||||||
if (_downloader->get(dl, _authorization))
|
if (_downloader->get(dl, _headers))
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
for (int i = 0; i < tl.size(); i++) {
|
for (int i = 0; i < tl.size(); i++) {
|
||||||
@ -142,6 +143,11 @@ void TileLoader::loadTilesSync(QVector<FetchTile> &list)
|
|||||||
|
|
||||||
QFuture<void> future = QtConcurrent::map(imgs, &TileImage::load);
|
QFuture<void> future = QtConcurrent::map(imgs, &TileImage::load);
|
||||||
future.waitForFinished();
|
future.waitForFinished();
|
||||||
|
|
||||||
|
for (int i = 0; i < imgs.size(); i++) {
|
||||||
|
TileImage &ti = imgs[i];
|
||||||
|
QPixmapCache::insert(ti.file(), ti.tile()->pixmap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileLoader::clearCache()
|
void TileLoader::clearCache()
|
||||||
|
@ -14,8 +14,7 @@ public:
|
|||||||
TileLoader(const QString &dir, QObject *parent = 0);
|
TileLoader(const QString &dir, QObject *parent = 0);
|
||||||
|
|
||||||
void setUrl(const QString &url) {_url = url;}
|
void setUrl(const QString &url) {_url = url;}
|
||||||
void setAuthorization(const Authorization &authorization)
|
void setHeaders(const QList<HTTPHeader> &headers) {_headers = headers;}
|
||||||
{_authorization = authorization;}
|
|
||||||
void setScaledSize(int size);
|
void setScaledSize(int size);
|
||||||
void setQuadTiles(bool quadTiles) {_quadTiles = quadTiles;}
|
void setQuadTiles(bool quadTiles) {_quadTiles = quadTiles;}
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ private:
|
|||||||
Downloader *_downloader;
|
Downloader *_downloader;
|
||||||
QString _url;
|
QString _url;
|
||||||
QString _dir;
|
QString _dir;
|
||||||
Authorization _authorization;
|
QList<HTTPHeader> _headers;
|
||||||
int _scaledSize;
|
int _scaledSize;
|
||||||
bool _quadTiles;
|
bool _quadTiles;
|
||||||
};
|
};
|
||||||
|
@ -345,7 +345,7 @@ WMS::WMS(const QString &file, const WMS::Setup &setup, QObject *parent)
|
|||||||
|
|
||||||
QList<Download> dl;
|
QList<Download> dl;
|
||||||
dl.append(Download(url, _path));
|
dl.append(Download(url, _path));
|
||||||
_valid = downloader->get(dl, _setup.authorization());
|
_valid = downloader->get(dl, _setup.headers());
|
||||||
} else {
|
} else {
|
||||||
_ready = true;
|
_ready = true;
|
||||||
_valid = parseCapabilities();
|
_valid = parseCapabilities();
|
||||||
|
@ -23,13 +23,13 @@ public:
|
|||||||
Setup(const QString &url, const QString &layer, const QString &style,
|
Setup(const QString &url, const QString &layer, const QString &style,
|
||||||
const QString &format, const QString &crs, const CoordinateSystem &cs,
|
const QString &format, const QString &crs, const CoordinateSystem &cs,
|
||||||
const QList<KV<QString, QString> > &dimensions,
|
const QList<KV<QString, QString> > &dimensions,
|
||||||
const Authorization &authorization = Authorization())
|
const QList<HTTPHeader> &headers)
|
||||||
: _url(url), _layer(layer), _style(style), _format(format),
|
: _url(url), _layer(layer), _style(style), _format(format),
|
||||||
_crs(crs), _cs(cs), _dimensions(dimensions),
|
_crs(crs), _cs(cs), _dimensions(dimensions),
|
||||||
_authorization(authorization) {}
|
_headers(headers) {}
|
||||||
|
|
||||||
const QString &url() const {return _url;}
|
const QString &url() const {return _url;}
|
||||||
const Authorization &authorization() const {return _authorization;}
|
const QList<HTTPHeader> &headers() const {return _headers;}
|
||||||
const QString &layer() const {return _layer;}
|
const QString &layer() const {return _layer;}
|
||||||
const QString &style() const {return _style;}
|
const QString &style() const {return _style;}
|
||||||
const QString &format() const {return _format;}
|
const QString &format() const {return _format;}
|
||||||
@ -46,7 +46,7 @@ public:
|
|||||||
QString _crs;
|
QString _crs;
|
||||||
CoordinateSystem _cs;
|
CoordinateSystem _cs;
|
||||||
QList<KV<QString, QString> > _dimensions;
|
QList<KV<QString, QString> > _dimensions;
|
||||||
Authorization _authorization;
|
QList<HTTPHeader> _headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ WMSMap::WMSMap(const QString &fileName, const QString &name,
|
|||||||
QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name));
|
QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name));
|
||||||
|
|
||||||
_tileLoader = new TileLoader(tilesDir, this);
|
_tileLoader = new TileLoader(tilesDir, this);
|
||||||
_tileLoader->setAuthorization(setup.authorization());
|
_tileLoader->setHeaders(setup.headers());
|
||||||
connect(_tileLoader, &TileLoader::finished, this, &WMSMap::tilesLoaded);
|
connect(_tileLoader, &TileLoader::finished, this, &WMSMap::tilesLoaded);
|
||||||
|
|
||||||
_wms = new WMS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this);
|
_wms = new WMS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this);
|
||||||
|
@ -361,7 +361,7 @@ WMTS::WMTS(const QString &file, const WMTS::Setup &setup, QObject *parent)
|
|||||||
|
|
||||||
QList<Download> dl;
|
QList<Download> dl;
|
||||||
dl.append(Download(url.toString(), _path));
|
dl.append(Download(url.toString(), _path));
|
||||||
_valid = downloader->get(dl, _setup.authorization());
|
_valid = downloader->get(dl, _setup.headers());
|
||||||
} else {
|
} else {
|
||||||
_ready = true;
|
_ready = true;
|
||||||
_valid = init();
|
_valid = init();
|
||||||
|
@ -27,13 +27,13 @@ public:
|
|||||||
const QString &style, const QString &format, bool rest,
|
const QString &style, const QString &format, bool rest,
|
||||||
const CoordinateSystem &cs,
|
const CoordinateSystem &cs,
|
||||||
const QList<KV<QString, QString> > &dimensions,
|
const QList<KV<QString, QString> > &dimensions,
|
||||||
const Authorization &authorization = Authorization())
|
const QList<HTTPHeader> &headers)
|
||||||
: _url(url), _layer(layer), _set(set), _style(style),
|
: _url(url), _layer(layer), _set(set), _style(style),
|
||||||
_format(format), _rest(rest), _cs(cs), _dimensions(dimensions),
|
_format(format), _rest(rest), _cs(cs), _dimensions(dimensions),
|
||||||
_authorization(authorization) {}
|
_headers(headers) {}
|
||||||
|
|
||||||
const QString &url() const {return _url;}
|
const QString &url() const {return _url;}
|
||||||
const Authorization &authorization() const {return _authorization;}
|
const QList<HTTPHeader> &headers() const {return _headers;}
|
||||||
const QString &layer() const {return _layer;}
|
const QString &layer() const {return _layer;}
|
||||||
const QString &set() const {return _set;}
|
const QString &set() const {return _set;}
|
||||||
const QString &style() const {return _style;}
|
const QString &style() const {return _style;}
|
||||||
@ -52,7 +52,7 @@ public:
|
|||||||
bool _rest;
|
bool _rest;
|
||||||
CoordinateSystem _cs;
|
CoordinateSystem _cs;
|
||||||
QList<KV<QString, QString> > _dimensions;
|
QList<KV<QString, QString> > _dimensions;
|
||||||
Authorization _authorization;
|
QList<HTTPHeader> _headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Zoom
|
class Zoom
|
||||||
|
@ -20,7 +20,7 @@ WMTSMap::WMTSMap(const QString &fileName, const QString &name,
|
|||||||
QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name));
|
QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name));
|
||||||
|
|
||||||
_tileLoader = new TileLoader(tilesDir, this);
|
_tileLoader = new TileLoader(tilesDir, this);
|
||||||
_tileLoader->setAuthorization(setup.authorization());
|
_tileLoader->setHeaders(setup.headers());
|
||||||
connect(_tileLoader, &TileLoader::finished, this, &WMTSMap::tilesLoaded);
|
connect(_tileLoader, &TileLoader::finished, this, &WMTSMap::tilesLoaded);
|
||||||
|
|
||||||
_wmts = new WMTS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this);
|
_wmts = new WMTS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this);
|
||||||
|
Reference in New Issue
Block a user