mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-01-19 12:12:08 +01:00
Use integers as tag keys in Mapsforge maps
This commit is contained in:
parent
dacaeca71a
commit
ce4f0472c0
@ -15,6 +15,11 @@ using namespace Mapsforge;
|
|||||||
#define MD(val) ((val) / 1e6)
|
#define MD(val) ((val) / 1e6)
|
||||||
#define OFFSET_MASK 0x7FFFFFFFFFL
|
#define OFFSET_MASK 0x7FFFFFFFFFL
|
||||||
|
|
||||||
|
#define KEY_NAME "name"
|
||||||
|
#define KEY_HOUSE "addr:housenumber"
|
||||||
|
#define KEY_REF "ref"
|
||||||
|
#define KEY_ELE "ele"
|
||||||
|
|
||||||
static void copyPaths(const RectC &rect, const QList<MapData::Path> *src,
|
static void copyPaths(const RectC &rect, const QList<MapData::Path> *src,
|
||||||
QList<MapData::Path> *dst)
|
QList<MapData::Path> *dst)
|
||||||
{
|
{
|
||||||
@ -43,65 +48,6 @@ static bool isClosed(const Polygon &poly)
|
|||||||
return (distance(poly.first().first(), poly.first().last()) < 0.000000001);
|
return (distance(poly.first().first(), poly.first().last()) < 0.000000001);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readTags(SubFile &subfile, int count,
|
|
||||||
const QVector<MapData::Tag> &tags, QVector<MapData::Tag> &list)
|
|
||||||
{
|
|
||||||
QVector<quint32> ids(count);
|
|
||||||
|
|
||||||
list.resize(count);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (!subfile.readVUInt32(ids[i]))
|
|
||||||
return false;
|
|
||||||
if (ids[i] >= (quint32)tags.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
const MapData::Tag &tag = tags.at(ids.at(i));
|
|
||||||
|
|
||||||
if (tag.value.length() == 2 && tag.value.at(0) == '%') {
|
|
||||||
QByteArray value;
|
|
||||||
|
|
||||||
if (tag.value.at(1) == 'b') {
|
|
||||||
quint8 b;
|
|
||||||
if (!subfile.readByte(b))
|
|
||||||
return false;
|
|
||||||
value.setNum(b);
|
|
||||||
} else if (tag.value.at(1) == 'i') {
|
|
||||||
qint32 u;
|
|
||||||
if (!subfile.readInt32(u))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (tag.key.contains(":colour"))
|
|
||||||
value = QColor((quint32)u).name().toLatin1();
|
|
||||||
else
|
|
||||||
value.setNum(u);
|
|
||||||
} else if (tag.value.at(1) == 'f') {
|
|
||||||
quint32 u;
|
|
||||||
if (!subfile.readUInt32(u))
|
|
||||||
return false;
|
|
||||||
float *f = (float *)&u;
|
|
||||||
value.setNum(*f);
|
|
||||||
} else if (tag.value.at(1) == 'h') {
|
|
||||||
quint16 s;
|
|
||||||
if (!subfile.readUInt16(s))
|
|
||||||
return false;
|
|
||||||
value.setNum(s);
|
|
||||||
} else if (tag.value.at(1) == 's') {
|
|
||||||
if (!subfile.readString(value))
|
|
||||||
return false;
|
|
||||||
} else
|
|
||||||
value = tag.value;
|
|
||||||
|
|
||||||
list[i] = MapData::Tag(tag.key, value);
|
|
||||||
} else
|
|
||||||
list[i] = tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool readSingleDelta(SubFile &subfile, const Coordinates &c,
|
static bool readSingleDelta(SubFile &subfile, const Coordinates &c,
|
||||||
int count, QVector<Coordinates> &nodes)
|
int count, QVector<Coordinates> &nodes)
|
||||||
{
|
{
|
||||||
@ -204,6 +150,64 @@ static bool readOffset(QDataStream &stream, quint64 &offset)
|
|||||||
return (stream.status() == QDataStream::Ok);
|
return (stream.status() == QDataStream::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MapData::readTags(SubFile &subfile, int count,
|
||||||
|
const QVector<TagSource> &tags, QVector<Tag> &list)
|
||||||
|
{
|
||||||
|
QVector<quint32> ids(count);
|
||||||
|
|
||||||
|
list.resize(count);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!subfile.readVUInt32(ids[i]))
|
||||||
|
return false;
|
||||||
|
if (ids[i] >= (quint32)tags.size())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
const TagSource &tag = tags.at(ids.at(i));
|
||||||
|
|
||||||
|
if (tag.value.length() == 2 && tag.value.at(0) == '%') {
|
||||||
|
QByteArray value;
|
||||||
|
|
||||||
|
if (tag.value.at(1) == 'b') {
|
||||||
|
quint8 b;
|
||||||
|
if (!subfile.readByte(b))
|
||||||
|
return false;
|
||||||
|
value.setNum(b);
|
||||||
|
} else if (tag.value.at(1) == 'i') {
|
||||||
|
qint32 u;
|
||||||
|
if (!subfile.readInt32(u))
|
||||||
|
return false;
|
||||||
|
if (tag.key.contains(":colour"))
|
||||||
|
value = QColor((quint32)u).name().toLatin1();
|
||||||
|
else
|
||||||
|
value.setNum(u);
|
||||||
|
} else if (tag.value.at(1) == 'f') {
|
||||||
|
quint32 u;
|
||||||
|
if (!subfile.readUInt32(u))
|
||||||
|
return false;
|
||||||
|
float *f = (float *)&u;
|
||||||
|
value.setNum(*f);
|
||||||
|
} else if (tag.value.at(1) == 'h') {
|
||||||
|
quint16 s;
|
||||||
|
if (!subfile.readUInt16(s))
|
||||||
|
return false;
|
||||||
|
value.setNum(s);
|
||||||
|
} else if (tag.value.at(1) == 's') {
|
||||||
|
if (!subfile.readString(value))
|
||||||
|
return false;
|
||||||
|
} else
|
||||||
|
value = tag.value;
|
||||||
|
|
||||||
|
list[i] = MapData::Tag(tag.id, value);
|
||||||
|
} else
|
||||||
|
list[i] = MapData::Tag(tag.id, tag.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MapData::readSubFiles()
|
bool MapData::readSubFiles()
|
||||||
{
|
{
|
||||||
QDataStream stream(&_file);
|
QDataStream stream(&_file);
|
||||||
@ -273,34 +277,43 @@ bool MapData::readZoomInfo(SubFile &hdr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readTagInfo(SubFile &hdr)
|
bool MapData::readTagInfo(SubFile &hdr, QVector<TagSource> &tags)
|
||||||
{
|
{
|
||||||
quint16 tags;
|
quint16 size;
|
||||||
QByteArray tag;
|
QByteArray str;
|
||||||
|
|
||||||
if (!hdr.readUInt16(tags))
|
if (!hdr.readUInt16(size))
|
||||||
return false;
|
return false;
|
||||||
_pointTags.resize(tags);
|
tags.resize(size);
|
||||||
for (quint16 i = 0; i < tags; i++) {
|
|
||||||
if (!hdr.readString(tag))
|
|
||||||
return false;
|
|
||||||
_pointTags[i] = tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hdr.readUInt16(tags))
|
for (quint16 i = 0; i < size; i++) {
|
||||||
return false;
|
TagSource &tag = tags[i];
|
||||||
_pathTags.resize(tags);
|
if (!hdr.readString(str))
|
||||||
for (quint16 i = 0; i < tags; i++) {
|
|
||||||
if (!hdr.readString(tag))
|
|
||||||
return false;
|
return false;
|
||||||
_pathTags[i] = tag;
|
tag = str;
|
||||||
|
unsigned key = _keys.value(tag.key);
|
||||||
|
if (key)
|
||||||
|
tag.id = key;
|
||||||
|
else {
|
||||||
|
tag.id = _keys.size() + 1;
|
||||||
|
_keys.insert(tag.key, tag.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readMapInfo(SubFile &hdr, QByteArray &projection,
|
bool MapData::readTagInfo(SubFile &hdr)
|
||||||
bool &debugMap)
|
{
|
||||||
|
_keys.insert(KEY_NAME, ID_NAME);
|
||||||
|
_keys.insert(KEY_HOUSE, ID_HOUSE);
|
||||||
|
_keys.insert(KEY_REF, ID_REF);
|
||||||
|
_keys.insert(KEY_ELE, ID_ELE);
|
||||||
|
|
||||||
|
return (readTagInfo(hdr, _pointTags) && readTagInfo(hdr, _pathTags));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapData::readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap)
|
||||||
{
|
{
|
||||||
quint64 fileSize, date;
|
quint64 fileSize, date;
|
||||||
quint32 version;
|
quint32 version;
|
||||||
@ -592,17 +605,17 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
if (!subfile.readString(name))
|
if (!subfile.readString(name))
|
||||||
return false;
|
return false;
|
||||||
name = name.split('\r').first();
|
name = name.split('\r').first();
|
||||||
p.tags.append(Tag("name", name));
|
p.tags.append(Tag(ID_NAME, name));
|
||||||
}
|
}
|
||||||
if (flags & 0x40) {
|
if (flags & 0x40) {
|
||||||
if (!subfile.readString(houseNumber))
|
if (!subfile.readString(houseNumber))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag("addr:housenumber", houseNumber));
|
p.tags.append(Tag(ID_HOUSE, houseNumber));
|
||||||
}
|
}
|
||||||
if (flags & 0x20) {
|
if (flags & 0x20) {
|
||||||
if (!subfile.readString(reference))
|
if (!subfile.readString(reference))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag("ref", reference));
|
p.tags.append(Tag(ID_REF, reference));
|
||||||
}
|
}
|
||||||
if (flags & 0x10) {
|
if (flags & 0x10) {
|
||||||
if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon)))
|
if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon)))
|
||||||
@ -675,18 +688,18 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
|||||||
if (!subfile.readString(name))
|
if (!subfile.readString(name))
|
||||||
return false;
|
return false;
|
||||||
name = name.split('\r').first();
|
name = name.split('\r').first();
|
||||||
p.tags.append(Tag("name", name));
|
p.tags.append(Tag(ID_NAME, name));
|
||||||
}
|
}
|
||||||
if (flags & 0x40) {
|
if (flags & 0x40) {
|
||||||
if (!subfile.readString(houseNumber))
|
if (!subfile.readString(houseNumber))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag("addr:housenumber", houseNumber));
|
p.tags.append(Tag(ID_HOUSE, houseNumber));
|
||||||
}
|
}
|
||||||
if (flags & 0x20) {
|
if (flags & 0x20) {
|
||||||
qint32 elevation;
|
qint32 elevation;
|
||||||
if (!subfile.readVInt32(elevation))
|
if (!subfile.readVInt32(elevation))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag("ele", QByteArray::number(elevation)));
|
p.tags.append(Tag(ID_ELE, QByteArray::number(elevation)));
|
||||||
}
|
}
|
||||||
|
|
||||||
list->append(p);
|
list->append(p);
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include "common/range.h"
|
#include "common/range.h"
|
||||||
#include "common/polygon.h"
|
#include "common/polygon.h"
|
||||||
|
|
||||||
|
#define ID_NAME 1
|
||||||
|
#define ID_HOUSE 2
|
||||||
|
#define ID_REF 3
|
||||||
|
#define ID_ELE 4
|
||||||
|
|
||||||
namespace Mapsforge {
|
namespace Mapsforge {
|
||||||
|
|
||||||
@ -22,21 +26,12 @@ public:
|
|||||||
|
|
||||||
struct Tag {
|
struct Tag {
|
||||||
Tag() {}
|
Tag() {}
|
||||||
Tag(const QByteArray &key, const QByteArray &value)
|
Tag(unsigned key, const QByteArray &value) : key(key), value(value) {}
|
||||||
: key(key), value(value) {}
|
|
||||||
Tag(const QByteArray &str)
|
|
||||||
{
|
|
||||||
QList<QByteArray> l(str.split('='));
|
|
||||||
if (l.size() == 2) {
|
|
||||||
key = l.at(0);
|
|
||||||
value = l.at(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Tag &other) const
|
bool operator==(const Tag &other) const
|
||||||
{return (key == other.key && value == other.value);}
|
{return (key == other.key && value == other.value);}
|
||||||
|
|
||||||
QByteArray key;
|
unsigned key;
|
||||||
QByteArray value;
|
QByteArray value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +70,7 @@ public:
|
|||||||
|
|
||||||
void points(const RectC &rect, int zoom, QList<Point> *list);
|
void points(const RectC &rect, int zoom, QList<Point> *list);
|
||||||
void paths(const RectC &rect, int zoom, QList<Path> *set);
|
void paths(const RectC &rect, int zoom, QList<Path> *set);
|
||||||
|
unsigned tagId(const QByteArray &name) const {return _keys.value(name);}
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
void clear();
|
void clear();
|
||||||
@ -128,10 +124,27 @@ private:
|
|||||||
int zoom;
|
int zoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TagSource {
|
||||||
|
TagSource() {}
|
||||||
|
TagSource(const QByteArray &str)
|
||||||
|
{
|
||||||
|
QList<QByteArray> l(str.split('='));
|
||||||
|
if (l.size() == 2) {
|
||||||
|
key = l.at(0);
|
||||||
|
value = l.at(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray key;
|
||||||
|
QByteArray value;
|
||||||
|
unsigned id;
|
||||||
|
};
|
||||||
|
|
||||||
typedef RTree<VectorTile *, double, 2> TileTree;
|
typedef RTree<VectorTile *, double, 2> TileTree;
|
||||||
|
|
||||||
bool readZoomInfo(SubFile &hdr);
|
bool readZoomInfo(SubFile &hdr);
|
||||||
bool readTagInfo(SubFile &hdr);
|
bool readTagInfo(SubFile &hdr);
|
||||||
|
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();
|
||||||
bool readSubFiles();
|
bool readSubFiles();
|
||||||
@ -145,6 +158,8 @@ private:
|
|||||||
bool readPaths(const VectorTile *tile, int zoom, QList<Path> *list);
|
bool readPaths(const VectorTile *tile, int zoom, QList<Path> *list);
|
||||||
bool readPoints(const VectorTile *tile, int zoom, QList<Point> *list);
|
bool readPoints(const VectorTile *tile, int zoom, QList<Point> *list);
|
||||||
|
|
||||||
|
static bool readTags(SubFile &subfile, int count,
|
||||||
|
const QVector<TagSource> &tags, QVector<Tag> &list);
|
||||||
static bool pathCb(VectorTile *tile, void *context);
|
static bool pathCb(VectorTile *tile, void *context);
|
||||||
static bool pointCb(VectorTile *tile, void *context);
|
static bool pointCb(VectorTile *tile, void *context);
|
||||||
|
|
||||||
@ -153,9 +168,10 @@ private:
|
|||||||
QFile _file;
|
QFile _file;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
quint16 _tileSize;
|
quint16 _tileSize;
|
||||||
QVector<Tag> _pointTags, _pathTags;
|
|
||||||
QVector<SubFileInfo> _subFiles;
|
QVector<SubFileInfo> _subFiles;
|
||||||
|
QVector<TagSource> _pointTags, _pathTags;
|
||||||
QList<TileTree*> _tiles;
|
QList<TileTree*> _tiles;
|
||||||
|
QHash<QByteArray, unsigned> _keys;
|
||||||
|
|
||||||
QCache<Key, QList<Path> > _pathCache;
|
QCache<Key, QList<Path> > _pathCache;
|
||||||
QCache<Key, QList<Point> > _pointCache;
|
QCache<Key, QList<Point> > _pointCache;
|
||||||
|
@ -5,12 +5,6 @@
|
|||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
|
|
||||||
static const Style& style(qreal ratio)
|
|
||||||
{
|
|
||||||
static Style s(ProgramPaths::renderthemeFile(), ratio);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static qreal area(const QPainterPath &polygon)
|
static qreal area(const QPainterPath &polygon)
|
||||||
{
|
{
|
||||||
qreal area = 0;
|
qreal area = 0;
|
||||||
@ -41,8 +35,7 @@ static QPointF centroid(const QPainterPath &polygon)
|
|||||||
return QPointF(cx * factor, cy * factor);
|
return QPointF(cx * factor, cy * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QByteArray *label(const QByteArray &key,
|
static const QByteArray *label(unsigned key, const QVector<MapData::Tag> &tags)
|
||||||
const QVector<MapData::Tag> &tags)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tags.size(); i++) {
|
for (int i = 0; i < tags.size(); i++) {
|
||||||
const MapData::Tag &tag = tags.at(i);
|
const MapData::Tag &tag = tags.at(i);
|
||||||
@ -61,9 +54,8 @@ static const QColor *haloColor(const Style::TextRender *ti)
|
|||||||
|
|
||||||
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style(_ratio);
|
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
||||||
QList<const Style::TextRender*> labels(s.pointLabels(_zoom));
|
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(s.pointSymbols(_zoom));
|
|
||||||
QList<PainterPoint> points;
|
QList<PainterPoint> points;
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < _points.size(); i++) {
|
||||||
@ -115,9 +107,8 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
|||||||
void RasterTile::processAreaLabels(QList<TextItem*> &textItems,
|
void RasterTile::processAreaLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths)
|
QVector<PainterPath> &paths)
|
||||||
{
|
{
|
||||||
const Style &s = style(_ratio);
|
QList<const Style::TextRender*> labels(_style->areaLabels(_zoom));
|
||||||
QList<const Style::TextRender*> labels(s.areaLabels(_zoom));
|
QList<const Style::Symbol*> symbols(_style->areaSymbols(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(s.areaSymbols(_zoom));
|
|
||||||
|
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
PainterPath &path = paths[i];
|
PainterPath &path = paths[i];
|
||||||
@ -168,8 +159,7 @@ void RasterTile::processAreaLabels(QList<TextItem*> &textItems,
|
|||||||
void RasterTile::processLineLabels(QList<TextItem*> &textItems,
|
void RasterTile::processLineLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths)
|
QVector<PainterPath> &paths)
|
||||||
{
|
{
|
||||||
const Style &s = style(_ratio);
|
QList<const Style::TextRender*> instructions(_style->pathLabels(_zoom));
|
||||||
QList<const Style::TextRender*> instructions(s.pathLabels(_zoom));
|
|
||||||
QSet<QByteArray> set;
|
QSet<QByteArray> set;
|
||||||
|
|
||||||
for (int i = 0; i < instructions.size(); i++) {
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
@ -183,9 +173,7 @@ void RasterTile::processLineLabels(QList<TextItem*> &textItems,
|
|||||||
continue;
|
continue;
|
||||||
if (!ri->rule().match(path.path->closed, path.path->tags))
|
if (!ri->rule().match(path.path->closed, path.path->tags))
|
||||||
continue;
|
continue;
|
||||||
bool limit = (ri->key() == "ref" || ri->key() == "ele"
|
bool limit = (ri->key() == ID_ELE || ri->key() == ID_REF);
|
||||||
|| ri->key() == "ref_hike" || ri->key() == "ref_cycle"
|
|
||||||
|| ri->key() == "ref_mtb");
|
|
||||||
if (limit && set.contains(*lbl))
|
if (limit && set.contains(*lbl))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -242,7 +230,6 @@ void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
|||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
||||||
const Style &s = style(_ratio);
|
|
||||||
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++) {
|
||||||
@ -253,8 +240,8 @@ void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
|||||||
rp.path = &path;
|
rp.path = &path;
|
||||||
|
|
||||||
if (!(ri = cache.object(key))) {
|
if (!(ri = cache.object(key))) {
|
||||||
ri = new QList<const Style::PathRender*>(s.paths(_zoom, path.closed,
|
ri = new QList<const Style::PathRender*>(_style->paths(_zoom,
|
||||||
path.tags));
|
path.closed, path.tags));
|
||||||
for (int j = 0; j < ri->size(); j++)
|
for (int j = 0; j < ri->size(); j++)
|
||||||
instructions.append(RenderInstruction(ri->at(j), &rp));
|
instructions.append(RenderInstruction(ri->at(j), &rp));
|
||||||
cache.insert(key, ri);
|
cache.insert(key, ri);
|
||||||
@ -269,7 +256,6 @@ void RasterTile::circleInstructions(
|
|||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
||||||
const Style &s = style(_ratio);
|
|
||||||
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++) {
|
||||||
@ -277,7 +263,8 @@ void RasterTile::circleInstructions(
|
|||||||
PointKey key(_zoom, point.tags);
|
PointKey key(_zoom, point.tags);
|
||||||
|
|
||||||
if (!(ri = cache.object(key))) {
|
if (!(ri = cache.object(key))) {
|
||||||
ri = new QList<const Style::CircleRender*>(s.circles(_zoom, point.tags));
|
ri = new QList<const Style::CircleRender*>(_style->circles(_zoom,
|
||||||
|
point.tags));
|
||||||
for (int j = 0; j < ri->size(); j++)
|
for (int j = 0; j < ri->size(); j++)
|
||||||
instructions.append(RenderInstruction(ri->at(j), &point));
|
instructions.append(RenderInstruction(ri->at(j), &point));
|
||||||
cache.insert(key, ri);
|
cache.insert(key, ri);
|
||||||
|
@ -14,12 +14,12 @@ namespace Mapsforge {
|
|||||||
class RasterTile
|
class RasterTile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform, int zoom,
|
RasterTile(const Projection &proj, const Transform &transform,
|
||||||
const QRect &rect, qreal ratio, const QList<MapData::Path> &paths,
|
const Style *style, int zoom, const QRect &rect, qreal ratio,
|
||||||
const QList<MapData::Point> &points) : _proj(proj), _transform(transform),
|
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
|
||||||
_zoom(zoom), _rect(rect), _ratio(ratio),
|
: _proj(proj), _transform(transform), _style(style),
|
||||||
_pixmap(rect.width() * ratio, rect.height() * ratio), _paths(paths),
|
_zoom(zoom), _rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio,
|
||||||
_points(points), _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();}
|
||||||
@ -159,8 +159,10 @@ private:
|
|||||||
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, QVector<PainterPath> &paths);
|
||||||
|
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
|
const Style *_style;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
#include "common/programpaths.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
@ -37,6 +38,48 @@ static QImage image(const QString &path, int width, int height, qreal ratio)
|
|||||||
return QImage(path);
|
return QImage(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QList<unsigned> keyList(const MapData &data, const QList<QByteArray> &in)
|
||||||
|
{
|
||||||
|
QList<unsigned> out;
|
||||||
|
|
||||||
|
for (int i = 0; i < in.size(); i++) {
|
||||||
|
if (in.at(i) == "*")
|
||||||
|
out.append(0);
|
||||||
|
else {
|
||||||
|
unsigned key = data.tagId(in.at(i));
|
||||||
|
if (key)
|
||||||
|
out.append(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<QByteArray> valList(const QList<QByteArray> &in)
|
||||||
|
{
|
||||||
|
QList<QByteArray> out;
|
||||||
|
|
||||||
|
for (int i = 0; i < in.size(); i++) {
|
||||||
|
if (in.at(i) == "*")
|
||||||
|
out.append(QByteArray());
|
||||||
|
else
|
||||||
|
out.append(in.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Style::Rule::Filter::Filter(const MapData &data, const QList<QByteArray> &keys,
|
||||||
|
const QList<QByteArray> &vals) : _neg(false)
|
||||||
|
{
|
||||||
|
_keys = keyList(data, keys);
|
||||||
|
|
||||||
|
QList<QByteArray> vc(vals);
|
||||||
|
if (vc.removeAll("~"))
|
||||||
|
_neg = true;
|
||||||
|
_vals = valList(vc);
|
||||||
|
}
|
||||||
|
|
||||||
bool Style::Rule::match(const QVector<MapData::Tag> &tags) const
|
bool Style::Rule::match(const QVector<MapData::Tag> &tags) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _filters.size(); i++)
|
for (int i = 0; i < _filters.size(); i++)
|
||||||
@ -237,7 +280,7 @@ void Style::circle(QXmlStreamReader &reader, const Rule &rule)
|
|||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::text(QXmlStreamReader &reader, const Rule &rule,
|
void Style::text(QXmlStreamReader &reader, const MapData &data, const Rule &rule,
|
||||||
QList<QList<TextRender>*> &lists)
|
QList<QList<TextRender>*> &lists)
|
||||||
{
|
{
|
||||||
TextRender ri(rule);
|
TextRender ri(rule);
|
||||||
@ -249,7 +292,7 @@ void Style::text(QXmlStreamReader &reader, const Rule &rule,
|
|||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
if (attr.hasAttribute("k"))
|
if (attr.hasAttribute("k"))
|
||||||
ri._key = attr.value("k").toLatin1();
|
ri._key = data.tagId(attr.value("k").toLatin1());
|
||||||
if (attr.hasAttribute("fill"))
|
if (attr.hasAttribute("fill"))
|
||||||
ri._fillColor = QColor(attr.value("fill").toString());
|
ri._fillColor = QColor(attr.value("fill").toString());
|
||||||
if (attr.hasAttribute("stroke"))
|
if (attr.hasAttribute("stroke"))
|
||||||
@ -357,8 +400,9 @@ void Style::symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
|||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::rule(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
void Style::rule(QXmlStreamReader &reader, const QString &dir,
|
||||||
const QSet<QString> &cats, const Rule &parent)
|
const MapData &data, qreal ratio, const QSet<QString> &cats,
|
||||||
|
const Rule &parent)
|
||||||
{
|
{
|
||||||
Rule r(parent);
|
Rule r(parent);
|
||||||
const QXmlStreamAttributes &attr = reader.attributes();
|
const QXmlStreamAttributes &attr = reader.attributes();
|
||||||
@ -399,11 +443,11 @@ void Style::rule(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
|||||||
|
|
||||||
QList<QByteArray> keys(attr.value("k").toLatin1().split('|'));
|
QList<QByteArray> keys(attr.value("k").toLatin1().split('|'));
|
||||||
QList<QByteArray> vals(attr.value("v").toLatin1().split('|'));
|
QList<QByteArray> vals(attr.value("v").toLatin1().split('|'));
|
||||||
r.addFilter(Rule::Filter(keys, vals));
|
r.addFilter(Rule::Filter(data, keys, vals));
|
||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("rule"))
|
if (reader.name() == QLatin1String("rule"))
|
||||||
rule(reader, dir, ratio, cats, r);
|
rule(reader, dir, data, ratio, cats, r);
|
||||||
else if (reader.name() == QLatin1String("area"))
|
else if (reader.name() == QLatin1String("area"))
|
||||||
area(reader, dir, ratio, r);
|
area(reader, dir, ratio, r);
|
||||||
else if (reader.name() == QLatin1String("line"))
|
else if (reader.name() == QLatin1String("line"))
|
||||||
@ -413,14 +457,14 @@ void Style::rule(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
|||||||
else if (reader.name() == QLatin1String("pathText")) {
|
else if (reader.name() == QLatin1String("pathText")) {
|
||||||
QList<QList<TextRender>*> list;
|
QList<QList<TextRender>*> list;
|
||||||
list.append(&_pathLabels);
|
list.append(&_pathLabels);
|
||||||
text(reader, r, list);
|
text(reader, data, r, list);
|
||||||
} else if (reader.name() == QLatin1String("caption")) {
|
} else if (reader.name() == QLatin1String("caption")) {
|
||||||
QList<QList<TextRender>*> list;
|
QList<QList<TextRender>*> list;
|
||||||
if (r._type == Rule::WayType || r._type == Rule::AnyType)
|
if (r._type == Rule::WayType || r._type == Rule::AnyType)
|
||||||
list.append(&_areaLabels);
|
list.append(&_areaLabels);
|
||||||
if (r._type == Rule::NodeType || r._type == Rule::AnyType)
|
if (r._type == Rule::NodeType || r._type == Rule::AnyType)
|
||||||
list.append(&_pointLabels);
|
list.append(&_pointLabels);
|
||||||
text(reader, r, list);
|
text(reader, data, r, list);
|
||||||
}
|
}
|
||||||
else if (reader.name() == QLatin1String("symbol"))
|
else if (reader.name() == QLatin1String("symbol"))
|
||||||
symbol(reader, dir, ratio, r);
|
symbol(reader, dir, ratio, r);
|
||||||
@ -462,14 +506,14 @@ void Style::stylemenu(QXmlStreamReader &reader, QSet<QString> &cats)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
|
void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
|
||||||
qreal ratio)
|
const MapData &data, qreal ratio)
|
||||||
{
|
{
|
||||||
Rule r;
|
Rule r;
|
||||||
QSet<QString> cats;
|
QSet<QString> cats;
|
||||||
|
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("rule"))
|
if (reader.name() == QLatin1String("rule"))
|
||||||
rule(reader, dir, ratio, cats, r);
|
rule(reader, dir, data, ratio, cats, r);
|
||||||
else if (reader.name() == QLatin1String("stylemenu"))
|
else if (reader.name() == QLatin1String("stylemenu"))
|
||||||
stylemenu(reader, cats);
|
stylemenu(reader, cats);
|
||||||
else
|
else
|
||||||
@ -477,7 +521,7 @@ void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Style::loadXml(const QString &path, qreal ratio)
|
bool Style::loadXml(const QString &path, const MapData &data, qreal ratio)
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (!file.open(QFile::ReadOnly))
|
if (!file.open(QFile::ReadOnly))
|
||||||
@ -487,7 +531,7 @@ bool Style::loadXml(const QString &path, qreal ratio)
|
|||||||
|
|
||||||
if (reader.readNextStartElement()) {
|
if (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("rendertheme"))
|
if (reader.name() == QLatin1String("rendertheme"))
|
||||||
rendertheme(reader, fi.absolutePath(), ratio);
|
rendertheme(reader, fi.absolutePath(), data, ratio);
|
||||||
else
|
else
|
||||||
reader.raiseError("Not a Mapsforge style file");
|
reader.raiseError("Not a Mapsforge style file");
|
||||||
}
|
}
|
||||||
@ -499,10 +543,22 @@ bool Style::loadXml(const QString &path, qreal ratio)
|
|||||||
return !reader.error();
|
return !reader.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
Style::Style(const QString &path, qreal ratio)
|
void Style::load(const MapData &data, qreal ratio)
|
||||||
{
|
{
|
||||||
if (!QFileInfo::exists(path) || !loadXml(path, ratio))
|
QString path(ProgramPaths::renderthemeFile());
|
||||||
loadXml(":/mapsforge/default.xml", ratio);
|
|
||||||
|
if (!QFileInfo::exists(path) || !loadXml(path, data, ratio))
|
||||||
|
loadXml(":/mapsforge/default.xml", data, ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Style::clear()
|
||||||
|
{
|
||||||
|
_paths.clear();
|
||||||
|
_circles.clear();
|
||||||
|
_pathLabels.clear();
|
||||||
|
_pointLabels.clear();
|
||||||
|
_areaLabels.clear();
|
||||||
|
_symbols.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<const Style::PathRender *> Style::paths(int zoom, bool closed,
|
QList<const Style::PathRender *> Style::paths(int zoom, bool closed,
|
||||||
|
@ -53,16 +53,8 @@ public:
|
|||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
Filter() : _neg(false) {}
|
Filter() : _neg(false) {}
|
||||||
Filter(const QList<QByteArray> &keys, const QList<QByteArray> &vals)
|
Filter(const MapData &data, const QList<QByteArray> &keys,
|
||||||
: _neg(false)
|
const QList<QByteArray> &vals);
|
||||||
{
|
|
||||||
_keys = list(keys);
|
|
||||||
|
|
||||||
QList<QByteArray> vc(vals);
|
|
||||||
if (vc.removeAll("~"))
|
|
||||||
_neg = true;
|
|
||||||
_vals = list(vc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool match(const QVector<MapData::Tag> &tags) const
|
bool match(const QVector<MapData::Tag> &tags) const
|
||||||
{
|
{
|
||||||
@ -76,30 +68,15 @@ public:
|
|||||||
|
|
||||||
bool isTautology() const
|
bool isTautology() const
|
||||||
{
|
{
|
||||||
return (!_neg && _keys.contains(QByteArray())
|
return (!_neg && _keys.contains(0u) && _vals.contains(QByteArray()));
|
||||||
&& _vals.contains(QByteArray()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QList<QByteArray> list(const QList<QByteArray> &in)
|
|
||||||
{
|
|
||||||
QList<QByteArray> out;
|
|
||||||
|
|
||||||
for (int i = 0; i < in.size(); i++) {
|
|
||||||
if (in.at(i) == "*")
|
|
||||||
out.append(QByteArray());
|
|
||||||
else
|
|
||||||
out.append(in.at(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyMatches(const QVector<MapData::Tag> &tags) const
|
bool keyMatches(const QVector<MapData::Tag> &tags) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _keys.size(); i++)
|
for (int i = 0; i < _keys.size(); i++)
|
||||||
for (int j = 0; j < tags.size(); j++)
|
for (int j = 0; j < tags.size(); j++)
|
||||||
if (wcmp(_keys.at(i), tags.at(j).key))
|
if (!_keys.at(i) || _keys.at(i) == tags.at(j).key)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -115,7 +92,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> _keys;
|
QList<unsigned> _keys;
|
||||||
QList<QByteArray> _vals;
|
QList<QByteArray> _vals;
|
||||||
bool _neg;
|
bool _neg;
|
||||||
};
|
};
|
||||||
@ -218,7 +195,7 @@ public:
|
|||||||
const QColor &fillColor() const {return _fillColor;}
|
const QColor &fillColor() const {return _fillColor;}
|
||||||
const QColor &strokeColor() const {return _strokeColor;}
|
const QColor &strokeColor() const {return _strokeColor;}
|
||||||
qreal strokeWidth() const {return _strokeWidth;}
|
qreal strokeWidth() const {return _strokeWidth;}
|
||||||
const QByteArray &key() const {return _key;}
|
unsigned key() const {return _key;}
|
||||||
int priority() const {return _priority;}
|
int priority() const {return _priority;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -228,7 +205,7 @@ public:
|
|||||||
QColor _fillColor, _strokeColor;
|
QColor _fillColor, _strokeColor;
|
||||||
qreal _strokeWidth;
|
qreal _strokeWidth;
|
||||||
QFont _font;
|
QFont _font;
|
||||||
QByteArray _key;
|
unsigned _key;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Symbol : public Render
|
class Symbol : public Render
|
||||||
@ -246,7 +223,8 @@ public:
|
|||||||
QImage _img;
|
QImage _img;
|
||||||
};
|
};
|
||||||
|
|
||||||
Style(const QString &path, qreal ratio);
|
void load(const MapData &data, qreal ratio);
|
||||||
|
void clear();
|
||||||
|
|
||||||
QList<const PathRender *> paths(int zoom, bool closed,
|
QList<const PathRender *> paths(int zoom, bool closed,
|
||||||
const QVector<MapData::Tag> &tags) const;
|
const QVector<MapData::Tag> &tags) const;
|
||||||
@ -264,18 +242,19 @@ private:
|
|||||||
QList<TextRender> _pathLabels, _pointLabels, _areaLabels;
|
QList<TextRender> _pathLabels, _pointLabels, _areaLabels;
|
||||||
QList<Symbol> _symbols;
|
QList<Symbol> _symbols;
|
||||||
|
|
||||||
bool loadXml(const QString &path, qreal ratio);
|
bool loadXml(const QString &path, const MapData &data, qreal ratio);
|
||||||
void rendertheme(QXmlStreamReader &reader, const QString &dir, qreal ratio);
|
void rendertheme(QXmlStreamReader &reader, const QString &dir,
|
||||||
|
const MapData &data, qreal ratio);
|
||||||
void layer(QXmlStreamReader &reader, QSet<QString> &cats);
|
void layer(QXmlStreamReader &reader, QSet<QString> &cats);
|
||||||
void stylemenu(QXmlStreamReader &reader, QSet<QString> &cats);
|
void stylemenu(QXmlStreamReader &reader, QSet<QString> &cats);
|
||||||
void cat(QXmlStreamReader &reader, QSet<QString> &cats);
|
void cat(QXmlStreamReader &reader, QSet<QString> &cats);
|
||||||
void rule(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
void rule(QXmlStreamReader &reader, const QString &dir, const MapData &data,
|
||||||
const QSet<QString> &cats, const Rule &parent);
|
qreal ratio, const QSet<QString> &cats, const Rule &parent);
|
||||||
void area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
void area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
||||||
const Rule &rule);
|
const Rule &rule);
|
||||||
void line(QXmlStreamReader &reader, const Rule &rule);
|
void line(QXmlStreamReader &reader, const Rule &rule);
|
||||||
void circle(QXmlStreamReader &reader, const Rule &rule);
|
void circle(QXmlStreamReader &reader, const Rule &rule);
|
||||||
void text(QXmlStreamReader &reader, const Rule &rule,
|
void text(QXmlStreamReader &reader, const MapData &data, const Rule &rule,
|
||||||
QList<QList<TextRender> *> &lists);
|
QList<QList<TextRender> *> &lists);
|
||||||
void symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
void symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
||||||
const Rule &rule);
|
const Rule &rule);
|
||||||
|
@ -24,11 +24,15 @@ MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
|||||||
void MapsforgeMap::load()
|
void MapsforgeMap::load()
|
||||||
{
|
{
|
||||||
_data.load();
|
_data.load();
|
||||||
|
_style.load(_data, _tileRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapsforgeMap::unload()
|
void MapsforgeMap::unload()
|
||||||
{
|
{
|
||||||
|
cancelJobs(true);
|
||||||
|
|
||||||
_data.clear();
|
_data.clear();
|
||||||
|
_style.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MapsforgeMap::zoomFit(const QSize &size, const RectC &rect)
|
int MapsforgeMap::zoomFit(const QSize &size, const RectC &rect)
|
||||||
@ -54,7 +58,7 @@ int MapsforgeMap::zoomFit(const QSize &size, const RectC &rect)
|
|||||||
|
|
||||||
int MapsforgeMap::zoomIn()
|
int MapsforgeMap::zoomIn()
|
||||||
{
|
{
|
||||||
cancelJobs();
|
cancelJobs(false);
|
||||||
|
|
||||||
_zoom = qMin(_zoom + 1, _data.zooms().max());
|
_zoom = qMin(_zoom + 1, _data.zooms().max());
|
||||||
updateTransform();
|
updateTransform();
|
||||||
@ -63,7 +67,7 @@ int MapsforgeMap::zoomIn()
|
|||||||
|
|
||||||
int MapsforgeMap::zoomOut()
|
int MapsforgeMap::zoomOut()
|
||||||
{
|
{
|
||||||
cancelJobs();
|
cancelJobs(false);
|
||||||
|
|
||||||
_zoom = qMax(_zoom - 1, _data.zooms().min());
|
_zoom = qMax(_zoom - 1, _data.zooms().min());
|
||||||
updateTransform();
|
updateTransform();
|
||||||
@ -148,10 +152,10 @@ void MapsforgeMap::jobFinished(MapsforgeMapJob *job)
|
|||||||
emit tilesLoaded();
|
emit tilesLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapsforgeMap::cancelJobs()
|
void MapsforgeMap::cancelJobs(bool wait)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _jobs.size(); i++)
|
for (int i = 0; i < _jobs.size(); i++)
|
||||||
_jobs.at(i)->cancel();
|
_jobs.at(i)->cancel(wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||||
@ -198,7 +202,7 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
_data.points(pointRectD.toRectC(_projection, 20), _zoom,
|
_data.points(pointRectD.toRectC(_projection, 20), _zoom,
|
||||||
&points);
|
&points);
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, _zoom,
|
tiles.append(RasterTile(_projection, _transform, &_style, _zoom,
|
||||||
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||||
_tileRatio, paths, points));
|
_tileRatio, paths, points));
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,12 @@ public:
|
|||||||
_future = QtConcurrent::map(_tiles, &Mapsforge::RasterTile::render);
|
_future = QtConcurrent::map(_tiles, &Mapsforge::RasterTile::render);
|
||||||
_watcher.setFuture(_future);
|
_watcher.setFuture(_future);
|
||||||
}
|
}
|
||||||
void cancel() {_future.cancel();}
|
void cancel(bool wait)
|
||||||
|
{
|
||||||
|
_future.cancel();
|
||||||
|
if (wait)
|
||||||
|
_future.waitForFinished();
|
||||||
|
}
|
||||||
const QList<Mapsforge::RasterTile> &tiles() const {return _tiles;}
|
const QList<Mapsforge::RasterTile> &tiles() const {return _tiles;}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@ -82,9 +87,10 @@ private:
|
|||||||
bool isRunning(int zoom, const QPoint &xy) const;
|
bool isRunning(int zoom, const QPoint &xy) const;
|
||||||
void runJob(MapsforgeMapJob *job);
|
void runJob(MapsforgeMapJob *job);
|
||||||
void removeJob(MapsforgeMapJob *job);
|
void removeJob(MapsforgeMapJob *job);
|
||||||
void cancelJobs();
|
void cancelJobs(bool wait);
|
||||||
|
|
||||||
Mapsforge::MapData _data;
|
Mapsforge::MapData _data;
|
||||||
|
Mapsforge::Style _style;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
|
|
||||||
Projection _projection;
|
Projection _projection;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user