mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-04-15 22:56:43 +00:00
Fix and test round trip of compound attributes through tile-join
This commit is contained in:
parent
c2b7d36b1f
commit
1ca0d0017e
14
Makefile
14
Makefile
@ -52,10 +52,10 @@ tippecanoe: geojson.o jsonpull/jsonpull.o tile.o pool.o mbtiles.o geometry.o pro
|
||||
tippecanoe-enumerate: enumerate.o
|
||||
$(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lsqlite3
|
||||
|
||||
tippecanoe-decode: decode.o projection.o mvt.o write_json.o
|
||||
tippecanoe-decode: decode.o projection.o mvt.o write_json.o text.o
|
||||
$(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3
|
||||
|
||||
tile-join: tile-join.o projection.o pool.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o
|
||||
tile-join: tile-join.o projection.o pool.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o write_json.o
|
||||
$(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread
|
||||
|
||||
unit: unit.o text.o
|
||||
@ -78,7 +78,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 unit
|
||||
test: tippecanoe tippecanoe-decode $(addsuffix .check,$(TESTS)) raw-tiles-test parallel-test pbf-test join-test enumerate-test decode-test unit join-test-object
|
||||
./unit
|
||||
|
||||
# Work around Makefile and filename punctuation limits: _ for space, @ for :, % for /
|
||||
@ -199,6 +199,14 @@ join-test:
|
||||
rm tests/join-population/tabblock_06001420.mbtiles tests/join-population/joined.mbtiles tests/join-population/joined-i.mbtiles tests/join-population/joined.mbtiles.json.check tests/join-population/joined-i.mbtiles.json.check tests/join-population/macarthur.mbtiles tests/join-population/merged.mbtiles tests/join-population/merged.mbtiles.json.check tests/join-population/merged-folder.mbtiles tests/join-population/macarthur2.mbtiles tests/join-population/windows.mbtiles tests/join-population/windows-merged.mbtiles tests/join-population/windows-merged2.mbtiles tests/join-population/windows.mbtiles.json.check tests/join-population/just-macarthur.mbtiles tests/join-population/no-macarthur.mbtiles tests/join-population/just-macarthur.mbtiles.json.check tests/join-population/no-macarthur.mbtiles.json.check tests/join-population/merged-folder.mbtiles.json.check tests/join-population/windows-merged.mbtiles.json.check tests/join-population/windows-merged2.mbtiles.json.check tests/join-population/macarthur-and-macarthur2-merged.mbtiles tests/join-population/macarthur-and-macarthur2-merged2.mbtiles tests/join-population/macarthur-and-macarthur2-merged.mbtiles.json.check tests/join-population/macarthur-and-macarthur2-merged2.mbtiles.json.check
|
||||
rm -rf tests/join-population/raw-merged-folder tests/join-population/tabblock_06001420-folder tests/join-population/macarthur-folder tests/join-population/macarthur2-folder tests/join-population/merged-mbtiles-to-folder tests/join-population/merged-folders-to-folder tests/join-population/windows-merged-folder tests/join-population/macarthur-and-macarthur2-folder
|
||||
|
||||
join-test-object:
|
||||
./tippecanoe -z0 -f -o tests/object/out/before.mbtiles tests/object/in.json
|
||||
./tile-join -f -o tests/object/out/after.mbtiles tests/object/out/before.mbtiles
|
||||
./tippecanoe-decode tests/object/out/before.mbtiles | grep -v '"bounds"' > tests/object/out/before.mbtiles.json
|
||||
./tippecanoe-decode tests/object/out/after.mbtiles | grep -v '"bounds"' > tests/object/out/after.mbtiles.json
|
||||
cmp tests/object/out/before.mbtiles.json tests/object/out/after.mbtiles.json
|
||||
rm -f tests/object/out/before.mbtiles.json tests/object/out/after.mbtiles.json tests/object/out/before.mbtiles tests/object/out/after.mbtiles
|
||||
|
||||
# Use this target to regenerate the standards that the tests are compared against
|
||||
# after making a change that legitimately changes their output
|
||||
|
||||
|
20
mbtiles.cpp
20
mbtiles.cpp
@ -1,8 +1,3 @@
|
||||
// for vasprintf() on Linux
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -102,21 +97,6 @@ static void quote(std::string &buf, std::string const &s) {
|
||||
}
|
||||
}
|
||||
|
||||
void aprintf(std::string *buf, const char *format, ...) {
|
||||
va_list ap;
|
||||
char *tmp;
|
||||
|
||||
va_start(ap, format);
|
||||
if (vasprintf(&tmp, format, ap) < 0) {
|
||||
fprintf(stderr, "memory allocation failure\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
buf->append(tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
bool type_and_string::operator<(const type_and_string &o) const {
|
||||
if (string < o.string) {
|
||||
return true;
|
||||
|
@ -43,8 +43,6 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *outdir, const char *fnam
|
||||
|
||||
void mbtiles_close(sqlite3 *outdb, const char *pgm);
|
||||
|
||||
void aprintf(std::string *buf, const char *format, ...);
|
||||
|
||||
std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::string, layermap_entry> > const &maps);
|
||||
std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::string, layermap_entry> > const &maps, bool trunc);
|
||||
|
||||
|
21
text.cpp
21
text.cpp
@ -1,5 +1,11 @@
|
||||
// for vasprintf() on Linux
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "text.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Returns an empty string if `s` is valid utf8;
|
||||
@ -122,3 +128,18 @@ std::string truncate16(std::string const &s, size_t runes) {
|
||||
|
||||
return std::string(s, 0, lastgood - start);
|
||||
}
|
||||
|
||||
void aprintf(std::string *buf, const char *format, ...) {
|
||||
va_list ap;
|
||||
char *tmp;
|
||||
|
||||
va_start(ap, format);
|
||||
if (vasprintf(&tmp, format, ap) < 0) {
|
||||
fprintf(stderr, "memory allocation failure\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
buf->append(tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
}
|
||||
|
1
text.hpp
1
text.hpp
@ -6,5 +6,6 @@
|
||||
std::string check_utf8(std::string text);
|
||||
const char *utf8_next(const char *s, long *c);
|
||||
std::string truncate16(std::string const &s, size_t runes);
|
||||
void aprintf(std::string *buf, const char *format, ...);
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "mbtiles.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "dirtiles.hpp"
|
||||
#include "write_json.hpp"
|
||||
#include "text.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
@ -171,6 +173,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map<std::st
|
||||
type = mvt_double;
|
||||
} else if (val.type == mvt_null || val.type == mvt_list || val.type == mvt_hash) {
|
||||
type = mvt_hash;
|
||||
stringify_val(value, feat, layer, val, feat.tags[t + 1]);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -250,7 +253,12 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::map<std::st
|
||||
auto fa = attributes.find(k);
|
||||
|
||||
if (fa != attributes.end()) {
|
||||
outlayer.tag(outfeature, k, fa->second.first);
|
||||
if (fa->second.first.type == mvt_hash) {
|
||||
copy_nested(layer, feat, k, fa->second.first, outlayer, outfeature);
|
||||
} else {
|
||||
outlayer.tag(outfeature, k, fa->second.first);
|
||||
}
|
||||
|
||||
add_to_file_keys(file_keys->second.file_keys, k, fa->second.second);
|
||||
attributes.erase(fa);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "geometry.hpp"
|
||||
#include "mvt.hpp"
|
||||
#include "write_json.hpp"
|
||||
#include "text.hpp"
|
||||
|
||||
struct lonlat {
|
||||
int op;
|
||||
@ -25,49 +26,74 @@ struct lonlat {
|
||||
};
|
||||
|
||||
void print_val(FILE *fp, mvt_feature const &feature, mvt_layer const &layer, mvt_value const &val, size_t vo) {
|
||||
std::string s;
|
||||
stringify_val(s, feature, layer, val, vo);
|
||||
fprintf(fp, "%s", s.c_str());
|
||||
}
|
||||
|
||||
static void quote(std::string &buf, std::string const &s) {
|
||||
buf.push_back('"');
|
||||
for (size_t i = 0; i < s.size(); i++) {
|
||||
unsigned char ch = s[i];
|
||||
|
||||
if (ch == '\\' || ch == '\"') {
|
||||
buf.push_back('\\');
|
||||
buf.push_back(ch);
|
||||
} else if (ch < ' ') {
|
||||
char tmp[7];
|
||||
sprintf(tmp, "\\u%04x", ch);
|
||||
buf.append(std::string(tmp));
|
||||
} else {
|
||||
buf.push_back(ch);
|
||||
}
|
||||
}
|
||||
buf.push_back('"');
|
||||
}
|
||||
|
||||
void stringify_val(std::string &out, mvt_feature const &feature, mvt_layer const &layer, mvt_value const &val, size_t vo) {
|
||||
if (val.type == mvt_string) {
|
||||
fprintq(fp, val.string_value.c_str());
|
||||
quote(out, val.string_value);
|
||||
} else if (val.type == mvt_int) {
|
||||
fprintf(fp, "%lld", (long long) val.numeric_value.int_value);
|
||||
out.append(std::to_string((long long) val.numeric_value.int_value));
|
||||
} else if (val.type == mvt_double) {
|
||||
double v = val.numeric_value.double_value;
|
||||
if (v == (long long) v) {
|
||||
fprintf(fp, "%lld", (long long) v);
|
||||
out.append(std::to_string((long long) v));
|
||||
} else {
|
||||
fprintf(fp, "%g", v);
|
||||
aprintf(&out, "%g", v);
|
||||
}
|
||||
} else if (val.type == mvt_float) {
|
||||
double v = val.numeric_value.float_value;
|
||||
if (v == (long long) v) {
|
||||
fprintf(fp, "%lld", (long long) v);
|
||||
out.append(std::to_string((long long) v));
|
||||
} else {
|
||||
fprintf(fp, "%g", v);
|
||||
aprintf(&out, "%g", v);
|
||||
}
|
||||
} else if (val.type == mvt_sint) {
|
||||
fprintf(fp, "%lld", (long long) val.numeric_value.sint_value);
|
||||
out.append(std::to_string((long long) val.numeric_value.sint_value));
|
||||
} else if (val.type == mvt_uint) {
|
||||
fprintf(fp, "%lld", (long long) val.numeric_value.uint_value);
|
||||
out.append(std::to_string((long long) val.numeric_value.uint_value));
|
||||
} else if (val.type == mvt_bool) {
|
||||
fprintf(fp, "%s", val.numeric_value.bool_value ? "true" : "false");
|
||||
out.append(val.numeric_value.bool_value ? "true" : "false");
|
||||
} else if (val.type == mvt_list) {
|
||||
fprintf(fp, "[");
|
||||
out.push_back('[');
|
||||
for (size_t i = 0; i < val.list_value.size(); i++) {
|
||||
if (i != 0) {
|
||||
fprintf(fp, ",");
|
||||
out.push_back(',');
|
||||
}
|
||||
if (val.list_value[i] >= vo || val.list_value[i] >= layer.values.size()) {
|
||||
fprintf(stderr, "Invalid value reference in list (%lu from %lu within %lu)\n", val.list_value[i], vo,
|
||||
layer.values.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_val(fp, feature, layer, layer.values[val.list_value[i]], val.list_value[i]);
|
||||
stringify_val(out, feature, layer, layer.values[val.list_value[i]], val.list_value[i]);
|
||||
}
|
||||
fprintf(fp, "]");
|
||||
out.push_back(']');
|
||||
} else if (val.type == mvt_hash) {
|
||||
fprintf(fp, "{");
|
||||
out.push_back('{');
|
||||
for (size_t i = 0; i + 1 < val.list_value.size(); i += 2) {
|
||||
if (i != 0) {
|
||||
fprintf(fp, ",");
|
||||
out.push_back(',');
|
||||
}
|
||||
if (val.list_value[i] >= layer.keys.size()) {
|
||||
fprintf(stderr, "Invalid key reference in hash (%lu from %lu within %lu)\n", val.list_value[i], vo, layer.keys.size());
|
||||
@ -78,13 +104,13 @@ void print_val(FILE *fp, mvt_feature const &feature, mvt_layer const &layer, mvt
|
||||
vo, layer.values.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintq(fp, layer.keys[val.list_value[i]].c_str());
|
||||
fprintf(fp, ":");
|
||||
print_val(fp, feature, layer, layer.values[val.list_value[i + 1]], val.list_value[i + 1]);
|
||||
quote(out, layer.keys[val.list_value[i]]);
|
||||
out.push_back(':');
|
||||
stringify_val(out, feature, layer, layer.values[val.list_value[i + 1]], val.list_value[i + 1]);
|
||||
}
|
||||
fprintf(fp, "}");
|
||||
out.push_back('}');
|
||||
} else if (val.type == mvt_null) {
|
||||
fprintf(fp, "null");
|
||||
out.append("null");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, unsigned long long index, long long sequence, long long extent, bool complain);
|
||||
void fprintq(FILE *f, const char *s);
|
||||
void stringify_val(std::string &out, mvt_feature const &feature, mvt_layer const &layer, mvt_value const &val, size_t vo);
|
||||
|
Loading…
x
Reference in New Issue
Block a user