From 0c650b881a3338249958f710b3be6b6aa5fe0f8f Mon Sep 17 00:00:00 2001 From: Denis Stadnikov <37743611+Den2505@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:42:57 +0600 Subject: [PATCH] Preserve numeric property types for FlatGeobuf input (#395) Fix FlatGeobuf numeric property types Co-authored-by: dstadnikov --- Makefile | 8 +++++++- flatgeobuf.cpp | 20 ++++++++++---------- tests/flatgeobuf/numeric-properties.fgb | Bin 0 -> 720 bytes tests/flatgeobuf/numeric-properties.json | 5 +++++ 4 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 tests/flatgeobuf/numeric-properties.fgb create mode 100644 tests/flatgeobuf/numeric-properties.json diff --git a/Makefile b/Makefile index 0b988399..a7ee214e 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ indent: TESTS = $(wildcard tests/*/out/*.json) SPACE = $(NULL) $(NULL) -test: tippecanoe tippecanoe-decode $(addsuffix .check,$(TESTS)) raw-tiles-test parallel-test pbf-test join-test enumerate-test decode-test join-filter-test unit json-tool-test allow-existing-test csv-test layer-json-test pmtiles-test decode-pmtiles-test overzoom-test +test: tippecanoe tippecanoe-decode $(addsuffix .check,$(TESTS)) raw-tiles-test parallel-test pbf-test join-test enumerate-test decode-test join-filter-test unit json-tool-test allow-existing-test csv-test layer-json-test pmtiles-test decode-pmtiles-test overzoom-test flatgeobuf-test ./unit suffixes = json json.gz @@ -572,6 +572,12 @@ csv-test: tippecanoe tippecanoe-decode cmp tests/csv/out.mbtiles.json.check tests/csv/out.mbtiles.json rm -f tests/csv/out.mbtiles.json.check tests/csv/out.mbtiles +flatgeobuf-test: tippecanoe tippecanoe-decode + ./tippecanoe -q -f -z0 -l numeric-properties -o tests/flatgeobuf/numeric-properties.mbtiles tests/flatgeobuf/numeric-properties.fgb + ./tippecanoe-decode tests/flatgeobuf/numeric-properties.mbtiles 0 0 0 > tests/flatgeobuf/numeric-properties.json.check + cmp tests/flatgeobuf/numeric-properties.json.check tests/flatgeobuf/numeric-properties.json + rm -f tests/flatgeobuf/numeric-properties.mbtiles tests/flatgeobuf/numeric-properties.json.check + layer-json-test: tippecanoe tippecanoe-decode # GeoJSON with description and named layer ./tippecanoe -q -z0 -r1 -yNAME -f -o tests/layer-json/out.mbtiles -L'{"file":"tests/ne_110m_populated_places/in.json", "description":"World cities", "layer":"places"}' diff --git a/flatgeobuf.cpp b/flatgeobuf.cpp index 571bb8fb..c081128f 100644 --- a/flatgeobuf.cpp +++ b/flatgeobuf.cpp @@ -163,13 +163,13 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_ serial_val sv; if (col_type == FlatGeobuf::ColumnType_Byte) { - sv.type = mvt_sint; + sv.type = mvt_double; int8_t byte_val; memcpy(&byte_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(byte_val)); sv.s = std::to_string(byte_val); p_pos += sizeof(uint16_t) + sizeof(byte_val); } else if (col_type == FlatGeobuf::ColumnType_UByte) { - sv.type = mvt_uint; + sv.type = mvt_double; uint8_t ubyte_val; memcpy(&ubyte_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(ubyte_val)); sv.s = std::to_string(ubyte_val); @@ -185,43 +185,43 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_ } p_pos += sizeof(uint16_t) + sizeof(bool_val); } else if (col_type == FlatGeobuf::ColumnType_Short) { - sv.type = mvt_sint; + sv.type = mvt_double; int16_t short_val; memcpy(&short_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(short_val)); sv.s = std::to_string(short_val); p_pos += sizeof(uint16_t) + sizeof(short_val); } else if (col_type == FlatGeobuf::ColumnType_UShort) { - sv.type = mvt_uint; + sv.type = mvt_double; uint16_t ushort_val; memcpy(&ushort_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(ushort_val)); sv.s = std::to_string(ushort_val); p_pos += sizeof(uint16_t) + sizeof(ushort_val); } else if (col_type == FlatGeobuf::ColumnType_Int) { - sv.type = mvt_sint; + sv.type = mvt_double; int32_t int_val; memcpy(&int_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(int_val)); sv.s = std::to_string(int_val); p_pos += sizeof(uint16_t) + sizeof(int_val); } else if (col_type == FlatGeobuf::ColumnType_UInt) { - sv.type = mvt_uint; + sv.type = mvt_double; uint32_t uint_val; memcpy(&uint_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(uint_val)); sv.s = std::to_string(uint_val); p_pos += sizeof(uint16_t) + sizeof(uint_val); } else if (col_type == FlatGeobuf::ColumnType_Long) { - sv.type = mvt_sint; + sv.type = mvt_double; int64_t long_val; memcpy(&long_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(long_val)); sv.s = std::to_string(long_val); p_pos += sizeof(uint16_t) + sizeof(long_val); } else if (col_type == FlatGeobuf::ColumnType_ULong) { - sv.type = mvt_uint; - int64_t ulong_val; + sv.type = mvt_double; + uint64_t ulong_val; memcpy(&ulong_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(ulong_val)); sv.s = std::to_string(ulong_val); p_pos += sizeof(uint16_t) + sizeof(ulong_val); } else if (col_type == FlatGeobuf::ColumnType_Float) { - sv.type = mvt_float; + sv.type = mvt_double; float float_val; memcpy(&float_val, feature->properties()->data() + p_pos + sizeof(uint16_t), sizeof(float_val)); sv.s = milo::dtoa_milo(float_val); diff --git a/tests/flatgeobuf/numeric-properties.fgb b/tests/flatgeobuf/numeric-properties.fgb new file mode 100644 index 0000000000000000000000000000000000000000..b86506462bcbbc755c617b228785c2759c62e062 GIT binary patch literal 720 zcmaiyzfQtX6vj`Xl=5dV#({x>fwc*R3YwV6;1f8TKr5v-mX?&(;KtzK;OMS{Bah(d zz!Ufc#P}4}@7&u?4xZ$@J?H%HIX$-dWqBiN&q)HwW9ncYJ)Z$nn z3h=mqnli*H{VmudG=;`c2U4Lu_y_a`JwQ`v45`q6c8CpOx^QFv+E~WX(v1_}T@ii% zWEoI{d(^=FeiJ4jvh%>=76;~8gB>I7~4m^Yw#5ZOtN$CByHYET+Pp*LCB zYxq}^Rhj9KM1BaD){ zQ79{sQii8emWiKaqruBEKAf