Removed Google protobuf dependency

This commit is contained in:
Martin Tůma 2025-01-06 09:19:36 +01:00
parent caf0a29b74
commit 3287e54411
13 changed files with 405 additions and 232 deletions

View File

@ -1,4 +1,4 @@
version: 3.2.{build} version: 4.0.{build}
configuration: configuration:
- Release - Release
@ -14,16 +14,14 @@ environment:
install: install:
- cmd: |- - cmd: |-
set PATH=%QTDIR%\bin;%VCPKGDIR%\tools\protobuf;%PATH% set PATH=%QTDIR%\bin;%PATH%
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
vcpkg install pkgconf:x64-windows-static-md-release
vcpkg install protobuf:x64-windows-static-md-release
vcpkg install zlib:x64-windows-static-md-release vcpkg install zlib:x64-windows-static-md-release
copy /y %VCPKGDIR%\lib\zlib.lib %VCPKGDIR%\lib\zlibstatic.lib copy /y %VCPKGDIR%\lib\zlib.lib %VCPKGDIR%\lib\zlibstatic.lib
build_script: build_script:
- cmd: |- - cmd: |-
qmake USE_PKGCONFIG=true pbfplugin.pro qmake ZLIB=%VCPKGDIR% pbfplugin.pro
nmake release nmake release
artifacts: artifacts:

View File

@ -12,10 +12,6 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install protobuf compiler
run: |
sudo apt-get update
sudo apt-get install protobuf-compiler
- name: set up JDK 11 - name: set up JDK 11
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
@ -41,10 +37,8 @@ jobs:
version: '6.4.0' version: '6.4.0'
target: 'android' target: 'android'
arch: 'android_arm64_v8a' arch: 'android_arm64_v8a'
- name: Install Android Google Protocol Buffers
run: git clone https://github.com/tumic0/android_protobuf.git
- name: Configure build - name: Configure build
run: qmake pbfplugin.pro PROTOBUF=android_protobuf run: qmake pbfplugin.pro
- name: Build project - name: Build project
run: make -j2 run: make -j2
- name: Upload artifacts - name: Upload artifacts

View File

@ -15,7 +15,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install qtbase5-dev qtbase5-dev-tools qt5-qmake libprotobuf-dev protobuf-compiler zlib1g-dev sudo apt-get install qtbase5-dev qtbase5-dev-tools qt5-qmake zlib1g-dev
- name: Configure build - name: Configure build
run: qmake pbfplugin.pro run: qmake pbfplugin.pro
- name: Build project - name: Build project

View File

@ -6,36 +6,22 @@ on:
- master - master
jobs: jobs:
qt5: build:
name: QtPBFImagePlugin Qt5 build name: QtPBFImagePlugin
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Set environment variables
run: echo "PATH=/opt/homebrew/opt/qt@5/bin:/opt/homebrew/opt/protobuf@21/bin:$PATH" >> $GITHUB_ENV
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install dependencies - name: Install Qt
run: | uses: jurplel/install-qt-action@v4
brew update with:
brew install qt@5 protobuf@21 version: '6.8.1'
- name: Configure build - name: Configure build
run: qmake PROTOBUF=/opt/homebrew/opt/protobuf@21 pbfplugin.pro run: qmake pbfplugin.pro QMAKE_APPLE_DEVICE_ARCHS="x86_64h arm64"
- name: Build project
run: make -j3
qt6:
name: QtPBFImagePlugin Qt6 build
runs-on: macos-latest
steps:
- name: Set environment variables
run: echo "PATH=/opt/homebrew/opt/qt@6/bin:/opt/homebrew/opt/protobuf@21/bin:$PATH" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
brew update
brew install qt@6 protobuf@21
- name: Configure build
run: qmake PROTOBUF=/opt/homebrew/opt/protobuf@21 pbfplugin.pro
- name: Build project - name: Build project
run: make -j3 run: make -j3
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: libpbf.dylib
name: libpbf.dylib

View File

