mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 10:51:07 +00:00
C++ headers: add sort comparator and deserialize_header
This commit is contained in:
@@ -74,6 +74,57 @@ struct headerv3 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pmtiles_magic_number_exception : std::exception {
|
||||||
|
const char* what() const noexcept override {
|
||||||
|
return "pmtiles magic number exception";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmtiles_version_exception : std::exception {
|
||||||
|
const char* what() const noexcept override {
|
||||||
|
return "pmtiles version: must be 3";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline headerv3 deserialize_header(const std::string &s) {
|
||||||
|
if (s.substr(0,7) != "PMTiles") {
|
||||||
|
throw pmtiles_magic_number_exception{};
|
||||||
|
}
|
||||||
|
if (s.size() != 127 || s[7] != 0x3) {
|
||||||
|
throw pmtiles_version_exception{};
|
||||||
|
}
|
||||||
|
headerv3 h;
|
||||||
|
s.copy((char *)&h.root_dir_offset,8,8);
|
||||||
|
s.copy((char *)&h.root_dir_bytes,8,16);
|
||||||
|
s.copy((char *)&h.json_metadata_offset,8,24);
|
||||||
|
s.copy((char *)&h.json_metadata_bytes,8,32);
|
||||||
|
s.copy((char *)&h.leaf_dirs_offset,8,40);
|
||||||
|
s.copy((char *)&h.leaf_dirs_bytes,8,48);
|
||||||
|
s.copy((char *)&h.tile_data_offset,8,56);
|
||||||
|
s.copy((char *)&h.tile_data_bytes,8,64);
|
||||||
|
s.copy((char *)&h.addressed_tiles_count,8,72);
|
||||||
|
s.copy((char *)&h.tile_entries_count,8,80);
|
||||||
|
s.copy((char *)&h.tile_contents_count,8,88);
|
||||||
|
if (s[96] == 0x1) {
|
||||||
|
h.clustered = true;
|
||||||
|
} else {
|
||||||
|
h.clustered = false;
|
||||||
|
}
|
||||||
|
h.internal_compression = s[97];
|
||||||
|
h.tile_compression = s[98];
|
||||||
|
h.tile_type = s[99];
|
||||||
|
h.min_zoom = s[100];
|
||||||
|
h.max_zoom = s[101];
|
||||||
|
s.copy((char *)&h.min_lon_e7,4,102);
|
||||||
|
s.copy((char *)&h.min_lat_e7,4,106);
|
||||||
|
s.copy((char *)&h.max_lon_e7,4,110);
|
||||||
|
s.copy((char *)&h.max_lat_e7,4,114);
|
||||||
|
h.center_zoom = s[118];
|
||||||
|
s.copy((char *)&h.center_lon_e7,4,119);
|
||||||
|
s.copy((char *)&h.center_lat_e7,4,123);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
struct zxy {
|
struct zxy {
|
||||||
uint8_t z;
|
uint8_t z;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
@@ -97,6 +148,10 @@ struct entryv3 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool operator()(entryv3 a, entryv3 b) const { return a.tile_id < b.tile_id; }
|
||||||
|
} entryv3_cmp;
|
||||||
|
|
||||||
struct varint_too_long_exception : std::exception {
|
struct varint_too_long_exception : std::exception {
|
||||||
const char* what() const noexcept override {
|
const char* what() const noexcept override {
|
||||||
return "varint too long exception";
|
return "varint too long exception";
|
||||||
|
|||||||
55
cpp/test.cpp
55
cpp/test.cpp
@@ -67,11 +67,66 @@ MU_TEST(test_serialize_header) {
|
|||||||
mu_check(len == 127);
|
mu_check(len == 127);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MU_TEST(test_deserialize_header) {
|
||||||
|
headerv3 header;
|
||||||
|
header.root_dir_offset = 1;
|
||||||
|
header.root_dir_bytes = 2;
|
||||||
|
header.json_metadata_offset = 3;
|
||||||
|
header.json_metadata_bytes = 4;
|
||||||
|
header.leaf_dirs_offset = 5;
|
||||||
|
header.leaf_dirs_bytes = 6;
|
||||||
|
header.tile_data_offset = 7;
|
||||||
|
header.tile_data_bytes = 8;
|
||||||
|
header.addressed_tiles_count = 9;
|
||||||
|
header.tile_entries_count = 10;
|
||||||
|
header.tile_contents_count = 11;
|
||||||
|
header.clustered = true;
|
||||||
|
header.internal_compression = 0x1;
|
||||||
|
header.tile_compression = 0x2;
|
||||||
|
header.tile_type = 0x3;
|
||||||
|
header.min_zoom = 12;
|
||||||
|
header.max_zoom = 13;
|
||||||
|
header.min_lon_e7 = 14;
|
||||||
|
header.min_lat_e7 = 15;
|
||||||
|
header.max_lon_e7 = 16;
|
||||||
|
header.max_lat_e7 = 17;
|
||||||
|
header.center_zoom = 14;
|
||||||
|
header.center_lon_e7 = 18;
|
||||||
|
header.center_lat_e7 = 19;
|
||||||
|
auto serialized = header.serialize();
|
||||||
|
auto deserialized = deserialize_header(serialized);
|
||||||
|
mu_check(deserialized.root_dir_offset == 1);
|
||||||
|
mu_check(deserialized.root_dir_bytes == 2);
|
||||||
|
mu_check(deserialized.json_metadata_offset == 3);
|
||||||
|
mu_check(deserialized.json_metadata_bytes == 4);
|
||||||
|
mu_check(deserialized.leaf_dirs_offset == 5);
|
||||||
|
mu_check(deserialized.leaf_dirs_bytes == 6);
|
||||||
|
mu_check(deserialized.tile_data_offset == 7);
|
||||||
|
mu_check(deserialized.tile_data_bytes == 8);
|
||||||
|
mu_check(deserialized.addressed_tiles_count == 9);
|
||||||
|
mu_check(deserialized.tile_entries_count == 10);
|
||||||
|
mu_check(deserialized.tile_contents_count == 11);
|
||||||
|
mu_check(deserialized.clustered == true);
|
||||||
|
mu_check(deserialized.internal_compression == 0x1);
|
||||||
|
mu_check(deserialized.tile_compression == 0x2);
|
||||||
|
mu_check(deserialized.tile_type == 0x3);
|
||||||
|
mu_check(deserialized.min_zoom == 12);
|
||||||
|
mu_check(deserialized.max_zoom == 13);
|
||||||
|
mu_check(deserialized.min_lon_e7 == 14);
|
||||||
|
mu_check(deserialized.min_lat_e7 == 15);
|
||||||
|
mu_check(deserialized.max_lon_e7 == 16);
|
||||||
|
mu_check(deserialized.max_lat_e7 == 17);
|
||||||
|
mu_check(deserialized.center_zoom == 14);
|
||||||
|
mu_check(deserialized.center_lon_e7 == 18);
|
||||||
|
mu_check(deserialized.center_lat_e7 == 19);
|
||||||
|
}
|
||||||
|
|
||||||
MU_TEST_SUITE(test_suite) {
|
MU_TEST_SUITE(test_suite) {
|
||||||
MU_RUN_TEST(test_tileid_to_zxy);
|
MU_RUN_TEST(test_tileid_to_zxy);
|
||||||
MU_RUN_TEST(test_zxy_to_tileid);
|
MU_RUN_TEST(test_zxy_to_tileid);
|
||||||
MU_RUN_TEST(test_serialize_directory);
|
MU_RUN_TEST(test_serialize_directory);
|
||||||
MU_RUN_TEST(test_serialize_header);
|
MU_RUN_TEST(test_serialize_header);
|
||||||
|
MU_RUN_TEST(test_deserialize_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user