2021-04-10 15:27:40 +02:00
|
|
|
#ifndef MAPSFORGE_MAPDATA_H
|
|
|
|
#define MAPSFORGE_MAPDATA_H
|
|
|
|
|
|
|
|
#include <QFile>
|
|
|
|
#include <QCache>
|
|
|
|
#include <QPainterPath>
|
|
|
|
#include "common/config.h"
|
|
|
|
#include "common/rectc.h"
|
|
|
|
#include "common/rtree.h"
|
|
|
|
#include "common/range.h"
|
|
|
|
#include "common/polygon.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Mapsforge {
|
|
|
|
|
|
|
|
class MapData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MapData(const QString &path);
|
|
|
|
~MapData();
|
|
|
|
|
|
|
|
struct Tag {
|
|
|
|
Tag() {}
|
|
|
|
Tag(const QByteArray &key, const QByteArray &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
|
2021-04-10 15:49:48 +02:00
|
|
|
{return (key == other.key && value == other.value);}
|
2021-04-10 15:27:40 +02:00
|
|
|
|
|
|
|
QByteArray key;
|
|
|
|
QByteArray value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Point {
|
|
|
|
Point(const Coordinates &c) : coordinates(c) {}
|
|
|
|
|
|
|
|
Coordinates coordinates;
|
|
|
|
QString label;
|
|
|
|
QVector<Tag> tags;
|
|
|
|
int layer;
|
|
|
|
quint64 id;
|
|
|
|
|
|
|
|
bool operator<(const Point &other) const
|
|
|
|
{return id > other.id;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Path {
|
|
|
|
Polygon poly;
|
|
|
|
QString label;
|
|
|
|
QString reference;
|
|
|
|
QVector<Tag> tags;
|
2021-04-11 11:37:43 +02:00
|
|
|
Coordinates labelPos;
|
2021-04-10 15:27:40 +02:00
|
|
|
int layer;
|
|
|
|
bool closed;
|
|
|
|
|
|
|
|
QPainterPath path;
|
|
|
|
|
|
|
|
bool operator<(const Path &other) const
|
|
|
|
{return layer < other.layer;}
|
|
|
|
};
|
|
|
|
|
|
|
|
RectC bounds() const;
|
|
|
|
Range zooms() const
|
|
|
|
{return Range(_subFiles.first().min, _subFiles.last().max);}
|
|
|
|
int tileSize() const {return _tileSize;}
|
|
|
|
|
|
|
|
void points(const RectC &rect, int zoom, QList<Point> *list);
|
|
|
|
void paths(const RectC &rect, int zoom, QList<Path> *list);
|
|
|
|
|
|
|
|
void load();
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
bool isValid() const {return _valid;}
|
|
|
|
QString errorString() const {return _errorString;}
|
|
|
|
|
|
|
|
static bool isMapsforge(const QString &path);
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct SubFileInfo {
|
|
|
|
quint8 base;
|
|
|
|
quint8 min;
|
|
|
|
quint8 max;
|
|
|
|
quint64 offset;
|
|
|
|
quint64 size;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VectorTile {
|
|
|
|
VectorTile(size_t offset, const RectC &rect)
|
|
|
|
: offset(offset), pos(rect.topLeft()) {}
|
|
|
|
|
|
|
|
size_t offset;
|
|
|
|
Coordinates pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PathCTX {
|
|
|
|
PathCTX(MapData *data, const RectC &rect, int zoom, QList<Path> *list)
|
|
|
|
: data(data), rect(rect), zoom(zoom), list(list) {}
|
|
|
|
|
|
|
|
MapData *data;
|
|
|
|
const RectC ▭
|
|
|
|
int zoom;
|
|
|
|
QList<Path> *list;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PointCTX {
|
|
|
|
PointCTX(MapData *data, const RectC &rect, int zoom, QList<Point> *list)
|
|
|
|
: data(data), rect(rect), zoom(zoom), list(list) {}
|
|
|
|
|
|
|
|
MapData *data;
|
|
|
|
const RectC ▭
|
|
|
|
int zoom;
|
|
|
|
QList<Point> *list;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Key {
|
|
|
|
Key(const VectorTile *tile, int zoom) : tile(tile), zoom(zoom) {}
|
|
|
|
bool operator==(const Key &other) const
|
|
|
|
{return tile == other.tile && zoom == other.zoom;}
|
|
|
|
|
|
|
|
const VectorTile *tile;
|
|
|
|
int zoom;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef RTree<VectorTile *, double, 2> TileTree;
|
|
|
|
|
|
|
|
bool readHeader();
|
|
|
|
bool readSubFiles();
|
|
|
|
void clearTiles();
|
|
|
|
|
|
|
|
int level(int zoom) const;
|
|
|
|
void paths(const VectorTile *tile, const RectC &rect, int zoom,
|
|
|
|
QList<Path> *list);
|
|
|
|
void points(const VectorTile *tile, const RectC &rect, int zoom,
|
|
|
|
QList<Point> *list);
|
|
|
|
bool readPaths(const VectorTile *tile, int zoom, QList<Path> *list);
|
|
|
|
bool readPoints(const VectorTile *tile, int zoom, QList<Point> *list);
|
|
|
|
|
|
|
|
static bool pathCb(VectorTile *tile, void *context);
|
|
|
|
static bool pointCb(VectorTile *tile, void *context);
|
|
|
|
|
|
|
|
friend HASH_T qHash(const MapData::Key &key);
|
|
|
|
|
|
|
|
QFile _file;
|
|
|
|
RectC _bounds;
|
|
|
|
quint16 _tileSize;
|
|
|
|
QVector<Tag> _pointTags, _pathTags;
|
|
|
|
QVector<SubFileInfo> _subFiles;
|
|
|
|
QList<TileTree*> _tiles;
|
|
|
|
|
|
|
|
QCache<Key, QList<Path> > _pathCache;
|
|
|
|
QCache<Key, QList<Point> > _pointCache;
|
|
|
|
|
|
|
|
bool _valid;
|
|
|
|
QString _errorString;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline HASH_T qHash(const MapData::Key &key)
|
|
|
|
{
|
|
|
|
return ::qHash(key.tile) ^ ::qHash(key.zoom);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline HASH_T qHash(const MapData::Tag &tag)
|
|
|
|
{
|
|
|
|
return ::qHash(tag.key) ^ ::qHash(tag.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG
|
|
|
|
QDebug operator<<(QDebug dbg, const Mapsforge::MapData::Tag &tag);
|
|
|
|
QDebug operator<<(QDebug dbg, const Mapsforge::MapData::Path &path);
|
|
|
|
QDebug operator<<(QDebug dbg, const Mapsforge::MapData::Point &point);
|
|
|
|
#endif // QT_NO_DEBUG
|
|
|
|
|
|
|
|
#endif // MAPSFORGE_MAPDATA_H
|