@ -2,13 +2,10 @@ TARGET = pbf
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin CONFIG += plugin
QT += gui QT += gui
VERSION = 3.3 VERSION = 4.0
PROTOS = protobuf/vector_tile.proto
include(protobuf/vector_tile.pri)
INCLUDEPATH += ./protobuf
HEADERS += src/pbfhandler.h \ HEADERS += src/pbfhandler.h \
src/data.h \
src/pbfplugin.h \ src/pbfplugin.h \
src/gzip.h \ src/gzip.h \
src/pbf.h \ src/pbf.h \
@ -23,6 +20,7 @@ HEADERS += src/pbfhandler.h \
src/textitem.h \ src/textitem.h \
src/sprites.h src/sprites.h
SOURCES += src/pbfplugin.cpp \ SOURCES += src/pbfplugin.cpp \
src/data.cpp \
src/pbfhandler.cpp \ src/pbfhandler.cpp \
src/gzip.cpp \ src/gzip.cpp \
src/pbf.cpp \ src/pbf.cpp \
@ -39,45 +37,25 @@ RESOURCES += pbfplugin.qrc
DEFINES += QT_NO_DEPRECATED_WARNINGS DEFINES += QT_NO_DEPRECATED_WARNINGS
equals(USE_PKGCONFIG, "true") {
CONFIG += link_pkgconfig
PKGCONFIG += protobuf-lite zlib
}
unix:!macx:!android { unix:!macx:!android {
!equals(USE_PKGCONFIG, "true") { LIBS += -lz
LIBS += -lprotobuf-lite \
-lz
}
target.path += $$[QT_INSTALL_PLUGINS]/imageformats target.path += $$[QT_INSTALL_PLUGINS]/imageformats
INSTALLS += target INSTALLS += target
} }
win32 { win32 {
!equals(USE_PKGCONFIG, "true") { INCLUDEPATH += $$ZLIB/include
INCLUDEPATH += $$PROTOBUF/include \ LIBS += $$ZLIB/lib/zlibstatic.lib
$$ZLIB/include
LIBS += $$PROTOBUF/lib/libprotobuf-lite.lib \
$$ZLIB/lib/zlibstatic.lib
}
QMAKE_TARGET_PRODUCT = QtPBFImagePlugin QMAKE_TARGET_PRODUCT = QtPBFImagePlugin
QMAKE_TARGET_DESCRIPTION = Qt $$QT_VERSION MVT/PBF image plugin QMAKE_TARGET_DESCRIPTION = Qt $$QT_VERSION MVT/PBF image plugin
QMAKE_TARGET_COPYRIGHT = Copyright (c) 2018-2025 Martin Tuma QMAKE_TARGET_COPYRIGHT = Copyright (c) 2018-2025 Martin Tuma
} }
macx { macx {
!equals(USE_PKGCONFIG, "true") { LIBS += -lz
INCLUDEPATH += $$PROTOBUF/include
LIBS += $$PROTOBUF/lib/libprotobuf-lite.a \
-lz
}
} }
android { android {
!equals(USE_PKGCONFIG, "true") { LIBS += -lz
INCLUDEPATH += $$PROTOBUF/include
LIBS += $$PROTOBUF/$$ANDROID_TARGET_ARCH/libprotobuf-lite.a \
-lz
}
top_builddir=$$shadowed($$PWD) top_builddir=$$shadowed($$PWD)
DESTDIR = $$top_builddir/plugins DESTDIR = $$top_builddir/plugins

View File

@ -1,17 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
protobuf_decl.name = protobuf headers
protobuf_decl.input = PROTOS
protobuf_decl.output = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_BASE}.pb.h
protobuf_decl.commands = protoc --cpp_out=${QMAKE_FILE_IN_PATH} --proto_path=${QMAKE_FILE_IN_PATH} ${QMAKE_FILE_NAME}
protobuf_decl.variable_out = HEADERS
QMAKE_EXTRA_COMPILERS += protobuf_decl
protobuf_impl.name = protobuf sources
protobuf_impl.input = PROTOS
protobuf_impl.output = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_BASE}.pb.cc
protobuf_impl.depends = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_BASE}.pb.h
protobuf_impl.commands = $$escape_expand(\n)
protobuf_impl.variable_out = SOURCES
QMAKE_EXTRA_COMPILERS += protobuf_impl

View File

