Skip to content

Commit ea8c255

Browse files
VectorLayer - Task AlpineMapsOrg#182
- osm-bright and qwant styles are now parsed and displayed - qwant style generates too many indices, and does not fit into indexbuffer cascades when drawing vienna -> will most likely solve itself after index buffer refactor
1 parent 63f17d2 commit ea8c255

File tree

9 files changed

+441
-78
lines changed

9 files changed

+441
-78
lines changed

app/vectorlayerstyles/osm-bright.json

-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@
333333
"metadata": {"mapbox:group": "1444849382550.77"},
334334
"source": "openmaptiles",
335335
"source-layer": "water",
336-
"filter": ["all"],
337336
"layout": {"visibility": "visible"},
338337
"paint": {"fill-pattern": "wave", "fill-translate": [0, 2.5]}
339338
},

gl_engine/shaders/vector_layer.frag

+6-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,12 @@ void main() {
314314
highp uvec2 offset_size = uvec2(0u);
315315

316316
lowp float pixel_alpha = 0.0;
317-
texout_albedo = vec3(242.0f/255.0f, 239.0f/255.0f, 233.0f/255.0f);
317+
// openmaptile
318+
// texout_albedo = vec3(242.0f/255.0f, 239.0f/255.0f, 233.0f/255.0f);
319+
// qwant
320+
// texout_albedo = vec3(248.0f/255.0f, 248.0f/255.0f, 248.0f/255.0f);
321+
// osm-bright
322+
texout_albedo = vec3(248.0f/255.0f, 244.0f/255.0f, 240.0f/255.0f);
318323

319324

320325

nucleus/vector_layer/Scheduler.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Scheduler::Scheduler(std::string name, QObject* parent)
2929
// , m_style(":/vectorlayerstyles/basemap.json")
3030
, m_style(":/vectorlayerstyles/openstreetmap.json")
3131
// , m_style(":/vectorlayerstyles/qwant.json")
32+
// , m_style(":/vectorlayerstyles/osm-bright.json")
3233
{
3334
connect(&m_style, &Style::load_finished, this, &Scheduler::enable_scheduler);
3435
}

nucleus/vector_layer/Style.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ void Style::load()
115115
s.outline_dash = parse_dasharray(paintObject.value(key).toArray());
116116
} else if (key == "line-offset") {
117117
// might be needed
118+
} else if (key == "fill-translate" || key == "line-translate-anchor") {
119+
// currentley not supported
118120
} else if (key == "fill-pattern") {
119121
// currently not supported -> causes errors when parsed
120122
invalid = true;
@@ -321,7 +323,7 @@ uint32_t Style::parse_color(const QJsonValue& value)
321323

322324
uint8_t a = 255;
323325
if (matches.size() == 5 && matches[4].length() > 0) {
324-
a = std::stod(matches[4]) * 255.0;
326+
a = stringToFloat(matches[4]) * 255.0;
325327
}
326328

327329
// formula from https://www.rapidtables.com/convert/color/hsl-to-rgb.html

nucleus/vector_layer/StyleExpander.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,9 @@ SubLayerInfo generate_expanded_filters(const QJsonObject& paint, const QJsonArra
172172
}
173173
}
174174
} else {
175-
// no all -> only save the current instance as the sub filter
176-
sub_filter.push_back(filter);
175+
// no all -> only save the current instance as the sub filter (only if there is a filter)
176+
if (!filter.isEmpty())
177+
sub_filter.push_back(filter);
177178

178179
if (filter.contains("in")) {
179180
in_filter_index = 0;
@@ -296,7 +297,9 @@ SubLayerInfo generate_expanded_filters(const QJsonObject& paint, const QJsonArra
296297

297298
QJsonArray rejoin_filter(std::vector<QJsonArray> filters)
298299
{
299-
assert(filters.size() > 0);
300+
if (filters.size() == 0) {
301+
return {};
302+
}
300303

301304
if (filters.size() == 1) {
302305
// just one element -> we can just use it without changing anything

nucleus/vector_layer/StyleExpression.cpp

+42-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424

2525
namespace nucleus::vector_layer {
2626

27+
QJsonValue StyleExpressionBase::extract_literal(QJsonValue expression)
28+
{
29+
assert(expression.isArray());
30+
assert(expression.toArray()[0].isString());
31+
assert(expression.toArray()[0].toString() == "literal");
32+
assert(expression.toArray().size() == 2);
33+
34+
return expression.toArray()[1];
35+
}
36+
2737
std::unique_ptr<StyleExpressionBase> StyleExpressionBase::create_filter_expression(QJsonArray data)
2838
{
2939
if (data.isEmpty())
@@ -73,9 +83,28 @@ StyleExpression::StyleExpression(QJsonArray data)
7383
// values
7484
if (m_comparator == "in" || m_comparator == "!in") {
7585
// multiple values
76-
for (qsizetype i = 2; i < data.size(); ++i) {
77-
m_values.push_back(data[i].toString().toStdString());
86+
if (data.size() == 3 && data[2].isArray()) {
87+
// we most likely have a "literal" sub array
88+
const auto values = extract_literal(data[2]).toArray();
89+
90+
for (qsizetype i = 0; i < values.size(); ++i) {
91+
assert(values[i].isString());
92+
m_values.push_back(values[i].toString().toStdString());
93+
}
94+
95+
} else {
96+
for (qsizetype i = 2; i < data.size(); ++i) {
97+
if (data[i].isDouble()) {
98+
m_values.push_back(std::to_string(data[i].toDouble()));
99+
} else if (data[i].isString()) {
100+
m_values.push_back(data[i].toString().toStdString());
101+
} else {
102+
qDebug() << "invalid data: " << data[i];
103+
assert(false);
104+
}
105+
}
78106
}
107+
79108
} else if (m_comparator == "has" || m_comparator == "!has") {
80109
// no values for has expressions -> we only check if key is present
81110
if (data.size() > 2) {
@@ -103,8 +132,8 @@ bool compare_equal(int64_t) { return true; }
103132

104133
bool StyleExpression::matches(const mapbox::vector_tile::GeomType& type, const mapbox::feature::properties_type& properties)
105134
{
106-
mapbox::feature::value value = extract_value(type, properties);
107135
// qDebug() << "match: " << m_key;
136+
mapbox::feature::value value = extract_value(type, properties);
108137

109138
if (m_comparator == "in" || m_comparator == "!in") {
110139
const auto string_value = std::visit(vector_tile::util::string_print_visitor, value).toStdString(); // we are only using the value to see if it is in a list -> string is sufficient
@@ -161,21 +190,29 @@ StyleExpressionCollection::StyleExpressionCollection(QJsonArray data)
161190
m_subFilters = std::vector<std::unique_ptr<StyleExpressionBase>>();
162191

163192
for (qsizetype i = 1; i < data.size(); ++i) {
164-
if (data[i].isArray())
193+
if (data[i].isArray()) {
194+
if (data[i].toArray().isEmpty()) {
195+
qDebug() << "empty array";
196+
assert(false);
197+
}
165198
m_subFilters.push_back(create_filter_expression(data[i].toArray()));
166-
else
199+
} else {
167200
qDebug() << "not an array??";
201+
assert(false);
202+
}
168203
}
169204
}
170205

171206
bool StyleExpressionCollection::matches(const mapbox::vector_tile::GeomType& type, const mapbox::feature::properties_type& properties)
172207
{
173208
if (m_negate) {
209+
assert(m_subFilters.size() == 1);
174210
// negate should only handle one subfilter -> get the match and negate it
175211
return !m_subFilters[0]->matches(type, properties);
176212
}
177213

178214
for (size_t i = 0; i < m_subFilters.size(); ++i) {
215+
assert(m_subFilters[i] != nullptr);
179216
bool result = m_subFilters[i]->matches(type, properties);
180217
if (m_all && !result) {
181218
return false; // the current match was false but all had to be true

nucleus/vector_layer/StyleExpression.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class StyleExpressionBase {
4747
virtual bool matches(const mapbox::vector_tile::GeomType& type, const mapbox::feature::properties_type& properties) = 0;
4848

4949
static std::unique_ptr<StyleExpressionBase> create_filter_expression(QJsonArray data);
50+
QJsonValue extract_literal(QJsonValue expression);
5051
};
5152

5253
class StyleExpression : public StyleExpressionBase {

nucleus/vector_layer/StyleFilter.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,26 @@ std::vector<std::pair<uint32_t, uint32_t>> StyleFilter::indices(unsigned zoom, c
4545
auto styles = std::vector<std::pair<uint32_t, uint32_t>>();
4646

4747
for (const auto& values : m_filter.at(zoom)) {
48+
// qDebug() << (std::get<2>(values) == nullptr);
4849
if (std::get<2>(values) == nullptr) // no filter is here -> we assume that every feature with layername and zoom is valid
4950
{
50-
assert(m_filter.at(zoom).size() == 1); // if there is no filter -> there should only be one valid value
51+
// if (m_filter.at(zoom).size() > 1) {
52+
// qDebug() << "more than one filter is applicable: " << m_filter.at(zoom).size();
53+
// qDebug() << std::get<0>(values);
54+
// qDebug() << std::get<1>(values);
55+
// }
56+
// assert(m_filter.at(zoom).size() == 1); // if there is no filter -> there should only be one valid value
5157
styles.push_back(std::make_pair(std::get<0>(values), std::get<1>(values)));
58+
// if (m_filter.at(zoom).size() > 1) {
59+
// qDebug() << "why not working?: " << m_filter.at(zoom).size();
60+
// }
5261
} else if (std::get<2>(values)->matches(type, properties)) {
53-
styles.push_back(std::make_pair(std::get<0>(values), std::get<1>(values))); // first filter that matches returns the indices
62+
styles.push_back(std::make_pair(std::get<0>(values), std::get<1>(values)));
5463
}
5564
}
5665

66+
// qDebug() << "return style!";
67+
5768
return styles;
5869
}
5970

0 commit comments

Comments
 (0)