94 lines
2.2 KiB
C++
Raw Normal View History

2018-10-29 00:11:23 +01:00
#include "pbf.h"
#define MOVE_TO 1
#define LINE_TO 2
#define CLOSE_PATH 7
2019-01-01 21:27:07 +01:00
static inline qint32 zigzag32decode(quint32 value)
{
return static_cast<qint32>((value >> 1u) ^ static_cast<quint32>(
-static_cast<qint32>(value & 1u)));
}
static inline QPoint parameters(quint32 v1, quint32 v2)
{
return QPoint(zigzag32decode(v1), zigzag32decode(v2));
}
const QVariant *PBF::Feature::value(const QByteArray &key) const
{
2019-01-01 21:27:07 +01:00
const KeyHash &keys(_layer->keys());
KeyHash::const_iterator it(keys.find(key));
if (it == keys.constEnd())
return 0;
2025-01-06 09:19:36 +01:00
quint32 index = *it;
for (int i = 0; i < _data->tags.size(); i = i + 2)
if (_data->tags.at(i) == index)
return &(_layer->values().at(_data->tags.at(i+1)));
2019-01-01 21:27:07 +01:00
return 0;
}
2019-01-01 21:27:07 +01:00
QPainterPath PBF::Feature::path(const QSizeF &factor) const
{
2018-10-29 00:11:23 +01:00
QPoint cursor;
QPainterPath path;
2025-01-06 09:19:36 +01:00
for (int i = 0; i < _data->geometry.size(); i++) {
quint32 g = _data->geometry.at(i);
2018-10-29 00:11:23 +01:00
unsigned cmdId = g & 0x7;
unsigned cmdCount = g >> 3;
if (cmdId == MOVE_TO) {
for (unsigned j = 0; j < cmdCount; j++) {
2025-01-06 09:19:36 +01:00
QPoint offset = parameters(_data->geometry.at(i+1),
_data->geometry.at(i+2));
2018-10-29 00:11:23 +01:00
i += 2;
cursor += offset;
path.moveTo(QPointF(cursor.x() * factor.width(),
cursor.y() * factor.height()));
2018-10-29 00:11:23 +01:00
}
} else if (cmdId == LINE_TO) {
for (unsigned j = 0; j < cmdCount; j++) {
2025-01-06 09:19:36 +01:00
QPoint offset = parameters(_data->geometry.at(i+1),
_data->geometry.at(i+2));
2018-10-29 00:11:23 +01:00
i += 2;
cursor += offset;
path.lineTo(QPointF(cursor.x() * factor.width(),
cursor.y() * factor.height()));
2018-10-29 00:11:23 +01:00
}
} else if (cmdId == CLOSE_PATH) {
path.closeSubpath();
path.moveTo(cursor);
}
}
2019-01-01 21:27:07 +01:00
return path;
2018-10-29 00:11:23 +01:00
}
2025-01-06 09:19:36 +01:00
PBF::Layer::Layer(const Data::Layer *layer) : _data(layer)
2018-10-29 00:11:23 +01:00
{
2025-01-06 09:19:36 +01:00
_keys.reserve(layer->keys.size());
for (int i = 0; i < layer->keys.size(); i++)
_keys.insert(layer->keys.at(i), i);
2019-01-01 21:27:07 +01:00
2025-01-06 09:19:36 +01:00
_features.reserve(layer->features.size());
for (int i = 0; i < layer->features.size(); i++)
_features.append(Feature(&(layer->features.at(i)), this));
std::sort(_features.begin(), _features.end());
2018-10-29 00:11:23 +01:00
}
2025-01-06 09:19:36 +01:00
PBF::PBF(const Data &data)
2018-10-29 00:11:23 +01:00
{
2025-01-06 09:19:36 +01:00
for (int i = 0; i < data.layers().size(); i++) {
const Data::Layer &layer = data.layers().at(i);
_layers.insert(layer.name, new Layer(&layer));
2018-10-29 00:11:23 +01:00
}
2019-01-01 21:27:07 +01:00
}
2018-10-29 00:11:23 +01:00
2019-01-01 21:27:07 +01:00
PBF::~PBF()
{
2020-07-01 20:48:37 +02:00
qDeleteAll(_layers);
2018-10-29 00:11:23 +01:00
}