osmpbf-outline(C++版本的)

// osmpbf-outline(C++版本的),练习用#include #include #include // pbf blobs中使用到了zlib压缩 #include // netinet中提供了network-byte-order的转换函数 #include // 定义了几种扩展的整数类型和宏 #include// 其它需要的头文件 #include #include #include // 描述低级blob存储的头文件 #include // 描述高级OSM对象的头文件 #include // 以byte为单位的最大blob header的大小 const int max_blob_header_size = 64 * 1024; // 64 kB// 以byte为单位的最大非压缩的blob的大小 const int max_uncompressed_blob_size = 32 * 1024 * 1024; // 32 MB// 用于double和int之间的转换的经度/纬度分辨率 const int lonlat_resolution = 1000 * 1000 * 1000; // 格式化输出,info信息,warn警告,fatal错误(考虑改为err) // 用法:将用于向屏幕显示的std::cout替换为info()或其它 // 例: info()<<"开始解析文件"; 行尾自动换行// info 绿色 struct info { info() {std::cout << "\033[32m"; } templateinfo & operator<<(const T & t){ std::cout << t; return *this; } ~info() {std::cout << "\033[0m" << std::endl; } }; // debug,白色,相当于std::cout<<... warn & operator<<(const T & t){ std::cout << t; return *this; } ~warn() {std::cout << "\033[0m" << std::endl; } }; //fatal 红色 struct fatal { fatal() {std::cout << "\033[31m"; } templatefatal & operator<<(const T & t){ std::cout << t; return *this; } ~fatal() {std::cout << "\033[0m" << std::endl; exit(1); } }; // 用于从文件中读取压缩的blob的buffer缓冲区 char buffer[max_uncompressed_blob_size]; // 用于进行解压缩blob的buffer缓冲区 char unpack_buffer[max_uncompressed_blob_size]; // pbf struct of a BlobHeader OSMPBF::BlobHeader blobheader; // pbf struct of a Blob OSMPBF::Blob blob; // pbf struct of an OSM HeaderBlock OSMPBF::HeaderBlock headerblock; // pbf struct of an OSM PrimitiveBlock OSMPBF::PrimitiveBlock primblock; // main函数 int main(int argc, char** argv) { if (argc != 2) { std::cout << "Usage: " << argv[0] << " file_to_read.osm.pbf" << std::endl; return 1; }// 读入文件 std::ifstream file; file.open(argv[1],std::ios::binary); if (!file.is_open()) fatal() << "无法打开文件: " << argv[1]; info() << "读取文件..." << argv[1]; //打开成功,开始解析数据的提示信息////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// 开始读取文件 while (!file.eof()){int32_t sz; // 存储size,多次重复使用// 读取文件的前4bytes,这是blob-header的sizeif ( !file.read((char*)&sz, 4) ){info() << "读取文件完成!"; break; //到达文件尾}// 将size从network byte-order转换为host hyte-ordersz = ntohl(sz); // 确保blob-header < MAX_BLOB_HEADER_SIZE (64kB)if (sz > max_blob_header_size)fatal() << "blob-header-size is bigger then allowed " << sz << " > " << max_blob_header_size; // 从文件中读取blob-header到buffer中if (!file.read(buffer, sz))fatal() << "无法从文件中读取blob-header"; // 从缓冲区中解析blob-headerif (!blobheader.ParseFromArray(buffer, sz))// 解析结果存储在OSMPBF::BlobHeader结构对象中fatal() << "无法解析blob-header"; // 输出blob-header的有关信息info() << "BlobHeader (" << sz <<"bytes)"; debug() << "type = " << blobheader.type(); // 以下的blob的sizesz = blobheader.datasize(); debug() <<"datasize = " << sz; // 可选的 indexdataif (blobheader.has_indexdata()) {debug() <<"indexdata ="https://www.it610.com/article/<< blobheader.indexdata().size()<<"bytes"; }// 确保blob < MAX_BLOB_SIZE (64kB)if (sz > max_uncompressed_blob_size) fatal()<<"blob-size is bigger then allowed"; // 从文件中读取blob到buffer中if (!file.read(buffer, sz))fatal() << "无法从文件中读取blob"; // 从缓冲区中解析blobif (!blob.ParseFromArray(buffer, sz))fatal() << "无法解析blob"; // 输出blob-header的有关信息info() << "Blob(" << sz <<"bytes)"; // 有无数据流的标志,bool found_data = https://www.it610.com/article/false; // 如果blob中有非压缩的数据if (blob.has_raw()) {// 则有至少一个数据流found_data = true; // blob-data的sizesz = blob.raw().size(); // 检查是否正确设置了raw_sizeif(sz != blob.raw_size())warn() <<"reports wrong raw_size: " << blob.raw_size() << " bytes"; // 输出blob的有关信息debug()<<"contains uncompressed data: " < 0) {found_items = true; debug() <<"nodes: " << pg.nodes_size(); if (pg.nodes(0).has_info()) {debug()<<"with meta-info"; }}// 输出关于dense nodesif (pg.has_dense()) {found_items = true; debug() <<"dense nodes: " << pg.dense().id_size(); if (pg.dense().has_denseinfo()) {debug()<<"with meta-info"; }}// 输出关于waysif (pg.ways_size() > 0) {found_items = true; debug() << "ways: " << pg.ways_size(); if (pg.ways(0).has_info()) {debug() << "with meta-info"; }}// 输出关于relationsif (pg.relations_size() > 0) {found_items = true; debug() << "relations: " << pg.relations_size(); if (pg.relations(0).has_info()) {debug() << "with meta-info"; }}if (!found_items) {warn()<<"contains no items"; }}}else{// 未知的blob类型warn()<<"unknown blob type: " << blobheader.type(); }}// close the file pointerfile.close(); // clean up the protobuf libgoogle::protobuf::ShutdownProtobufLibrary(); return 0; }

    推荐阅读