osmpbf-outline(C++版本的) 2021-09-22 // 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; } 推荐阅读 新房装修甲醛来自哪里 新装修的房子甲醛来自哪里 什么叫冰藤席 梦见被人骗财骗物 梦见被人骗得人财二空 烤肉怎么做 Python|Python 机器学习之线性回归详解分析 上班族“最为要命”的饮食习惯 天国拯救旅行事件之谜语人答案图文详解 谜语人答案是什么_网 如何使用文件服务器? 文件服务器怎么用 蜡烛是怎样生产的 生产蜡烛的原料是什么 删除的微信好友怎么看微信号 睡电热毯为什么会口干舌燥 椰子冻的功效与作用 国家卫健委|国家卫健委:疑似或确诊流感的医务人员不可带病工作 绿豆汤的绿豆可以多熬几次么 武汉灵活就业人员社保只交医保可以吗 海关关税查询系统入口,海关信息网站查询进出口数据 团购网的分析,社区团购优缺点分析 牵挂一个人的心情说说大全 牵挂一个人的心情短语 经济法垄断概念 馒头怎么看蒸没蒸熟 opencv|opencv C++模板匹配的简单实现 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题 C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场 C语言的版本比较 [源码解析]|[源码解析] NVIDIA HugeCTR,GPU版本参数服务器---(3) c++基础概念笔记 K8S|K8S 生态周报| Istio 即将发布重大安全更新,多个版本受影响 Caffe在Windows10下CPU版本的安装(cpu+anaconda3+vs2013+pycaffe) 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气 中单直通王者(三)(英雄池要跟上版本,选将放机灵点,听到没!)