zoukankan      html  css  js  c++  java
  • shp系列(七)——利用C++进行Shx文件的写(创建)

    之前介绍了Shp文件和Dbf的写(创建),最后来介绍一下Shx文件的写(创建)。Shx文件是三者之中最简单的一个,原因有两个:第一是Shx文件的头文件与Shp文件的头文件几乎一样(除了FileLength);第二是Shx文件的主体只有两个记录项,分别是Offset和ContentLength。

    推荐结合读取shx的博客一起看!

    推荐结合读取shx的博客一起看!

    推荐结合读取shx的博客一起看!

    1.Shx头文件

    Shx头文件的各项和Shp文件一样,字节数为100。FileLength代表本Shx文件的长度。其他项的含义参考shp头文件。

    2.Shx记录主体

    • Offset代表主文件(Shp)中对应记录相对于起始位置的,值为计算的字节数的一半。
    • 第一条记录的偏移量就是头文件的长度,100/2。
    • 第二条及以后记录的偏移量为:前一条偏移量 + 上一条记录的长度 + 8/2 ; 8是shp文件中对应记录的 RecordNum 和 ContentLength的字节数。
    • 每条ContentLength与写Shp时对应记录的ContentLength的数值一样。
    • 头文件中FileLength的计算:(文件头(100) + 记录总数 *(4(Offset)+4(ContentLength)))/2。

    3.代码

    void WriteShx(CString& filename)
    {
        //****创建完Shp和Dbf之后创建同名Shx
        int n = filename.ReverseFind('.');
        filename = filename.Left(n);
        filename = filename + ".shx";
        FILE* m_ShxFile_fp;
        if ((m_ShxFile_fp = fopen(filename, "wb")) == NULL)
            return;
    
        //****创建头文件
        int FileCode = 9994;
        int Unused = 0;
        int FileLength = 100;       //后面要回来修改
        int Version = 1000;
        int ShapeType = 5;
        double Xmin = map->GetMapRect().left;
        double Ymin = map->GetMapRect().top;
        double Xmax = map->GetMapRect().right;
        double Ymax = map->GetMapRect().bottom;
        double Zmin = 0;
        double Zmax = 0;
        double Mmin = 0;
        double Mmax = 0;
        FileCode = OnChangeByteOrderTenToSixteen(FileCode);
        fwrite(&FileCode, sizeof(int), 1, m_ShxFile_fp);
        for (int i = 0; i < 5; i++)
            fwrite(&Unused, sizeof(int), 1, m_ShxFile_fp);
        FileLength = OnChangeByteOrderTenToSixteen(FileLength);
        fwrite(&FileLength, sizeof(int), 1, m_ShxFile_fp);
        fwrite(&Version, sizeof(int), 1, m_ShxFile_fp);
        fwrite(&ShapeType, sizeof(int), 1, m_ShxFile_fp);
        fwrite(&Xmin, sizeof(double), 1, m_ShxFile_fp); 
        fwrite(&Ymin, sizeof(double), 1, m_ShxFile_fp);
        fwrite(&Xmax, sizeof(double), 1, m_ShxFile_fp);
        fwrite(&Ymax, sizeof(double), 1, m_ShxFile_fp);
        fwrite(&Zmin, sizeof(double), 1, m_ShxFile_fp);  
        fwrite(&Zmax, sizeof(double), 1, m_ShxFile_fp);
        fwrite(&Mmin, sizeof(double), 1, m_ShxFile_fp);
        fwrite(&Mmax, sizeof(double), 1, m_ShxFile_fp); 
        //****写文件头结束
    
        //****写实体信息
        int Offset = 100/2 ;                               //第一条记录的偏移量就是头文件的长度,为字节数的一半
        int ContentLength;                                 //ContentLength是主文件中每条记录的长度
        int RecordNum = map->layer->objects.size();        //文件中的记录条数
        for (int i = 1; i <= RecordNum; i++) {
            if (i == 1) {                                  //第一条
                int tempOffset = Offset;
                tempOffset = OnChangeByteOrderTenToSixteen(tempOffset);
                fwrite(&tempOffset, sizeof(int), 1, m_ShxFile_fp);
                ContentLength = recordLength[i - 1];       //recordLength是写Shp时记录下的每条记录的长度,已经除过2
                ContentLength = OnChangeByteOrderTenToSixteen(ContentLength);
                fwrite(&ContentLength, sizeof(int), 1, m_ShxFile_fp);
            }
            if (i >= 2) {
                Offset = Offset + recordLength[i - 2] + 4;  //第二条及以后记录的偏移量为:前一条偏移量 + 上一条记录的长度 + 8/2 ; 
                                                            //8是shp文件中每条记录的 RecordNum 和 ContentLength的字节数
                int tempOffset = Offset;
                tempOffset = OnChangeByteOrderTenToSixteen(tempOffset);
                fwrite(&tempOffset, sizeof(int), 1, m_ShxFile_fp);
                ContentLength = recordLength[i - 1];
                ContentLength = OnChangeByteOrderTenToSixteen(ContentLength);
                fwrite(&ContentLength, sizeof(int), 1, m_ShxFile_fp);
            }
        }
        fseek(m_ShxFile_fp, 24, SEEK_SET);                   //转到写FileLength的地方
        FileLength = 100 + RecordNum * 8;                    //文件头100 + 记录总数 *(4+4)
        FileLength = FileLength / 2;                         // FileLength为字节数的一半
        FileLength = OnChangeByteOrderTenToSixteen(FileLength);
        fwrite(&FileLength, sizeof(int), 1, m_ShxFile_fp);
        fclose(m_ShxFile_fp);
    }

    至此关于Shp系列的博客全部终结。

  • 相关阅读:
    k8s--容器挂载 error: /proc must be mounted
    mysql--read only
    C#读取Excel文件(.xls .xlsx)
    如何使用BBCode
    markdown使用经验积累
    openlayers学习之-----入门篇
    echarts学习之----动态排序柱状图
    echarts学习之----多图例折线图
    Web3D学习之-----全景图预览插件photo-sphere-viewer
    vue报错解决----npm ERR!
  • 原文地址:https://www.cnblogs.com/fan-0802-WHU/p/10160722.html
Copyright © 2011-2022 走看看