@ -1,78 +0,0 @@
package vector_tile;
option optimize_for = LITE_RUNTIME;
message Tile {
// GeomType is described in section 4.3.4 of the specification
enum GeomType {
UNKNOWN = 0;
POINT = 1;
LINESTRING = 2;
POLYGON = 3;
}
// Variant type encoding
// The use of values is described in section 4.1 of the specification
message Value {
// Exactly one of these values must be present in a valid message
optional string string_value = 1;
optional float float_value = 2;
optional double double_value = 3;
optional int64 int_value = 4;
optional uint64 uint_value = 5;
optional sint64 sint_value = 6;
optional bool bool_value = 7;
extensions 8 to max;
}
// Features are described in section 4.2 of the specification
message Feature {
optional uint64 id = 1 [ default = 0 ];
// Tags of this feature are encoded as repeated pairs of
// integers.
// A detailed description of tags is located in sections
// 4.2 and 4.4 of the specification
repeated uint32 tags = 2 [ packed = true ];
// The type of geometry stored in this feature.
optional GeomType type = 3 [ default = UNKNOWN ];
// Contains a stream of commands and parameters (vertices).
// A detailed description on geometry encoding is located in
// section 4.3 of the specification.
repeated uint32 geometry = 4 [ packed = true ];
}
// Layers are described in section 4.1 of the specification
message Layer {
// Any compliant implementation must first read the version
// number encoded in this message and choose the correct
// implementation for this version number before proceeding to
// decode other parts of this message.
required uint32 version = 15 [ default = 1 ];
required string name = 1;
// The actual features in this tile.
repeated Feature features = 2;
// Dictionary encoding for keys
repeated string keys = 3;
// Dictionary encoding for values
repeated Value values = 4;
// Although this is an "optional" field it is required by the specification.
// See https://github.com/mapbox/vector-tile-spec/issues/47
optional uint32 extent = 5 [ default = 4096 ];
extensions 16 to max;
}
repeated Layer layers = 3;
extensions 16 to 8191;
}

294
src/data.cpp Normal file
View File

