diff --git a/geobuf.cpp b/geobuf.cpp new file mode 100644 index 0000000..435710b --- /dev/null +++ b/geobuf.cpp @@ -0,0 +1,157 @@ +#include +#include +#include "serial.hpp" +#include "geobuf.hpp" +#include "protozero/varint.hpp" +#include "protozero/pbf_reader.hpp" +#include "protozero/pbf_writer.hpp" + +serial_val readValue(protozero::pbf_reader &pbf, double e, std::vector &keys) { + return serial_val(); +} + +drawvec readGeometry(protozero::pbf_reader &pbf, double e, std::vector &keys, int &type) { + std::vector lengths; + std::vector coords; + + while (pbf.next()) { + switch (pbf.tag()) { + case 1: + type = pbf.get_enum(); + break; + + case 2: { + auto pi = pbf.get_packed_sint32(); + for (auto it = pi.first; it != pi.second; ++it) { + lengths.push_back(*it); + } + break; + } + + case 3: { + auto pi = pbf.get_packed_sint64(); + for (auto it = pi.first; it != pi.second; ++it) { + coords.push_back(*it); + } + break; + } + + case 4: { + int type2; + protozero::pbf_reader geometry_reader(pbf.get_message()); + drawvec dv2 = readGeometry(geometry_reader, e, keys, type2); + break; + } + + default: + pbf.skip(); + } + } + + type /= 2; + return drawvec(); +} + +void readFeature(protozero::pbf_reader &pbf, double e, std::vector &keys) { + drawvec dv; + long long id = -1; + std::vector values; + std::vector properties; + + while (pbf.next()) { + switch (pbf.tag()) { + case 1: { + int type; + protozero::pbf_reader geometry_reader(pbf.get_message()); + dv = readGeometry(geometry_reader, e, keys, type); + break; + } + + case 11: + id = pbf.get_int64(); + break; + + case 12: + fprintf(stderr, "Non-numeric feature IDs not supported"); + break; + + case 13: { + protozero::pbf_reader value_reader(pbf.get_message()); + values.push_back(readValue(value_reader, e, keys)); + break; + } + + case 14: { + auto pi = pbf.get_packed_uint32(); + for (auto it = pi.first; it != pi.second; ++it) { + properties.push_back(*it); + } + break; + } + + default: + pbf.skip(); + } + } +} + +void readFeatureCollection(protozero::pbf_reader &pbf, double e, std::vector &keys) { + while (pbf.next()) { + switch (pbf.tag()) { + case 1: { + protozero::pbf_reader feature_reader(pbf.get_message()); + readFeature(feature_reader, e, keys); + break; + } + + default: + pbf.skip(); + } + } +} + +void parse_geobuf(struct serialization_state *sst, std::string const &src, int layer, std::string layername) { + protozero::pbf_reader pbf(src); + + long long dim = 2; + double e = 10e6; + std::vector keys; + + while (pbf.next()) { + switch (pbf.tag()) { + case 1: + keys.push_back(pbf.get_string()); + break; + + case 2: + dim = pbf.get_int64(); + break; + + case 3: + e = pow(10, pbf.get_int64()); + break; + + case 4: { + protozero::pbf_reader feature_collection_reader(pbf.get_message()); + readFeatureCollection(feature_collection_reader, e, keys); + break; + } + + case 5: { + protozero::pbf_reader feature_reader(pbf.get_message()); + readFeature(feature_reader, e, keys); + break; + } + + case 6: { + int type; + protozero::pbf_reader geometry_reader(pbf.get_message()); + drawvec dv = readGeometry(geometry_reader, e, keys, type); + break; + } + + default: + pbf.skip(); + } + } +} diff --git a/geobuf.hpp b/geobuf.hpp index 17db410..9880698 100644 --- a/geobuf.hpp +++ b/geobuf.hpp @@ -6,8 +6,8 @@ #include #include #include "mbtiles.hpp" +#include "serial.hpp" -void parse_geobuf(FILE *fp, const char *reading, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, std::set *exclude, std::set *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int basezoom, int layer, double droprate, long long *file_bbox, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y, struct reader *readers, int maxzoom, std::map *layermap, std::string layername, bool uses_gamma, std::map const *attribute_types, double *dist_sum, size_t *dist_count, bool want_dist); -void *run_parse_json(void *v); +void parse_geobuf(struct serialization_state *sst, std::string const &s, int layer, std::string layername); #endif diff --git a/main.cpp b/main.cpp index eb8d43c..9b068fc 100644 --- a/main.cpp +++ b/main.cpp @@ -1193,6 +1193,52 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo } size_t layer = a->second.id; + if (sources[source].file.size() > 4 && sources[source].file.substr(sources[source].file.size() - 4) == std::string(".pbf")) { + std::string s = ""; + + char buf[20000]; + ssize_t n; + while ((n = read(fd, buf, 20000)) > 0) { + s.append(std::string(buf, n)); + } + + if (close(fd) != 0) { + perror("close"); + exit(EXIT_FAILURE); + } + + long long layer_seq = overall_offset; + + struct serialization_state sst; + sst.fname = reading.c_str(); + sst.line = 0; + sst.layer_seq = &layer_seq; + sst.progress_seq = &progress_seq; + sst.readers = reader; + sst.segment = 0; + sst.initial_x = &initial_x[0]; + sst.initial_y = &initial_y[0]; + sst.initialized = &initialized[0]; + sst.dist_sum = &dist_sum; + sst.dist_count = &dist_count; + sst.want_dist = guess_maxzoom; + sst.maxzoom = maxzoom; + sst.filters = prefilter != NULL || postfilter != NULL; + sst.uses_gamma = uses_gamma; + sst.layermap = &layermaps[0]; + sst.exclude = exclude; + sst.include = include; + sst.exclude_all = exclude_all; + sst.basezoom = basezoom; + sst.attribute_types = attribute_types; + + parse_geobuf(&sst, s, layer, sources[layer].layer); + + overall_offset = layer_seq; + checkdisk(reader, CPUS); + continue; + } + struct stat st; char *map = NULL; off_t off = 0;