Compare commits

...

6 Commits

7 changed files with 77 additions and 58 deletions

View File

@ -1,4 +1,4 @@
version: 3.1.{build} version: 3.2.{build}
configuration: configuration:
- Release - Release

View File

@ -2,7 +2,7 @@ TARGET = pbf
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin CONFIG += plugin
QT += gui QT += gui
VERSION = 3.1 VERSION = 3.2
PROTOS = protobuf/vector_tile.proto PROTOS = protobuf/vector_tile.proto
include(protobuf/vector_tile.pri) include(protobuf/vector_tile.pri)

View File

@ -31,12 +31,12 @@ static QVariant value(const vector_tile::Tile_Value &val)
else if (val.has_double_value()) else if (val.has_double_value())
return QVariant(val.double_value()); return QVariant(val.double_value());
else if (val.has_string_value()) else if (val.has_string_value())
return QVariant(QString::fromStdString(val.string_value())); return QVariant(QByteArray::fromStdString(val.string_value()));
else else
return QVariant(); return QVariant();
} }
const QVariant *PBF::Feature::value(const QString &key) const const QVariant *PBF::Feature::value(const QByteArray &key) const
{ {
const KeyHash &keys(_layer->keys()); const KeyHash &keys(_layer->keys());
KeyHash::const_iterator it(keys.find(key)); KeyHash::const_iterator it(keys.find(key));
@ -92,7 +92,7 @@ PBF::Layer::Layer(const vector_tile::Tile_Layer *data) : _data(data)
{ {
_keys.reserve(data->keys_size()); _keys.reserve(data->keys_size());
for (int i = 0; i < data->keys_size(); i++) for (int i = 0; i < data->keys_size(); i++)
_keys.insert(QString::fromStdString(data->keys(i)), i); _keys.insert(QByteArray::fromStdString(data->keys(i)), i);
_values.reserve(data->values_size()); _values.reserve(data->values_size());
for (int i = 0; i < data->values_size(); i++) for (int i = 0; i < data->values_size(); i++)
_values.append(value(data->values(i))); _values.append(value(data->values(i)));
@ -107,7 +107,8 @@ PBF::PBF(const vector_tile::Tile &tile)
{ {
for (int i = 0; i < tile.layers_size(); i++) { for (int i = 0; i < tile.layers_size(); i++) {
const vector_tile::Tile_Layer &layer = tile.layers(i); const vector_tile::Tile_Layer &layer = tile.layers(i);
_layers.insert(QString::fromStdString(layer.name()), new Layer(&layer)); _layers.insert(QByteArray::fromStdString(layer.name()),
new Layer(&layer));
} }
} }

View File

@ -8,7 +8,7 @@
#include "vector_tile.pb.h" #include "vector_tile.pb.h"
typedef QHash<QString, google::protobuf::uint32> KeyHash; typedef QHash<QByteArray, google::protobuf::uint32> KeyHash;
class PBF class PBF
{ {
@ -22,7 +22,7 @@ public:
Feature(const vector_tile::Tile_Feature *data, const Layer *layer) Feature(const vector_tile::Tile_Feature *data, const Layer *layer)
: _data(data), _layer(layer) {} : _data(data), _layer(layer) {}
const QVariant *value(const QString &key) const; const QVariant *value(const QByteArray &key) const;
vector_tile::Tile_GeomType type() const {return _data->type();} vector_tile::Tile_GeomType type() const {return _data->type();}
QPainterPath path(const QSizeF &factor) const; QPainterPath path(const QSizeF &factor) const;
@ -55,10 +55,10 @@ public:
PBF(const vector_tile::Tile &tile); PBF(const vector_tile::Tile &tile);
~PBF(); ~PBF();
const QHash<QString, Layer*> &layers() const {return _layers;} const QHash<QByteArray, Layer*> &layers() const {return _layers;}
private: private:
QHash<QString, Layer*> _layers; QHash<QByteArray, Layer*> _layers;
}; };
inline bool operator<(const PBF::Feature &f1, const PBF::Feature &f2) inline bool operator<(const PBF::Feature &f1, const PBF::Feature &f2)

View File

@ -95,6 +95,25 @@ bool Sprites::load(const QString &jsonFile, const QString &imageFile)
QImage Sprites::sprite(const Sprite &sprite, const QColor &color, qreal scale) QImage Sprites::sprite(const Sprite &sprite, const QColor &color, qreal scale)
{ {
_lock.lock();
if (_init <= 0) {
if (_init < 0) {
_lock.unlock();
return QImage();
}
_img = QImage(_imageFile);
if (_img.isNull()) {
qWarning() << _imageFile << ": invalid sprite atlas image";
_init = -1;
_lock.unlock();
return QImage();
}
_init = 1;
}
_lock.unlock();
if (!_img.rect().contains(sprite.rect())) if (!_img.rect().contains(sprite.rect()))
return QImage(); return QImage();
@ -118,25 +137,6 @@ QImage Sprites::icon(const QString &name, const QColor &color, qreal size)
if (name.isNull()) if (name.isNull())
return QImage(); return QImage();
_lock.lock();
if (_init <= 0) {
if (_init < 0) {
_lock.unlock();
return QImage();
}
_img = QImage(_imageFile);
if (_img.isNull()) {
qWarning() << _imageFile << ": invalid sprite atlas image";
_init = -1;
_lock.unlock();
return QImage();
}
_init = 1;
}
_lock.unlock();
QMap<QString, Sprite>::const_iterator it = _sprites.constFind(name); QMap<QString, Sprite>::const_iterator it = _sprites.constFind(name);
if (it == _sprites.constEnd()) if (it == _sprites.constEnd())
return QImage(); return QImage();

View File

@ -26,6 +26,20 @@ static vector_tile::Tile_GeomType geometryType(const QString &str)
return vector_tile::Tile_GeomType_UNKNOWN; return vector_tile::Tile_GeomType_UNKNOWN;
} }
static QVariant variant(const QJsonValue &val)
{
switch (val.type()) {
case QJsonValue::String:
return QVariant(val.toString().toUtf8());
case QJsonValue::Double:
case QJsonValue::Bool:
return val.toVariant();
default:
qWarning() << val << ": invalid filter value";
return QVariant();
}
}
Style::Layer::Filter::Filter(const QJsonArray &json) Style::Layer::Filter::Filter(const QJsonArray &json)
: _type(Unknown), _not(false) : _type(Unknown), _not(false)
{ {
@ -35,50 +49,50 @@ Style::Layer::Filter::Filter(const QJsonArray &json)
if (json.isEmpty()) if (json.isEmpty())
INVALID_FILTER(json); INVALID_FILTER(json);
QString type = json.at(0).toString(); QString type(json.at(0).toString());
if (type == "==") { if (type == "==") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
if (json.at(1).toString() == "$type") { if (json.at(1).toString() == "$type") {
_type = GeometryType; _type = GeometryType;
_kv = QPair<QString, QVariant>(QString(), _kv = QPair<QByteArray, QVariant>(QByteArray(),
QVariant(geometryType(json.at(2).toString()))); QVariant(geometryType(json.at(2).toString())));
} else { } else {
_type = EQ; _type = EQ;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} }
} else if (type == "!=") { } else if (type == "!=") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = NE; _type = NE;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} else if (type == "<") { } else if (type == "<") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = LT; _type = LT;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} else if (type == "<=") { } else if (type == "<=") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = LE; _type = LE;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} else if (type == ">") { } else if (type == ">") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = GT; _type = GT;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} else if (type == ">=") { } else if (type == ">=") {
if (json.size() != 3) if (json.size() != 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = GE; _type = GE;
_kv = QPair<QString, QVariant>(json.at(1).toString(), _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
json.at(2).toVariant()); variant(json.at(2)));
} else if (type == "all") { } else if (type == "all") {
_type = All; _type = All;
for (int i = 1; i < json.size(); i++) for (int i = 1; i < json.size(); i++)
@ -91,28 +105,32 @@ Style::Layer::Filter::Filter(const QJsonArray &json)
if (json.size() < 3) if (json.size() < 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = In; _type = In;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant()); _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
for (int i = 2; i < json.size(); i++) for (int i = 2; i < json.size(); i++)
_set.insert(json.at(i).toString()); _set.insert(json.at(i).toString().toUtf8());
} else if (type == "!in") { } else if (type == "!in") {
if (json.size() < 3) if (json.size() < 3)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = In; _type = In;
_not = true; _not = true;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant()); _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
for (int i = 2; i < json.size(); i++) for (int i = 2; i < json.size(); i++)
_set.insert(json.at(i).toString()); _set.insert(json.at(i).toString().toUtf8());
} else if (type == "has") { } else if (type == "has") {
if (json.size() < 2) if (json.size() < 2)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = Has; _type = Has;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant()); _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
} else if (type == "!has") { } else if (type == "!has") {
if (json.size() < 2) if (json.size() < 2)
INVALID_FILTER(json); INVALID_FILTER(json);
_type = Has; _type = Has;
_not = true; _not = true;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant()); _kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
} else } else
INVALID_FILTER(json); INVALID_FILTER(json);
} }
@ -182,7 +200,7 @@ bool Style::Layer::Filter::match(const PBF::Feature &feature) const
if (!(v = feature.value(_kv.first))) if (!(v = feature.value(_kv.first)))
return _not; return _not;
else else
return _set.contains((*v).toString()) ^ _not; return _set.contains((*v).toByteArray()) ^ _not;
case Has: case Has:
return (feature.value(_kv.first) ? true : false) ^ _not; return (feature.value(_kv.first) ? true : false) ^ _not;
case All: case All:
@ -216,7 +234,7 @@ QString Style::Layer::Template::value(int zoom, const PBF::Feature &feature) con
} }
for (int i = 0; i < keys.size(); i++) { for (int i = 0; i < keys.size(); i++) {
const QString &key = keys.at(i); const QString &key = keys.at(i);
const QVariant *val = feature.value(key); const QVariant *val = feature.value(key.toUtf8());
text.replace(QString("{%1}").arg(key), val ? val->toString() : ""); text.replace(QString("{%1}").arg(key), val ? val->toString() : "");
} }
@ -486,7 +504,7 @@ Style::Layer::Layer(const QJsonObject &json)
_type = Symbol; _type = Symbol;
// source-layer // source-layer
_sourceLayer = json["source-layer"].toString(); _sourceLayer = json["source-layer"].toString().toUtf8();
// zooms // zooms
if (json.contains("minzoom") && json["minzoom"].isDouble()) if (json.contains("minzoom") && json["minzoom"].isDouble())
@ -572,7 +590,7 @@ static bool loadSprites(const QDir &styleDir, const QString &json,
if (QFileInfo::exists(spritesImg)) if (QFileInfo::exists(spritesImg))
return sprites.load(spritesJSON, spritesImg); return sprites.load(spritesJSON, spritesImg);
else { else {
qCritical() << spritesImg << ": no such file"; qWarning() << spritesImg << ": no such file";
return false; return false;
} }
} }
@ -684,7 +702,7 @@ void Style::render(const PBF &data, Tile &tile)
drawBackground(tile); drawBackground(tile);
for (int i = 0; i < _layers.size(); i++) { for (int i = 0; i < _layers.size(); i++) {
QHash<QString, PBF::Layer*>::const_iterator it = data.layers().find( QHash<QByteArray, PBF::Layer*>::const_iterator it = data.layers().find(
_layers.at(i).sourceLayer()); _layers.at(i).sourceLayer());
if (it == data.layers().constEnd()) if (it == data.layers().constEnd())
continue; continue;

View File

@ -37,7 +37,7 @@ private:
Layer() : _type(Unknown), _minZoom(0), _maxZoom(24) {} Layer() : _type(Unknown), _minZoom(0), _maxZoom(24) {}
Layer(const QJsonObject &json); Layer(const QJsonObject &json);
const QString &sourceLayer() const {return _sourceLayer;} const QByteArray &sourceLayer() const {return _sourceLayer;}
bool isPath() const {return (_type == Line || _type == Fill);} bool isPath() const {return (_type == Line || _type == Fill);}
bool isBackground() const {return (_type == Background);} bool isBackground() const {return (_type == Background);}
bool isSymbol() const {return (_type == Symbol);} bool isSymbol() const {return (_type == Symbol);}
@ -74,8 +74,8 @@ private:
Type _type; Type _type;
bool _not; bool _not;
QSet<QString> _set; QSet<QByteArray> _set;
QPair<QString, QVariant> _kv; QPair<QByteArray, QVariant> _kv;
QVector<Filter> _filters; QVector<Filter> _filters;
}; };
@ -167,7 +167,7 @@ private:
}; };
Type _type; Type _type;
QString _sourceLayer; QByteArray _sourceLayer;
int _minZoom, _maxZoom; int _minZoom, _maxZoom;
Filter _filter; Filter _filter;
Layout _layout; Layout _layout;