@ -0,0 +1,294 @@
#include "data.h"
#define TYPE(tag) (tag & 0x07)
#define FIELD(tag) (tag >> 3)
struct CTX
{
CTX(const QByteArray &ba)
: bp(ba.constData()), be(bp + ba.size()) {}
const char *bp;
const char *be;
quint64 tag;
};
template<typename T>
static bool varint(CTX &ctx, T &val)
{
val = 0;
uint shift = 0;
while (ctx.bp < ctx.be) {
val |= ((quint8)*ctx.bp & 0x7F) << shift;
shift += 7;
if (!((quint8)*ctx.bp++ & 0x80))
return true;
}
return false;
}
static bool str(CTX &ctx, QByteArray &val)
{
quint64 len;
if (!varint(ctx, len))
return false;
if (ctx.bp + len > ctx.be)
return false;
val = QByteArray::fromRawData(ctx.bp, len);
ctx.bp += len;
return true;
}
static bool dbl(CTX &ctx, double &val)
{
if (ctx.bp + sizeof(val) > ctx.be)
return false;
memcpy(&val, ctx.bp, sizeof(val));
return true;
}
static bool flt(CTX &ctx, float &val)
{
if (ctx.bp + sizeof(val) > ctx.be)
return false;
memcpy(&val, ctx.bp, sizeof(val));
return true;
}
static bool packed(CTX &ctx, QVector<quint32> &vals)
{
quint32 v;
if (TYPE(ctx.tag) == 2) {
quint64 len;
if (!varint(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, v))
return false;
vals.append(v);
}
return (ctx.bp == ee);
} else if (TYPE(ctx.tag) == 0) {
if (!varint(ctx, v))
return false;
vals.append(v);
return true;
} else
return false;
}
static bool skip(CTX &ctx)
{
quint64 len = 0;
switch (TYPE(ctx.tag)) {
case 0:
return varint(ctx, len);
case 1:
len = 8;
break;
case 2:
if (!varint(ctx, len))
return false;
break;
case 5:
len = 4;
break;
default:
return false;
}
if (ctx.bp + len > ctx.be)
return false;
ctx.bp += len;
return true;
}
static bool value(CTX &ctx, QVariant &val)
{
QByteArray ba;
quint64 len, num;
double dnum;
float fnum;
if (!varint(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (!str(ctx, ba))
return false;
val = QVariant(ba);
break;
case 2:
if (!flt(ctx, fnum))
return false;
val = QVariant(fnum);
break;
case 3:
if (!dbl(ctx, dnum))
return false;
val = QVariant(dnum);
break;
case 4:
if (!varint(ctx, num))
return false;
val = QVariant((qint64)num);
break;
case 5:
if (!varint(ctx, num))
return false;
val = QVariant(num);
break;
case 6:
if (!varint(ctx, num))
return false;
val = QVariant((qint64)((num >> 1) ^ -(num & 1)));
break;
case 7:
if (!varint(ctx, num))
return false;
val = QVariant(num ? true : false);
break;
default:
if (!skip(ctx))
return false;
}
}
return (ctx.bp == ee);
}
static bool feature(CTX &ctx, Data::Feature &f)
{
quint64 len;
quint8 e;
if (!varint(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (!varint(ctx, f.id))
return false;
break;
case 2:
if (!packed(ctx, f.tags))
return false;
break;
case 3:
if (!varint(ctx, e))
return false;
if (e > Data::GeomType::POLYGON)
return false;
f.type = (Data::GeomType)e;
break;
case 4:
if (!packed(ctx, f.geometry))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
return (ctx.bp == ee);
}
static bool layer(CTX &ctx, Data::Layer &l)
{
if (ctx.tag == 0x1a) {
quint64 len;
if (!varint(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (!str(ctx, l.name))
return false;
break;
case 2:
l.features.append(Data::Feature());
if (!feature(ctx, l.features.last()))
return false;
break;
case 3:
l.keys.append(QByteArray());
if (!str(ctx, l.keys.last()))
return false;
break;
case 4:
l.values.append(QVariant());
if (!value(ctx, l.values.last()))
return false;
break;
case 5:
if (!varint(ctx, l.extent))
return false;
break;
case 15:
if (!varint(ctx, l.version))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
return (ctx.bp == ee);
} else
return skip(ctx);
}
bool Data::load(const QByteArray &ba)
{
CTX ctx(ba);
while (ctx.bp < ctx.be) {
if (!varint(ctx, ctx.tag))
return false;
_layers.append(Layer());
if (!layer(ctx, _layers.last()))
return false;
}
return (ctx.bp == ctx.be);
}

43
src/data.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef DATA_H
#define DATA_H
#include <QByteArray>
#include <QVector>
#include <QVariant>
class Data
{
public:
enum GeomType {
UNKNOWN = 0,
POINT = 1,
LINESTRING = 2,
POLYGON = 3
};
struct Feature
{
quint64 id;
QVector<quint32> tags;
GeomType type;
QVector<quint32> geometry;
};
struct Layer
{
quint32 version;
QByteArray name;
QVector<Feature> features;
QVector<QByteArray> keys;
QVector<QVariant> values;
quint32 extent;
};
bool load(const QByteArray &ba);
const QVector<Layer> &layers() const {return _layers;}
private:
QVector<Layer> _layers;
};
#endif // DATA_H

View File

@ -4,7 +4,6 @@
#define LINE_TO 2 #define LINE_TO 2
#define CLOSE_PATH 7 #define CLOSE_PATH 7
static inline qint32 zigzag32decode(quint32 value) static inline qint32 zigzag32decode(quint32 value)
{ {
return static_cast<qint32>((value >> 1u) ^ static_cast<quint32>( return static_cast<qint32>((value >> 1u) ^ static_cast<quint32>(
@ -16,26 +15,6 @@ static inline QPoint parameters(quint32 v1, quint32 v2)
return QPoint(zigzag32decode(v1), zigzag32decode(v2)); return QPoint(zigzag32decode(v1), zigzag32decode(v2));
} }
static QVariant value(const vector_tile::Tile_Value &val)
{
if (val.has_bool_value())
return QVariant(val.bool_value());
else if (val.has_int_value())
return QVariant((qlonglong)val.int_value());
else if (val.has_sint_value())
return QVariant((qlonglong)val.sint_value());
else if (val.has_uint_value())
return QVariant((qulonglong)val.uint_value());
else if (val.has_float_value())
return QVariant(val.float_value());
else if (val.has_double_value())
return QVariant(val.double_value());
else if (val.has_string_value())
return QVariant(QByteArray::fromStdString(val.string_value()));
else
return QVariant();
}
const QVariant *PBF::Feature::value(const QByteArray &key) const const QVariant *PBF::Feature::value(const QByteArray &key) const
{ {
const KeyHash &keys(_layer->keys()); const KeyHash &keys(_layer->keys());
@ -43,10 +22,10 @@ const QVariant *PBF::Feature::value(const QByteArray &key) const
if (it == keys.constEnd()) if (it == keys.constEnd())
return 0; return 0;
google::protobuf::uint32 index = *it; quint32 index = *it;
for (int i = 0; i < _data->tags_size(); i = i + 2) for (int i = 0; i < _data->tags.size(); i = i + 2)
if (_data->tags(i) == index) if (_data->tags.at(i) == index)
return &(_layer->values().at(_data->tags(i+1))); return &(_layer->values().at(_data->tags.at(i+1)));
return 0; return 0;
} }
@ -56,15 +35,15 @@ QPainterPath PBF::Feature::path(const QSizeF &factor) const
QPoint cursor; QPoint cursor;
QPainterPath path; QPainterPath path;
for (int i = 0; i < _data->geometry_size(); i++) { for (int i = 0; i < _data->geometry.size(); i++) {
quint32 g = _data->geometry(i); quint32 g = _data->geometry.at(i);
unsigned cmdId = g & 0x7; unsigned cmdId = g & 0x7;
unsigned cmdCount = g >> 3; unsigned cmdCount = g >> 3;
if (cmdId == MOVE_TO) { if (cmdId == MOVE_TO) {
for (unsigned j = 0; j < cmdCount; j++) { for (unsigned j = 0; j < cmdCount; j++) {
QPoint offset = parameters(_data->geometry(i+1), QPoint offset = parameters(_data->geometry.at(i+1),
_data->geometry(i+2)); _data->geometry.at(i+2));
i += 2; i += 2;
cursor += offset; cursor += offset;
path.moveTo(QPointF(cursor.x() * factor.width(), path.moveTo(QPointF(cursor.x() * factor.width(),
@ -72,8 +51,8 @@ QPainterPath PBF::Feature::path(const QSizeF &factor) const
} }
} else if (cmdId == LINE_TO) { } else if (cmdId == LINE_TO) {
for (unsigned j = 0; j < cmdCount; j++) { for (unsigned j = 0; j < cmdCount; j++) {
QPoint offset = parameters(_data->geometry(i+1), QPoint offset = parameters(_data->geometry.at(i+1),
_data->geometry(i+2)); _data->geometry.at(i+2));
i += 2; i += 2;
cursor += offset; cursor += offset;
path.lineTo(QPointF(cursor.x() * factor.width(), path.lineTo(QPointF(cursor.x() * factor.width(),
@ -88,27 +67,23 @@ QPainterPath PBF::Feature::path(const QSizeF &factor) const
return path; return path;
} }
PBF::Layer::Layer(const vector_tile::Tile_Layer *data) : _data(data) PBF::Layer::Layer(const Data::Layer *layer) : _data(layer)
{ {
_keys.reserve(data->keys_size()); _keys.reserve(layer->keys.size());
for (int i = 0; i < data->keys_size(); i++) for (int i = 0; i < layer->keys.size(); i++)
_keys.insert(QByteArray::fromStdString(data->keys(i)), i); _keys.insert(layer->keys.at(i), i);
_values.reserve(data->values_size());
for (int i = 0; i < data->values_size(); i++)
_values.append(value(data->values(i)));
_features.reserve(data->features_size()); _features.reserve(layer->features.size());
for (int i = 0; i < data->features_size(); i++) for (int i = 0; i < layer->features.size(); i++)
_features.append(Feature(&(data->features(i)), this)); _features.append(Feature(&(layer->features.at(i)), this));
std::sort(_features.begin(), _features.end()); std::sort(_features.begin(), _features.end());
} }
PBF::PBF(const vector_tile::Tile &tile) PBF::PBF(const Data &data)
{ {
for (int i = 0; i < tile.layers_size(); i++) { for (int i = 0; i < data.layers().size(); i++) {
const vector_tile::Tile_Layer &layer = tile.layers(i); const Data::Layer &layer = data.layers().at(i);
_layers.insert(QByteArray::fromStdString(layer.name()), _layers.insert(layer.name, new Layer(&layer));
new Layer(&layer));
} }
} }

View File

@ -5,10 +5,10 @@
#include <QVector> #include <QVector>
#include <QHash> #include <QHash>
#include <QPainterPath> #include <QPainterPath>
#include "vector_tile.pb.h" #include "data.h"
typedef QHash<QByteArray, google::protobuf::uint32> KeyHash; typedef QHash<QByteArray, quint32> KeyHash;
class PBF class PBF
{ {
@ -19,17 +19,17 @@ public:
{ {
public: public:
Feature() : _data(0), _layer(0) {} Feature() : _data(0), _layer(0) {}
Feature(const vector_tile::Tile_Feature *data, const Layer *layer) Feature(const Data::Feature *data, const Layer *layer)
: _data(data), _layer(layer) {} : _data(data), _layer(layer) {}
const QVariant *value(const QByteArray &key) const; const QVariant *value(const QByteArray &key) const;
vector_tile::Tile_GeomType type() const {return _data->type();} Data::GeomType type() const {return _data->type;}
QPainterPath path(const QSizeF &factor) const; QPainterPath path(const QSizeF &factor) const;
friend bool operator<(const Feature &f1, const Feature &f2); friend bool operator<(const Feature &f1, const Feature &f2);
private: private:
const vector_tile::Tile_Feature *_data; const Data::Feature *_data;
const Layer *_layer; const Layer *_layer;
}; };
@ -37,22 +37,21 @@ public:
{ {
public: public:
Layer(const vector_tile::Tile_Layer *data); Layer(const Data::Layer *layer);
const QVector<Feature> &features() const {return _features;} const QVector<Feature> &features() const {return _features;}
const QVector<QVariant> &values() const {return _values;} const QVector<QVariant> &values() const {return _data->values;}
const KeyHash &keys() const {return _keys;} const KeyHash &keys() const {return _keys;}
const vector_tile::Tile_Layer *data() const {return _data;} const Data::Layer *data() const {return _data;}
private: private:
const vector_tile::Tile_Layer *_data; const Data::Layer *_data;
QVector<Feature> _features; QVector<Feature> _features;
QVector<QVariant> _values;
KeyHash _keys; KeyHash _keys;
}; };
PBF(const vector_tile::Tile &tile); PBF(const Data &data);
~PBF(); ~PBF();
const QHash<QByteArray, Layer*> &layers() const {return _layers;} const QHash<QByteArray, Layer*> &layers() const {return _layers;}
@ -62,6 +61,6 @@ private:
}; };
inline bool operator<(const PBF::Feature &f1, const PBF::Feature &f2) inline bool operator<(const PBF::Feature &f1, const PBF::Feature &f2)
{return f1._data->id() < f2._data->id();} {return f1._data->id < f2._data->id;}
#endif // PBF_H #endif // PBF_H

View File

@ -3,6 +3,7 @@
#include <QtEndian> #include <QtEndian>
#include <QDebug> #include <QDebug>
#include "gzip.h" #include "gzip.h"
#include "data.h"
#include "tile.h" #include "tile.h"
#include "style.h" #include "style.h"
#include "pbfhandler.h" #include "pbfhandler.h"
@ -73,8 +74,8 @@ bool PBFHandler::read(QImage *image)
} }
} else if (isPlainPBF(magic)) } else if (isPlainPBF(magic))
ba = device()->readAll(); ba = device()->readAll();
vector_tile::Tile data; Data data;
if (!data.ParseFromArray(ba.constData(), ba.size())) { if (!data.load(ba)) {
qCritical() << "Invalid PBF data"; qCritical() << "Invalid PBF data";
return false; return false;
} }

View File

@ -14,16 +14,16 @@
#include "style.h" #include "style.h"
static vector_tile::Tile_GeomType geometryType(const QString &str) static Data::GeomType geometryType(const QString &str)
{ {
if (str == "Point") if (str == "Point")
return vector_tile::Tile_GeomType_POINT; return Data::GeomType::POINT;
else if (str == "LineString") else if (str == "LineString")
return vector_tile::Tile_GeomType_LINESTRING; return Data::GeomType::LINESTRING;
else if (str == "Polygon") else if (str == "Polygon")
return vector_tile::Tile_GeomType_POLYGON; return Data::GeomType::POLYGON;
else else
return vector_tile::Tile_GeomType_UNKNOWN; return Data::GeomType::UNKNOWN;
} }
static QVariant variant(const QJsonValue &val) static QVariant variant(const QJsonValue &val)
@ -680,15 +680,15 @@ void Style::drawFeature(const PBF::Feature &feature, const Layer &layer,
void Style::drawLayer(const PBF::Layer &pbfLayer, const Layer &styleLayer, void Style::drawLayer(const PBF::Layer &pbfLayer, const Layer &styleLayer,
Tile &tile) Tile &tile)
{ {
if (pbfLayer.data()->version() > 2) if (pbfLayer.data()->version > 2)
return; return;
if (!styleLayer.isVisible()) if (!styleLayer.isVisible())
return; return;
QSizeF factor(tile.size().width() / tile.scale().x() / QSizeF factor(tile.size().width() / tile.scale().x() /
(qreal)pbfLayer.data()->extent(), tile.size().height() / tile.scale().y() (qreal)pbfLayer.data()->extent, tile.size().height() / tile.scale().y()
/ (qreal)pbfLayer.data()->extent()); / (qreal)pbfLayer.data()->extent);
tile.painter().save(); tile.painter().save();
setupLayer(tile, styleLayer); setupLayer(tile, styleLayer);