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<<... <debug & operator<<(const T & t){ std::cout << t; return *this;}
    ~debug() {std::cout << "\033[0m" << std::endl;}

};

//warn 黄色
struct warn {
    warn() {std::cout << "\033[33m";}
    templatewarn & 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的size

        if ( !file.read((char*)&sz, 4) ){

            info() << "读取文件完成!";

            break; //到达文件尾

        }

        // 将size从network byte-order转换为host hyte-order

        sz = 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-header

        if (!blobheader.ParseFromArray(buffer, sz))

            // 解析结果存储在OSMPBF::BlobHeader结构对象中

            fatal() << "无法解析blob-header";

            // 输出blob-header的有关信息

        info() << "BlobHeader (" << sz <<"bytes)";

        debug() << "  type = " << blobheader.type();

        // 以下的blob的size

        sz = blobheader.datasize();

        debug() <<"  datasize = " << sz;

        // 可选的 indexdata

        if (blobheader.has_indexdata()) {

            debug() <<"  indexdata =  "<< 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";

        // 从缓冲区中解析blob

        if (!blob.ParseFromArray(buffer, sz))

            fatal() << "无法解析blob";

        

        // 输出blob-header的有关信息

        info() << "Blob  (" << sz <<"bytes)";

        // 有无数据流的标志,

        bool found_data = false;

        

        // 如果blob中有非压缩的数据

        if (blob.has_raw()) {

            // 则有至少一个数据流

            found_data = true;

            // blob-data的size

            sz = blob.raw().size();

            // 检查是否正确设置了raw_size

            if(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 nodes

                if (pg.has_dense()) {

                    found_items = true;



                    debug() <<"      dense nodes: " << pg.dense().id_size();

                    if (pg.dense().has_denseinfo()) {

                        debug()<<"        with meta-info";

                    }

                }



                // 输出关于ways

                if (pg.ways_size() > 0) {

                    found_items = true;



                    debug() << "      ways: " << pg.ways_size();

                    if (pg.ways(0).has_info()) {

                        debug() << "        with meta-info";

                    }

                }



                // 输出关于relations

                if (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 pointer

    file.close();



    // clean up the protobuf lib

    google::protobuf::ShutdownProtobufLibrary();

    

    return 0;

}

你可能感兴趣的:(osmpbf-outline(C++版本的))