mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Store hash key/value pairs in one ordered vector
Replace the parallel std::vector<json_object_ptr> keys / values on
json_hash with a single std::vector<json_entry>, where json_entry is
a small {key, value} aggregate. This still preserves insertion order
(the property the parallel vectors were providing) but removes the
"keep two vectors in lockstep" pattern, and call sites can now use
range-for with structured bindings:
for (auto &[k, v] : o->entries()) { ... }
Side effects:
* sizeof(json_hash) drops from 72 to 48 bytes (one fewer vector
header), matching json_array.
* The keys() and values() accessors on json_object are replaced by a
single entries() accessor returning std::vector<json_entry>&.
* All call sites were swept from the old paired-index pattern
(`o->keys()[i]` / `o->values()[i]`) to entry-based access. Where the
original pattern relied on `nprop = 0` to short-circuit iteration on
a null or non-hash `properties`, the rewrite now guards the loop
explicitly with `if (o->type == JSON_HASH)` so that calling
entries() doesn't trip the asserting downcast.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+6
-7
@@ -55,20 +55,19 @@ void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribut
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < o->keys().size(); i++) {
|
||||
json_object_ptr k = o->keys()[i];
|
||||
json_object_ptr v = o->values()[i];
|
||||
|
||||
if (k->type != JSON_STRING) {
|
||||
size_t i = 0;
|
||||
for (const auto &e : o->entries()) {
|
||||
if (e.key->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: -E%s: key %zu not a string\n", *argv, arg, i);
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
if (v->type != JSON_STRING) {
|
||||
if (e.value->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: -E%s: value %zu not a string\n", *argv, arg, i);
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
set_attribute_accum(attribute_accum, k->string().c_str(), v->string().c_str());
|
||||
set_attribute_accum(attribute_accum, e.key->string().c_str(), e.value->string().c_str());
|
||||
i++;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
+4
-4
@@ -260,14 +260,14 @@ sqlite3 *dirmeta2tmp(const char *fname) {
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < o->keys().size(); i++) {
|
||||
if (o->keys()[i]->type != JSON_STRING || o->values()[i]->type != JSON_STRING) {
|
||||
for (const auto &e : o->entries()) {
|
||||
if (e.key->type != JSON_STRING || e.value->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: non-string in metadata\n", name.c_str());
|
||||
}
|
||||
|
||||
char *sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", o->keys()[i]->string().c_str(), o->values()[i]->string().c_str());
|
||||
char *sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", e.key->string().c_str(), e.value->string().c_str());
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
|
||||
fprintf(stderr, "set %s in metadata: %s\n", o->keys()[i]->string().c_str(), err);
|
||||
fprintf(stderr, "set %s in metadata: %s\n", e.key->string().c_str(), err);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
|
||||
+11
-13
@@ -175,24 +175,22 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object_ptr g
|
||||
}
|
||||
}
|
||||
|
||||
size_t nprop = 0;
|
||||
if (properties != nullptr && properties->type == JSON_HASH) {
|
||||
nprop = properties->keys().size();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<std::string>> full_keys;
|
||||
std::vector<serial_val> values;
|
||||
|
||||
full_keys.reserve(nprop);
|
||||
values.reserve(nprop);
|
||||
key_pool key_pool;
|
||||
|
||||
for (size_t i = 0; i < nprop; i++) {
|
||||
if (properties->keys()[i]->type == JSON_STRING) {
|
||||
serial_val sv = stringify_value(properties->values()[i], sst->fname, sst->line, feature);
|
||||
if (properties != nullptr && properties->type == JSON_HASH) {
|
||||
const auto &entries = properties->entries();
|
||||
full_keys.reserve(entries.size());
|
||||
values.reserve(entries.size());
|
||||
|
||||
full_keys.emplace_back(key_pool.pool(properties->keys()[i]->string().c_str()));
|
||||
values.push_back(std::move(sv));
|
||||
for (const auto &e : entries) {
|
||||
if (e.key->type == JSON_STRING) {
|
||||
serial_val sv = stringify_value(e.value, sst->fname, sst->line, feature);
|
||||
|
||||
full_keys.emplace_back(key_pool.pool(e.key->string().c_str()));
|
||||
values.push_back(std::move(sv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-36
@@ -134,7 +134,7 @@ static json_object_ptr add_object(json_pull *j, json_type type) {
|
||||
}
|
||||
} else if (c->type == JSON_HASH) {
|
||||
if (c->expect == JSON_VALUE) {
|
||||
c->values().back() = o;
|
||||
c->entries().back().value = o;
|
||||
c->expect = JSON_COMMA;
|
||||
} else if (c->expect == JSON_KEY) {
|
||||
if (type != JSON_STRING) {
|
||||
@@ -142,8 +142,7 @@ static json_object_ptr add_object(json_pull *j, json_type type) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
c->keys().push_back(o);
|
||||
c->values().push_back(nullptr);
|
||||
c->entries().push_back({o, nullptr});
|
||||
c->expect = JSON_COLON;
|
||||
} else {
|
||||
j->error = "Expected a comma or colon";
|
||||
@@ -164,14 +163,9 @@ json_object_ptr json_hash_get(json_object *o, const char *s) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto &keys = o->keys();
|
||||
const auto &vals = o->values();
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
const auto &key = keys[i];
|
||||
if (key != nullptr && key->type == JSON_STRING) {
|
||||
if (key->string() == s) {
|
||||
return vals[i];
|
||||
}
|
||||
for (const auto &e : o->entries()) {
|
||||
if (e.key != nullptr && e.key->type == JSON_STRING && e.key->string() == s) {
|
||||
return e.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +293,7 @@ again:
|
||||
}
|
||||
|
||||
if (cc->expect != JSON_COMMA) {
|
||||
if (!(cc->expect == JSON_KEY && cc->keys().size() == 0)) {
|
||||
if (!(cc->expect == JSON_KEY && cc->entries().size() == 0)) {
|
||||
j->error = "Found } without final element";
|
||||
return nullptr;
|
||||
}
|
||||
@@ -676,11 +670,9 @@ static void clear_back_pointers(json_object *o) {
|
||||
}
|
||||
|
||||
if (o->type == JSON_HASH) {
|
||||
const auto &keys = o->keys();
|
||||
const auto &vals = o->values();
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
clear_back_pointers(keys[i].get());
|
||||
clear_back_pointers(vals[i].get());
|
||||
for (const auto &e : o->entries()) {
|
||||
clear_back_pointers(e.key.get());
|
||||
clear_back_pointers(e.value.get());
|
||||
}
|
||||
} else if (o->type == JSON_ARRAY) {
|
||||
const auto &arr = o->array();
|
||||
@@ -713,28 +705,26 @@ void json_disconnect(json_object_ptr o) {
|
||||
}
|
||||
}
|
||||
} else if (parent->type == JSON_HASH) {
|
||||
auto &keys = parent->keys();
|
||||
auto &vals = parent->values();
|
||||
auto &entries = parent->entries();
|
||||
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
if (keys[i].get() == o.get()) {
|
||||
for (size_t i = 0; i < entries.size(); i++) {
|
||||
auto &e = entries[i];
|
||||
if (e.key.get() == o.get()) {
|
||||
// Leave a NULL placeholder in the key slot so the
|
||||
// surrounding value isn't shifted; if the corresponding
|
||||
// value is also detached the pair is removed below.
|
||||
keys[i] = fabricate_object(parent->parser, parent, JSON_NULL);
|
||||
e.key = fabricate_object(parent->parser, parent, JSON_NULL);
|
||||
|
||||
if (vals[i] != nullptr && vals[i]->type == JSON_NULL && keys[i]->type == JSON_NULL) {
|
||||
keys.erase(keys.begin() + i);
|
||||
vals.erase(vals.begin() + i);
|
||||
if (e.value != nullptr && e.value->type == JSON_NULL && e.key->type == JSON_NULL) {
|
||||
entries.erase(entries.begin() + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (vals[i].get() == o.get()) {
|
||||
vals[i] = fabricate_object(parent->parser, parent, JSON_NULL);
|
||||
if (e.value.get() == o.get()) {
|
||||
e.value = fabricate_object(parent->parser, parent, JSON_NULL);
|
||||
|
||||
if (keys[i] != nullptr && keys[i]->type == JSON_NULL && vals[i]->type == JSON_NULL) {
|
||||
keys.erase(keys.begin() + i);
|
||||
vals.erase(vals.begin() + i);
|
||||
if (e.key != nullptr && e.key->type == JSON_NULL && e.value->type == JSON_NULL) {
|
||||
entries.erase(entries.begin() + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -815,13 +805,12 @@ static void json_print(std::string &val, json_object *o) {
|
||||
} else if (o->type == JSON_HASH) {
|
||||
string_append_c(val, '{');
|
||||
|
||||
const auto &keys = o->keys();
|
||||
const auto &vals = o->values();
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
json_print(val, keys[i].get());
|
||||
const auto &entries = o->entries();
|
||||
for (size_t i = 0; i < entries.size(); i++) {
|
||||
json_print(val, entries[i].key.get());
|
||||
string_append_c(val, ':');
|
||||
json_print(val, vals[i].get());
|
||||
if (i + 1 < keys.size()) {
|
||||
json_print(val, entries[i].value.get());
|
||||
if (i + 1 < entries.size()) {
|
||||
string_append_c(val, ',');
|
||||
}
|
||||
}
|
||||
|
||||
+17
-18
@@ -34,6 +34,16 @@ struct json_pull;
|
||||
typedef std::shared_ptr<json_object> json_object_ptr;
|
||||
typedef std::shared_ptr<json_pull> json_pull_ptr;
|
||||
|
||||
// A single key/value pair inside a JSON_HASH. The pairs are stored in
|
||||
// insertion order in a single std::vector<json_entry> on json_hash, so
|
||||
// callers can range-for over `o->entries()` with structured bindings
|
||||
// (`for (auto &[k, v] : o->entries()) ...`) while still preserving the
|
||||
// order keys appeared in the source document.
|
||||
struct json_entry {
|
||||
json_object_ptr key;
|
||||
json_object_ptr value;
|
||||
};
|
||||
|
||||
// json_object is a small base type that just records the JSON type and
|
||||
// the back-pointers to its parent and parser. The actual value payload
|
||||
// lives in a type-specific subclass (json_number, json_string, json_array,
|
||||
@@ -83,10 +93,8 @@ struct json_object {
|
||||
inline std::vector<json_object_ptr> &array();
|
||||
inline const std::vector<json_object_ptr> &array() const;
|
||||
|
||||
inline std::vector<json_object_ptr> &keys();
|
||||
inline const std::vector<json_object_ptr> &keys() const;
|
||||
inline std::vector<json_object_ptr> &values();
|
||||
inline const std::vector<json_object_ptr> &values() const;
|
||||
inline std::vector<json_entry> &entries();
|
||||
inline const std::vector<json_entry> &entries() const;
|
||||
};
|
||||
|
||||
struct json_number : json_object {
|
||||
@@ -113,8 +121,7 @@ struct json_array : json_object {
|
||||
};
|
||||
|
||||
struct json_hash : json_object {
|
||||
std::vector<json_object_ptr> keys_value;
|
||||
std::vector<json_object_ptr> values_value;
|
||||
std::vector<json_entry> entries_value;
|
||||
|
||||
json_hash() : json_object(JSON_HASH) {}
|
||||
json_hash(json_object *p, json_pull *pl) : json_object(JSON_HASH, p, pl) {}
|
||||
@@ -163,21 +170,13 @@ inline const std::vector<json_object_ptr> &json_object::array() const {
|
||||
return static_cast<const json_array *>(this)->array_value;
|
||||
}
|
||||
|
||||
inline std::vector<json_object_ptr> &json_object::keys() {
|
||||
inline std::vector<json_entry> &json_object::entries() {
|
||||
assert(type == JSON_HASH);
|
||||
return static_cast<json_hash *>(this)->keys_value;
|
||||
return static_cast<json_hash *>(this)->entries_value;
|
||||
}
|
||||
inline const std::vector<json_object_ptr> &json_object::keys() const {
|
||||
inline const std::vector<json_entry> &json_object::entries() const {
|
||||
assert(type == JSON_HASH);
|
||||
return static_cast<const json_hash *>(this)->keys_value;
|
||||
}
|
||||
inline std::vector<json_object_ptr> &json_object::values() {
|
||||
assert(type == JSON_HASH);
|
||||
return static_cast<json_hash *>(this)->values_value;
|
||||
}
|
||||
inline const std::vector<json_object_ptr> &json_object::values() const {
|
||||
assert(type == JSON_HASH);
|
||||
return static_cast<const json_hash *>(this)->values_value;
|
||||
return static_cast<const json_hash *>(this)->entries_value;
|
||||
}
|
||||
|
||||
struct json_pull {
|
||||
|
||||
+2
-4
@@ -298,8 +298,7 @@ void join_csv(json_object_ptr j) {
|
||||
}
|
||||
|
||||
if (fields.size() > 0 && joinkey == fields[0]) {
|
||||
properties->keys().reserve(properties->keys().size() + fields.size());
|
||||
properties->values().reserve(properties->values().size() + fields.size());
|
||||
properties->entries().reserve(properties->entries().size() + fields.size());
|
||||
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
std::string k = header[i];
|
||||
@@ -333,8 +332,7 @@ void join_csv(json_object_ptr j) {
|
||||
abort();
|
||||
}
|
||||
|
||||
properties->keys().push_back(ko);
|
||||
properties->values().push_back(vo);
|
||||
properties->entries().push_back({ko, vo});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2885,17 +2885,16 @@ void set_attribute_value(const char *arg) {
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < o->keys().size(); i++) {
|
||||
json_object_ptr k = o->keys()[i];
|
||||
json_object_ptr v = o->values()[i];
|
||||
|
||||
if (k->type != JSON_STRING) {
|
||||
size_t i = 0;
|
||||
for (const auto &e : o->entries()) {
|
||||
if (e.key->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: --set-attribute %s: key %zu not a string\n", *av, arg, i);
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
serial_val val = stringify_value(v, "json", 1, o);
|
||||
set_attributes.emplace(k->string(), val);
|
||||
serial_val val = stringify_value(e.value, "json", 1, o);
|
||||
set_attributes.emplace(e.key->string(), val);
|
||||
i++;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
+11
-9
@@ -343,18 +343,20 @@ serial_feature parse_feature(json_pull_ptr jp, int z, unsigned x, unsigned y, st
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < properties->keys().size(); i++) {
|
||||
serial_val v = stringify_value(properties->values()[i], "Filter output", jp->line, j);
|
||||
if (properties->type == JSON_HASH) {
|
||||
for (const auto &e : properties->entries()) {
|
||||
serial_val v = stringify_value(e.value, "Filter output", jp->line, j);
|
||||
|
||||
// Nulls can be excluded here because the expression evaluation filter
|
||||
// would have already run before prefiltering
|
||||
// Nulls can be excluded here because the expression evaluation filter
|
||||
// would have already run before prefiltering
|
||||
|
||||
if (v.type != mvt_null) {
|
||||
sf.full_keys.push_back(key_pool.pool(properties->keys()[i]->string()));
|
||||
sf.full_values.push_back(v);
|
||||
if (v.type != mvt_null) {
|
||||
sf.full_keys.push_back(key_pool.pool(e.key->string()));
|
||||
sf.full_values.push_back(v);
|
||||
|
||||
if (!postfilter) {
|
||||
add_to_tilestats(ts->second.tilestats, properties->keys()[i]->string(), v);
|
||||
if (!postfilter) {
|
||||
add_to_tilestats(ts->second.tilestats, e.key->string(), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -415,37 +415,37 @@ sqlite3 *pmtilesmeta2tmp(const char *fname, const char *pmtiles_map) {
|
||||
state.nospace = true;
|
||||
state.json_write_hash();
|
||||
|
||||
for (size_t i = 0; i < o->keys().size(); i++) {
|
||||
const std::string &key = o->keys()[i]->string();
|
||||
if (key == "vector_layers" && o->values()[i]->type == JSON_ARRAY) {
|
||||
for (const auto &e : o->entries()) {
|
||||
const std::string &key = e.key->string();
|
||||
if (key == "vector_layers" && e.value->type == JSON_ARRAY) {
|
||||
has_json = true;
|
||||
state.nospace = true;
|
||||
state.json_write_string("vector_layers");
|
||||
state.nospace = true;
|
||||
state.json_write_json(json_stringify(o->values()[i]));
|
||||
} else if (key == "tilestats" && o->values()[i]->type == JSON_HASH) {
|
||||
state.json_write_json(json_stringify(e.value));
|
||||
} else if (key == "tilestats" && e.value->type == JSON_HASH) {
|
||||
has_json = true;
|
||||
state.nospace = true;
|
||||
state.json_write_string("tilestats");
|
||||
state.nospace = true;
|
||||
state.json_write_json(json_stringify(o->values()[i]));
|
||||
} else if (key == "strategies" && o->values()[i]->type == JSON_ARRAY) {
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('strategies', %Q);", json_stringify(o->values()[i]).c_str());
|
||||
state.json_write_json(json_stringify(e.value));
|
||||
} else if (key == "strategies" && e.value->type == JSON_ARRAY) {
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('strategies', %Q);", json_stringify(e.value).c_str());
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
|
||||
fprintf(stderr, "set %s in metadata: %s\n", key.c_str(), err);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
} else if (key == "tippecanoe_decisions" && o->values()[i]->type == JSON_HASH) {
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('tippecanoe_decisions', %Q);", json_stringify(o->values()[i]).c_str());
|
||||
} else if (key == "tippecanoe_decisions" && e.value->type == JSON_HASH) {
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('tippecanoe_decisions', %Q);", json_stringify(e.value).c_str());
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
|
||||
fprintf(stderr, "set %s in metadata: %s\n", key.c_str(), err);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
} else if (o->keys()[i]->type != JSON_STRING || o->values()[i]->type != JSON_STRING) {
|
||||
} else if (e.key->type != JSON_STRING || e.value->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s\n", key.c_str());
|
||||
fprintf(stderr, "%s: non-string in metadata\n", fname);
|
||||
} else {
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", key.c_str(), o->values()[i]->string().c_str());
|
||||
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", key.c_str(), e.value->string().c_str());
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
|
||||
fprintf(stderr, "set %s in metadata: %s\n", key.c_str(), err);
|
||||
}
|
||||
|
||||
+9
-7
@@ -382,15 +382,17 @@ std::vector<mvt_layer> parse_layers(FILE *fp, int z, unsigned x, unsigned y, int
|
||||
feature.has_id = true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < properties->keys().size(); i++) {
|
||||
serial_val sv = stringify_value(properties->values()[i], "Filter output", jp->line, j);
|
||||
if (properties->type == JSON_HASH) {
|
||||
for (const auto &e : properties->entries()) {
|
||||
serial_val sv = stringify_value(e.value, "Filter output", jp->line, j);
|
||||
|
||||
// Nulls can be excluded here because this is the postfilter
|
||||
// and it is nearly time to create the vector representation
|
||||
// Nulls can be excluded here because this is the postfilter
|
||||
// and it is nearly time to create the vector representation
|
||||
|
||||
if (sv.type != mvt_null) {
|
||||
mvt_value v = stringified_to_mvt_value(sv.type, sv.s.c_str(), tile_stringpool);
|
||||
l->second.tag(feature, properties->keys()[i]->string(), v);
|
||||
if (sv.type != mvt_null) {
|
||||
mvt_value v = stringified_to_mvt_value(sv.type, sv.s.c_str(), tile_stringpool);
|
||||
l->second.tag(feature, e.key->string(), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-20
@@ -972,40 +972,39 @@ void handle_strategies(const unsigned char *s, std::vector<strategy> *st) {
|
||||
for (size_t i = 0; i < o->array().size(); i++) {
|
||||
json_object_ptr h = o->array()[i];
|
||||
if (h->type == JSON_HASH) {
|
||||
for (size_t j = 0; j < h->keys().size(); j++) {
|
||||
json_object_ptr k = h->keys()[j];
|
||||
json_object_ptr v = h->values()[j];
|
||||
|
||||
if (k->type != JSON_STRING) {
|
||||
size_t j = 0;
|
||||
for (const auto &kv : h->entries()) {
|
||||
if (kv.key->type != JSON_STRING) {
|
||||
fprintf(stderr, "Key %zu of %zu is not a string: %s\n", j, i, s);
|
||||
} else if (v->type != JSON_NUMBER) {
|
||||
} else if (kv.value->type != JSON_NUMBER) {
|
||||
fprintf(stderr, "Value %zu of %zu is not a number: %s\n", j, i, s);
|
||||
} else {
|
||||
if (i >= st->size()) {
|
||||
st->resize(i + 1);
|
||||
}
|
||||
|
||||
const std::string &key = k->string();
|
||||
const std::string &key = kv.key->string();
|
||||
if (key == "dropped_by_rate") {
|
||||
(*st)[i].dropped_by_rate += v->number();
|
||||
(*st)[i].dropped_by_rate += kv.value->number();
|
||||
} else if (key == "dropped_by_gamma") {
|
||||
(*st)[i].dropped_by_gamma += v->number();
|
||||
(*st)[i].dropped_by_gamma += kv.value->number();
|
||||
} else if (key == "dropped_as_needed") {
|
||||
(*st)[i].dropped_as_needed += v->number();
|
||||
(*st)[i].dropped_as_needed += kv.value->number();
|
||||
} else if (key == "coalesced_as_needed") {
|
||||
(*st)[i].coalesced_as_needed += v->number();
|
||||
(*st)[i].coalesced_as_needed += kv.value->number();
|
||||
} else if (key == "truncated_zooms") {
|
||||
(*st)[i].truncated_zooms += v->number();
|
||||
(*st)[i].truncated_zooms += kv.value->number();
|
||||
} else if (key == "detail_reduced") {
|
||||
(*st)[i].detail_reduced += v->number();
|
||||
(*st)[i].detail_reduced += kv.value->number();
|
||||
} else if (key == "tiny_polygons") {
|
||||
(*st)[i].tiny_polygons += v->number();
|
||||
(*st)[i].tiny_polygons += kv.value->number();
|
||||
} else if (key == "tile_size_desired") {
|
||||
(*st)[i].tile_size += v->number();
|
||||
(*st)[i].tile_size += kv.value->number();
|
||||
} else if (key == "feature_count_desired") {
|
||||
(*st)[i].feature_count += v->number();
|
||||
(*st)[i].feature_count += kv.value->number();
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Element %zu is not a hash: %s\n", i, s);
|
||||
@@ -1035,15 +1034,15 @@ void handle_vector_layers(json_object_ptr vector_layers, std::map<std::string, l
|
||||
|
||||
json_object_ptr fields = json_hash_get(vector_layers->array()[i], "fields");
|
||||
if (fields != nullptr && fields->type == JSON_HASH) {
|
||||
for (size_t j = 0; j < fields->keys().size(); j++) {
|
||||
if (fields->keys()[j]->type == JSON_STRING && fields->values()[j]->type) {
|
||||
const std::string &desc2 = fields->values()[j]->string();
|
||||
for (const auto &e : fields->entries()) {
|
||||
if (e.key->type == JSON_STRING && e.value->type) {
|
||||
const std::string &desc2 = e.value->string();
|
||||
|
||||
if (desc2 != "Number" &&
|
||||
desc2 != "String" &&
|
||||
desc2 != "Boolean" &&
|
||||
desc2 != "Mixed") {
|
||||
attribute_descriptions.insert(std::pair<std::string, std::string>(fields->keys()[j]->string(), desc2));
|
||||
attribute_descriptions.insert(std::pair<std::string, std::string>(e.key->string(), desc2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user