From 2318673108465de4672d15ab501044bfd8bf52e7 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Tue, 5 Jun 2018 15:01:02 -0700 Subject: [PATCH] Be more systematic about nulls and undefined attribute values It is an error to write a null attribute to a tile, but null attributes found within existing tiles will be decoded into JSON as null. --- mvt.cpp | 15 ++++++++++++++- mvt.hpp | 1 + write_json.cpp | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mvt.cpp b/mvt.cpp index c910044..f5028e7 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -122,6 +122,9 @@ bool mvt_tile::decode(std::string &message, bool &was_compressed) { protozero::pbf_reader value_reader(layer_reader.get_message()); mvt_value value; + value.type = mvt_null; + value.numeric_value.null_value = 0; + while (value_reader.next()) { switch (value_reader.tag()) { case 1: /* string */ @@ -303,6 +306,12 @@ std::string mvt_tile::encode() { value_writer.add_sint64(6, pbv.numeric_value.sint_value); } else if (pbv.type == mvt_bool) { value_writer.add_bool(7, pbv.numeric_value.bool_value); + } else if (pbv.type == mvt_null) { + fprintf(stderr, "Internal error: trying to write null attribute to tile\n"); + exit(EXIT_FAILURE); + } else { + fprintf(stderr, "Internal error: trying to write undefined attribute type to tile\n"); + exit(EXIT_FAILURE); } layer_writer.add_message(4, value_string); @@ -388,7 +397,8 @@ bool mvt_value::operator<(const mvt_value &o) const { (type == mvt_int && numeric_value.int_value < o.numeric_value.int_value) || (type == mvt_uint && numeric_value.uint_value < o.numeric_value.uint_value) || (type == mvt_sint && numeric_value.sint_value < o.numeric_value.sint_value) || - (type == mvt_bool && numeric_value.bool_value < o.numeric_value.bool_value)) { + (type == mvt_bool && numeric_value.bool_value < o.numeric_value.bool_value) || + (type == mvt_null && numeric_value.null_value < o.numeric_value.null_value)) { return true; } } @@ -442,6 +452,8 @@ std::string mvt_value::toString() { return std::to_string(numeric_value.uint_value); } else if (type == mvt_bool) { return numeric_value.bool_value ? "true" : "false"; + } else if (type == mvt_null) { + return "null"; } else { return "unknown"; } @@ -591,6 +603,7 @@ mvt_value stringified_to_mvt_value(int type, const char *s) { tv.numeric_value.bool_value = (s[0] == 't'); } else if (type == mvt_null) { tv.type = mvt_null; + tv.numeric_value.null_value = 0; } else { tv.type = mvt_string; tv.string_value = s; diff --git a/mvt.hpp b/mvt.hpp index 8aa5102..3bfd16e 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -77,6 +77,7 @@ struct mvt_value { unsigned long long uint_value; long long sint_value; bool bool_value; + int null_value; } numeric_value; bool operator<(const mvt_value &o) const; diff --git a/write_json.cpp b/write_json.cpp index c832804..cee0e47 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -337,6 +337,12 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y } else if (val.type == mvt_bool) { state.json_write_string(key); state.json_write_bool(val.numeric_value.bool_value); + } else if (val.type == mvt_null) { + state.json_write_string(key); + state.json_write_null(); + } else { + fprintf(stderr, "Internal error: property with unknown type\n"); + exit(EXIT_FAILURE); } }