diff --git a/CHANGELOG.md b/CHANGELOG.md index e70f9546..76226c7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.29.2 + +* Be careful to remove null attributes from prefilter/postfilter output + ## 1.29.1 * Add --use-source-polygon-winding and --reverse-source-polygon-winding diff --git a/geojson.cpp b/geojson.cpp index 6d54049f..514ecbee 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -341,7 +341,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std:: json_object *id = json_hash_get(j, "id"); json_object *geometries = json_hash_get(geometry, "geometries"); - if (geometries != NULL) { + if (geometries != NULL && geometries->type == JSON_ARRAY) { size_t g; for (g = 0; g < geometries->length; g++) { serialize_geojson_feature(sst, geometries->array[g], properties, id, layer, tippecanoe, j, layername); diff --git a/mvt.cpp b/mvt.cpp index c910044c..f5028e71 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 8aa5102b..3bfd16e3 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/plugin.cpp b/plugin.cpp index 7a395140..b1f54132 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -259,7 +259,11 @@ std::vector parse_layers(int fd, int z, unsigned x, unsigned y, std:: std::string s; stringify_value(properties->values[i], tp, s, "Filter output", jp->line, j); - if (tp >= 0) { + + // Nulls can be excluded here because this is the postfilter + // and it is nearly time to create the vector representation + + if (tp >= 0 && tp != mvt_null) { mvt_value v = stringified_to_mvt_value(tp, s.c_str()); l->second.tag(feature, std::string(properties->keys[i]->string), v); @@ -493,7 +497,10 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std:: stringify_value(properties->values[i], v.type, v.s, "Filter output", jp->line, j); - if (v.type >= 0) { + // Nulls can be excluded here because the expression evaluation filter + // would have already run before prefiltering + + if (v.type >= 0 && v.type != mvt_null) { sf.full_keys.push_back(std::string(properties->keys[i]->string)); sf.full_values.push_back(v); diff --git a/tests/filter/null b/tests/filter/null new file mode 100755 index 00000000..7c3cc98c --- /dev/null +++ b/tests/filter/null @@ -0,0 +1,3 @@ +#!/bin/sh + +echo '{ "type": "Feature", "properties": { "scalerank": 1, "featurecla": "Admin-0 country", "labelrank": 3.000000, "sovereignt": "Afghanistan", "sov_a3": "AFG", "adm0_dif": 0.000000, "level": 2.000000, "type": "Sovereign country", "admin": "Afghanistan", "adm0_a3": "AFG", "geou_dif": 0.000000, "geounit": "Afghanistan", "gu_a3": "AFG", "su_dif": 0.000000, "subunit": "Afghanistan", "su_a3": "AFG", "brk_diff": 0.000000, "name": "Afghanistan", "name_long": "Afghanistan", "brk_a3": "AFG", "brk_name": "Afghanistan", "brk_group": null, "abbrev": "Afg.", "postal": "AF", "formal_en": "Islamic State of Afghanistan", "formal_fr": null, "note_adm0": null, "note_brk": null, "name_sort": "Afghanistan", "name_alt": null, "mapcolor7": 5.000000, "mapcolor8": 6.000000, "mapcolor9": 8.000000, "mapcolor13": 7.000000, "pop_est": 28400000.000000, "gdp_md_est": 22270.000000, "pop_year": -99.000000, "lastcensus": 1979.000000, "gdp_year": -99.000000, "economy": "7. Least developed region", "income_grp": "5. Low income", "wikipedia": -99.000000, "fips_10": null, "iso_a2": "AF", "iso_a3": "AFG", "iso_n3": "004", "un_a3": "004", "wb_a2": "AF", "wb_a3": "AFG", "woe_id": -99.000000, "adm0_a3_is": "AFG", "adm0_a3_us": "AFG", "adm0_a3_un": -99.000000, "adm0_a3_wb": -99.000000, "continent": "Asia", "region_un": "Asia", "subregion": "Southern Asia", "region_wb": "South Asia", "name_len": 11.000000, "long_len": 11.000000, "abbrev_len": 4.000000, "tiny": -99.000000, "homepart": 1.000000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 61.210817, 35.650072 ], [ 62.230651, 35.270663 ], [ 62.984662, 35.404040 ], [ 63.193538, 35.857165 ], [ 63.982895, 36.007957 ], [ 64.546479, 36.312073 ], [ 64.746105, 37.111817 ], [ 65.588947, 37.305216 ], [ 65.745630, 37.661164 ], [ 66.217384, 37.393790 ], [ 66.518606, 37.362784 ], [ 67.075782, 37.356143 ], [ 67.829999, 37.144994 ], [ 68.135562, 37.023115 ], [ 68.859445, 37.344335 ], [ 69.196272, 37.151143 ], [ 69.518785, 37.608996 ], [ 70.116578, 37.588222 ], [ 70.270574, 37.735164 ], [ 70.376304, 38.138395 ], [ 70.806820, 38.486281 ], [ 71.348131, 38.258905 ], [ 71.239403, 37.953265 ], [ 71.541917, 37.905774 ], [ 71.448693, 37.065644 ], [ 71.844638, 36.738171 ], [ 72.193040, 36.948287 ], [ 72.636889, 37.047558 ], [ 73.260055, 37.495256 ], [ 73.948695, 37.421566 ], [ 74.980002, 37.419990 ], [ 75.158027, 37.133030 ], [ 74.575892, 37.020841 ], [ 74.067551, 36.836175 ], [ 72.920024, 36.720007 ], [ 71.846291, 36.509942 ], [ 71.262348, 36.074387 ], [ 71.498767, 35.650563 ], [ 71.613076, 35.153203 ], [ 71.115018, 34.733125 ], [ 71.156773, 34.348911 ], [ 70.881803, 33.988855 ], [ 69.930543, 34.020120 ], [ 70.323594, 33.358532 ], [ 69.687147, 33.105498 ], [ 69.262522, 32.501944 ], [ 69.317764, 31.901412 ], [ 68.926676, 31.620189 ], [ 68.556932, 31.713310 ], [ 67.792689, 31.582930 ], [ 67.683393, 31.303154 ], [ 66.938891, 31.304911 ], [ 66.381457, 30.738899 ], [ 66.346472, 29.887943 ], [ 65.046862, 29.472180 ], [ 64.350418, 29.560030 ], [ 64.148002, 29.340819 ], [ 63.550260, 29.468330 ], [ 62.549856, 29.318572 ], [ 60.874248, 29.829238 ], [ 61.781221, 30.735850 ], [ 61.699314, 31.379506 ], [ 60.941944, 31.548074 ], [ 60.863654, 32.182919 ], [ 60.536077, 32.981268 ], [ 60.963700, 33.528832 ], [ 60.528429, 33.676446 ], [ 60.803193, 34.404101 ], [ 61.210817, 35.650072 ] ] ] } }' diff --git a/tests/ne_110m_populated_places/out/-yNAME_-z0_-c.%tests%filter%null.json b/tests/ne_110m_populated_places/out/-yNAME_-z0_-c.%tests%filter%null.json new file mode 100644 index 00000000..af4c5cb1 --- /dev/null +++ b/tests/ne_110m_populated_places/out/-yNAME_-z0_-c.%tests%filter%null.json @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "-175.220564,-41.299973,179.216647,64.150023", +"center": "0.000000,0.000000,0", +"description": "tests/ne_110m_populated_places/out/-yNAME_-z0_-c.%tests%filter%null.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"unknown\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {\"abbrev\": \"String\", \"abbrev_len\": \"Number\", \"adm0_a3\": \"String\", \"adm0_a3_is\": \"String\", \"adm0_a3_un\": \"Number\", \"adm0_a3_us\": \"String\", \"adm0_a3_wb\": \"Number\", \"adm0_dif\": \"Number\", \"admin\": \"String\", \"brk_a3\": \"String\", \"brk_diff\": \"Number\", \"brk_name\": \"String\", \"continent\": \"String\", \"economy\": \"String\", \"featurecla\": \"String\", \"formal_en\": \"String\", \"gdp_md_est\": \"Number\", \"gdp_year\": \"Number\", \"geou_dif\": \"Number\", \"geounit\": \"String\", \"gu_a3\": \"String\", \"homepart\": \"Number\", \"income_grp\": \"String\", \"iso_a2\": \"String\", \"iso_a3\": \"String\", \"iso_n3\": \"String\", \"labelrank\": \"Number\", \"lastcensus\": \"Number\", \"level\": \"Number\", \"long_len\": \"Number\", \"mapcolor13\": \"Number\", \"mapcolor7\": \"Number\", \"mapcolor8\": \"Number\", \"mapcolor9\": \"Number\", \"name\": \"String\", \"name_len\": \"Number\", \"name_long\": \"String\", \"name_sort\": \"String\", \"pop_est\": \"Number\", \"pop_year\": \"Number\", \"postal\": \"String\", \"region_un\": \"String\", \"region_wb\": \"String\", \"scalerank\": \"Number\", \"sov_a3\": \"String\", \"sovereignt\": \"String\", \"su_a3\": \"String\", \"su_dif\": \"Number\", \"subregion\": \"String\", \"subunit\": \"String\", \"tiny\": \"Number\", \"type\": \"String\", \"un_a3\": \"String\", \"wb_a2\": \"String\", \"wb_a3\": \"String\", \"wikipedia\": \"Number\", \"woe_id\": \"Number\"} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"unknown\",\"count\": 1,\"geometry\": \"Polygon\",\"attributeCount\": 57,\"attributes\": [{\"attribute\": \"abbrev\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afg.\"]},{\"attribute\": \"abbrev_len\",\"count\": 1,\"type\": \"number\",\"values\": [4],\"min\": 4,\"max\": 4},{\"attribute\": \"adm0_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_is\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_un\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"adm0_a3_us\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_wb\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"adm0_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"admin\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"brk_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"brk_diff\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"brk_name\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"continent\",\"count\": 1,\"type\": \"string\",\"values\": [\"Asia\"]},{\"attribute\": \"economy\",\"count\": 1,\"type\": \"string\",\"values\": [\"7. Least developed region\"]},{\"attribute\": \"featurecla\",\"count\": 1,\"type\": \"string\",\"values\": [\"Admin-0 country\"]},{\"attribute\": \"formal_en\",\"count\": 1,\"type\": \"string\",\"values\": [\"Islamic State of Afghanistan\"]},{\"attribute\": \"gdp_md_est\",\"count\": 1,\"type\": \"number\",\"values\": [22270],\"min\": 22270,\"max\": 22270},{\"attribute\": \"gdp_year\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"geou_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"geounit\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"gu_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"homepart\",\"count\": 1,\"type\": \"number\",\"values\": [1],\"min\": 1,\"max\": 1},{\"attribute\": \"income_grp\",\"count\": 1,\"type\": \"string\",\"values\": [\"5. Low income\"]},{\"attribute\": \"iso_a2\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"iso_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"iso_n3\",\"count\": 1,\"type\": \"string\",\"values\": [\"004\"]},{\"attribute\": \"labelrank\",\"count\": 1,\"type\": \"number\",\"values\": [3],\"min\": 3,\"max\": 3},{\"attribute\": \"lastcensus\",\"count\": 1,\"type\": \"number\",\"values\": [1979],\"min\": 1979,\"max\": 1979},{\"attribute\": \"level\",\"count\": 1,\"type\": \"number\",\"values\": [2],\"min\": 2,\"max\": 2},{\"attribute\": \"long_len\",\"count\": 1,\"type\": \"number\",\"values\": [11],\"min\": 11,\"max\": 11},{\"attribute\": \"mapcolor13\",\"count\": 1,\"type\": \"number\",\"values\": [7],\"min\": 7,\"max\": 7},{\"attribute\": \"mapcolor7\",\"count\": 1,\"type\": \"number\",\"values\": [5],\"min\": 5,\"max\": 5},{\"attribute\": \"mapcolor8\",\"count\": 1,\"type\": \"number\",\"values\": [6],\"min\": 6,\"max\": 6},{\"attribute\": \"mapcolor9\",\"count\": 1,\"type\": \"number\",\"values\": [8],\"min\": 8,\"max\": 8},{\"attribute\": \"name\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"name_len\",\"count\": 1,\"type\": \"number\",\"values\": [11],\"min\": 11,\"max\": 11},{\"attribute\": \"name_long\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"name_sort\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"pop_est\",\"count\": 1,\"type\": \"number\",\"values\": [28400000],\"min\": 28400000,\"max\": 28400000},{\"attribute\": \"pop_year\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"postal\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"region_un\",\"count\": 1,\"type\": \"string\",\"values\": [\"Asia\"]},{\"attribute\": \"region_wb\",\"count\": 1,\"type\": \"string\",\"values\": [\"South Asia\"]},{\"attribute\": \"scalerank\",\"count\": 1,\"type\": \"number\",\"values\": [1],\"min\": 1,\"max\": 1},{\"attribute\": \"sov_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"sovereignt\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"su_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"su_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"subregion\",\"count\": 1,\"type\": \"string\",\"values\": [\"Southern Asia\"]},{\"attribute\": \"subunit\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"tiny\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"type\",\"count\": 1,\"type\": \"string\",\"values\": [\"Sovereign country\"]},{\"attribute\": \"un_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"004\"]},{\"attribute\": \"wb_a2\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"wb_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"wikipedia\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"woe_id\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99}]}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/ne_110m_populated_places/out/-yNAME_-z0_-c.%tests%filter%null.json.check.mbtiles", +"type": "overlay", +"version": "2" +}, "features": [ +{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "unknown", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "scalerank": 1, "featurecla": "Admin-0 country", "labelrank": 3, "sovereignt": "Afghanistan", "sov_a3": "AFG", "adm0_dif": 0, "level": 2, "type": "Sovereign country", "admin": "Afghanistan", "adm0_a3": "AFG", "geou_dif": 0, "geounit": "Afghanistan", "gu_a3": "AFG", "su_dif": 0, "subunit": "Afghanistan", "su_a3": "AFG", "brk_diff": 0, "name": "Afghanistan", "name_long": "Afghanistan", "brk_a3": "AFG", "brk_name": "Afghanistan", "abbrev": "Afg.", "postal": "AF", "formal_en": "Islamic State of Afghanistan", "name_sort": "Afghanistan", "mapcolor7": 5, "mapcolor8": 6, "mapcolor9": 8, "mapcolor13": 7, "pop_est": 28400000, "gdp_md_est": 22270, "pop_year": -99, "lastcensus": 1979, "gdp_year": -99, "economy": "7. Least developed region", "income_grp": "5. Low income", "wikipedia": -99, "iso_a2": "AF", "iso_a3": "AFG", "iso_n3": "004", "un_a3": "004", "wb_a2": "AF", "wb_a3": "AFG", "woe_id": -99, "adm0_a3_is": "AFG", "adm0_a3_us": "AFG", "adm0_a3_un": -99, "adm0_a3_wb": -99, "continent": "Asia", "region_un": "Asia", "subregion": "Southern Asia", "region_wb": "South Asia", "name_len": 11, "long_len": 11, "abbrev_len": 4, "tiny": -99, "homepart": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 70.839844, 38.479395 ], [ 71.367188, 38.272689 ], [ 71.279297, 37.926868 ], [ 71.542969, 37.926868 ], [ 71.455078, 37.090240 ], [ 71.806641, 36.738884 ], [ 72.158203, 36.949892 ], [ 72.597656, 37.020098 ], [ 73.300781, 37.509726 ], [ 73.916016, 37.439974 ], [ 74.970703, 37.439974 ], [ 75.146484, 37.160317 ], [ 74.619141, 37.020098 ], [ 74.091797, 36.809285 ], [ 72.949219, 36.738884 ], [ 71.806641, 36.527295 ], [ 71.279297, 36.102376 ], [ 71.455078, 35.675147 ], [ 71.630859, 35.173808 ], [ 71.103516, 34.741612 ], [ 71.191406, 34.379713 ], [ 70.839844, 34.016242 ], [ 69.960938, 34.016242 ], [ 70.312500, 33.358062 ], [ 69.697266, 33.137551 ], [ 69.257812, 32.472695 ], [ 69.345703, 31.877558 ], [ 68.906250, 31.653381 ], [ 68.554688, 31.728167 ], [ 67.763672, 31.578535 ], [ 67.675781, 31.278551 ], [ 66.972656, 31.278551 ], [ 66.357422, 30.751278 ], [ 66.357422, 29.916852 ], [ 65.039062, 29.458731 ], [ 64.335938, 29.535230 ], [ 64.160156, 29.305561 ], [ 63.544922, 29.458731 ], [ 62.578125, 29.305561 ], [ 60.908203, 29.840644 ], [ 61.787109, 30.751278 ], [ 61.699219, 31.353637 ], [ 60.908203, 31.578535 ], [ 60.820312, 32.175612 ], [ 60.556641, 32.990236 ], [ 60.996094, 33.504759 ], [ 60.556641, 33.651208 ], [ 60.820312, 34.379713 ], [ 61.171875, 35.675147 ], [ 62.226562, 35.245619 ], [ 63.017578, 35.389050 ], [ 63.193359, 35.889050 ], [ 63.984375, 36.031332 ], [ 64.511719, 36.315125 ], [ 64.775391, 37.090240 ], [ 65.566406, 37.300275 ], [ 65.742188, 37.649034 ], [ 66.181641, 37.370157 ], [ 67.060547, 37.370157 ], [ 67.851562, 37.160317 ], [ 68.115234, 37.020098 ], [ 68.818359, 37.370157 ], [ 69.169922, 37.160317 ], [ 69.521484, 37.579413 ], [ 70.136719, 37.579413 ], [ 70.312500, 37.718590 ], [ 70.400391, 38.134557 ], [ 70.839844, 38.479395 ] ] ] } } +] } +] } +] } diff --git a/tests/ne_110m_populated_places/out/-z0_-C.%tests%filter%null.json b/tests/ne_110m_populated_places/out/-z0_-C.%tests%filter%null.json new file mode 100644 index 00000000..1ea4d48a --- /dev/null +++ b/tests/ne_110m_populated_places/out/-z0_-C.%tests%filter%null.json @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "-175.220564,-41.299973,179.216647,64.150023", +"center": "0.000000,0.000000,0", +"description": "tests/ne_110m_populated_places/out/-z0_-C.%tests%filter%null.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"unknown\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {\"abbrev\": \"String\", \"abbrev_len\": \"Number\", \"adm0_a3\": \"String\", \"adm0_a3_is\": \"String\", \"adm0_a3_un\": \"Number\", \"adm0_a3_us\": \"String\", \"adm0_a3_wb\": \"Number\", \"adm0_dif\": \"Number\", \"admin\": \"String\", \"brk_a3\": \"String\", \"brk_diff\": \"Number\", \"brk_name\": \"String\", \"continent\": \"String\", \"economy\": \"String\", \"featurecla\": \"String\", \"formal_en\": \"String\", \"gdp_md_est\": \"Number\", \"gdp_year\": \"Number\", \"geou_dif\": \"Number\", \"geounit\": \"String\", \"gu_a3\": \"String\", \"homepart\": \"Number\", \"income_grp\": \"String\", \"iso_a2\": \"String\", \"iso_a3\": \"String\", \"iso_n3\": \"String\", \"labelrank\": \"Number\", \"lastcensus\": \"Number\", \"level\": \"Number\", \"long_len\": \"Number\", \"mapcolor13\": \"Number\", \"mapcolor7\": \"Number\", \"mapcolor8\": \"Number\", \"mapcolor9\": \"Number\", \"name\": \"String\", \"name_len\": \"Number\", \"name_long\": \"String\", \"name_sort\": \"String\", \"pop_est\": \"Number\", \"pop_year\": \"Number\", \"postal\": \"String\", \"region_un\": \"String\", \"region_wb\": \"String\", \"scalerank\": \"Number\", \"sov_a3\": \"String\", \"sovereignt\": \"String\", \"su_a3\": \"String\", \"su_dif\": \"Number\", \"subregion\": \"String\", \"subunit\": \"String\", \"tiny\": \"Number\", \"type\": \"String\", \"un_a3\": \"String\", \"wb_a2\": \"String\", \"wb_a3\": \"String\", \"wikipedia\": \"Number\", \"woe_id\": \"Number\"} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"unknown\",\"count\": 1,\"geometry\": \"Polygon\",\"attributeCount\": 57,\"attributes\": [{\"attribute\": \"abbrev\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afg.\"]},{\"attribute\": \"abbrev_len\",\"count\": 1,\"type\": \"number\",\"values\": [4],\"min\": 4,\"max\": 4},{\"attribute\": \"adm0_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_is\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_un\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"adm0_a3_us\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"adm0_a3_wb\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"adm0_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"admin\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"brk_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"brk_diff\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"brk_name\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"continent\",\"count\": 1,\"type\": \"string\",\"values\": [\"Asia\"]},{\"attribute\": \"economy\",\"count\": 1,\"type\": \"string\",\"values\": [\"7. Least developed region\"]},{\"attribute\": \"featurecla\",\"count\": 1,\"type\": \"string\",\"values\": [\"Admin-0 country\"]},{\"attribute\": \"formal_en\",\"count\": 1,\"type\": \"string\",\"values\": [\"Islamic State of Afghanistan\"]},{\"attribute\": \"gdp_md_est\",\"count\": 1,\"type\": \"number\",\"values\": [22270],\"min\": 22270,\"max\": 22270},{\"attribute\": \"gdp_year\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"geou_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"geounit\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"gu_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"homepart\",\"count\": 1,\"type\": \"number\",\"values\": [1],\"min\": 1,\"max\": 1},{\"attribute\": \"income_grp\",\"count\": 1,\"type\": \"string\",\"values\": [\"5. Low income\"]},{\"attribute\": \"iso_a2\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"iso_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"iso_n3\",\"count\": 1,\"type\": \"string\",\"values\": [\"004\"]},{\"attribute\": \"labelrank\",\"count\": 1,\"type\": \"number\",\"values\": [3],\"min\": 3,\"max\": 3},{\"attribute\": \"lastcensus\",\"count\": 1,\"type\": \"number\",\"values\": [1979],\"min\": 1979,\"max\": 1979},{\"attribute\": \"level\",\"count\": 1,\"type\": \"number\",\"values\": [2],\"min\": 2,\"max\": 2},{\"attribute\": \"long_len\",\"count\": 1,\"type\": \"number\",\"values\": [11],\"min\": 11,\"max\": 11},{\"attribute\": \"mapcolor13\",\"count\": 1,\"type\": \"number\",\"values\": [7],\"min\": 7,\"max\": 7},{\"attribute\": \"mapcolor7\",\"count\": 1,\"type\": \"number\",\"values\": [5],\"min\": 5,\"max\": 5},{\"attribute\": \"mapcolor8\",\"count\": 1,\"type\": \"number\",\"values\": [6],\"min\": 6,\"max\": 6},{\"attribute\": \"mapcolor9\",\"count\": 1,\"type\": \"number\",\"values\": [8],\"min\": 8,\"max\": 8},{\"attribute\": \"name\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"name_len\",\"count\": 1,\"type\": \"number\",\"values\": [11],\"min\": 11,\"max\": 11},{\"attribute\": \"name_long\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"name_sort\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"pop_est\",\"count\": 1,\"type\": \"number\",\"values\": [28400000],\"min\": 28400000,\"max\": 28400000},{\"attribute\": \"pop_year\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"postal\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"region_un\",\"count\": 1,\"type\": \"string\",\"values\": [\"Asia\"]},{\"attribute\": \"region_wb\",\"count\": 1,\"type\": \"string\",\"values\": [\"South Asia\"]},{\"attribute\": \"scalerank\",\"count\": 1,\"type\": \"number\",\"values\": [1],\"min\": 1,\"max\": 1},{\"attribute\": \"sov_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"sovereignt\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"su_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"su_dif\",\"count\": 1,\"type\": \"number\",\"values\": [0],\"min\": 0,\"max\": 0},{\"attribute\": \"subregion\",\"count\": 1,\"type\": \"string\",\"values\": [\"Southern Asia\"]},{\"attribute\": \"subunit\",\"count\": 1,\"type\": \"string\",\"values\": [\"Afghanistan\"]},{\"attribute\": \"tiny\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"type\",\"count\": 1,\"type\": \"string\",\"values\": [\"Sovereign country\"]},{\"attribute\": \"un_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"004\"]},{\"attribute\": \"wb_a2\",\"count\": 1,\"type\": \"string\",\"values\": [\"AF\"]},{\"attribute\": \"wb_a3\",\"count\": 1,\"type\": \"string\",\"values\": [\"AFG\"]},{\"attribute\": \"wikipedia\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99},{\"attribute\": \"woe_id\",\"count\": 1,\"type\": \"number\",\"values\": [-99],\"min\": -99,\"max\": -99}]}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/ne_110m_populated_places/out/-z0_-C.%tests%filter%null.json.check.mbtiles", +"type": "overlay", +"version": "2" +}, "features": [ +{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "unknown", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "scalerank": 1, "featurecla": "Admin-0 country", "labelrank": 3, "sovereignt": "Afghanistan", "sov_a3": "AFG", "adm0_dif": 0, "level": 2, "type": "Sovereign country", "admin": "Afghanistan", "adm0_a3": "AFG", "geou_dif": 0, "geounit": "Afghanistan", "gu_a3": "AFG", "su_dif": 0, "subunit": "Afghanistan", "su_a3": "AFG", "brk_diff": 0, "name": "Afghanistan", "name_long": "Afghanistan", "brk_a3": "AFG", "brk_name": "Afghanistan", "abbrev": "Afg.", "postal": "AF", "formal_en": "Islamic State of Afghanistan", "name_sort": "Afghanistan", "mapcolor7": 5, "mapcolor8": 6, "mapcolor9": 8, "mapcolor13": 7, "pop_est": 28400000, "gdp_md_est": 22270, "pop_year": -99, "lastcensus": 1979, "gdp_year": -99, "economy": "7. Least developed region", "income_grp": "5. Low income", "wikipedia": -99, "iso_a2": "AF", "iso_a3": "AFG", "iso_n3": "004", "un_a3": "004", "wb_a2": "AF", "wb_a3": "AFG", "woe_id": -99, "adm0_a3_is": "AFG", "adm0_a3_us": "AFG", "adm0_a3_un": -99, "adm0_a3_wb": -99, "continent": "Asia", "region_un": "Asia", "subregion": "Southern Asia", "region_wb": "South Asia", "name_len": 11, "long_len": 11, "abbrev_len": 4, "tiny": -99, "homepart": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 70.839844, 38.479395 ], [ 71.367188, 38.272689 ], [ 71.279297, 37.926868 ], [ 71.542969, 37.926868 ], [ 71.455078, 37.090240 ], [ 71.806641, 36.738884 ], [ 72.158203, 36.949892 ], [ 72.597656, 37.020098 ], [ 73.300781, 37.509726 ], [ 74.970703, 37.439974 ], [ 75.146484, 37.160317 ], [ 74.091797, 36.809285 ], [ 71.806641, 36.527295 ], [ 71.279297, 36.102376 ], [ 71.630859, 35.173808 ], [ 71.103516, 34.741612 ], [ 71.191406, 34.379713 ], [ 70.839844, 34.016242 ], [ 69.960938, 34.016242 ], [ 70.312500, 33.358062 ], [ 69.697266, 33.137551 ], [ 69.257812, 32.472695 ], [ 69.345703, 31.877558 ], [ 68.906250, 31.653381 ], [ 68.554688, 31.728167 ], [ 67.763672, 31.578535 ], [ 67.675781, 31.278551 ], [ 66.972656, 31.278551 ], [ 66.357422, 30.751278 ], [ 66.357422, 29.916852 ], [ 65.039062, 29.458731 ], [ 64.335938, 29.535230 ], [ 64.160156, 29.305561 ], [ 63.544922, 29.458731 ], [ 62.578125, 29.305561 ], [ 60.908203, 29.840644 ], [ 61.787109, 30.751278 ], [ 61.699219, 31.353637 ], [ 60.908203, 31.578535 ], [ 60.556641, 32.990236 ], [ 60.996094, 33.504759 ], [ 60.556641, 33.651208 ], [ 61.171875, 35.675147 ], [ 62.226562, 35.245619 ], [ 63.017578, 35.389050 ], [ 63.193359, 35.889050 ], [ 63.984375, 36.031332 ], [ 64.511719, 36.315125 ], [ 64.775391, 37.090240 ], [ 65.566406, 37.300275 ], [ 65.742188, 37.649034 ], [ 66.181641, 37.370157 ], [ 67.060547, 37.370157 ], [ 68.115234, 37.020098 ], [ 68.818359, 37.370157 ], [ 69.169922, 37.160317 ], [ 69.521484, 37.579413 ], [ 70.136719, 37.579413 ], [ 70.312500, 37.718590 ], [ 70.400391, 38.134557 ], [ 70.839844, 38.479395 ] ] ] } } +] } +] } +] } diff --git a/tile.cpp b/tile.cpp index 55be6dac..1ef626d2 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1388,7 +1388,7 @@ serial_feature next_feature(FILE *geoms, std::atomic *geompos_in, cha sf.dropped = true; } - // Remove nulls, now that the filter has run + // Remove nulls, now that the expression evaluation filter has run for (ssize_t i = (ssize_t) sf.keys.size() - 1; i >= 0; i--) { int type = (stringpool + pool_off[sf.segment])[sf.values[i]]; diff --git a/version.hpp b/version.hpp index a3433c95..894b19fb 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "tippecanoe v1.29.1\n" +#define VERSION "tippecanoe v1.29.2\n" #endif diff --git a/write_json.cpp b/write_json.cpp index c832804d..cee0e472 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); } }