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系列的博客全部终结。

原文地址:https://www.cnblogs.com/fan-0802-WHU/p/10160722.html

时间: 2024-10-03 14:45:29

shp系列(七)——利用C++进行Shx文件的写(创建)的相关文章

shp系列(六)——利用C++进行Dbf文件的写(创建)

上一篇介绍了shp文件的创建,接下来介绍dbf的创建. 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 1.Dbf头文件的创建 Dbf头文件的结构如下: 记录项数组说明: 字段类型说明: 关于每项的具体含义参照读取dbf文件的解释,这里重点解释几项: HeaderByteNum指dbf头文件的字节数,数值不用除于2,具体为:从version到Reserved2(共32) + n个字段 * 每一个字段长度 32 + terminator. Re

(七)利用apache组件进行文件上传下载

一.文件上传 文件上传,即服务器端得到并处理用户上传的文件,这个文件存放在request里,也就是需要对request进行处理. 1.1 编写html文件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action=&q

sparksql系列(七) Json转Map,多文件生成

公司所有产品均是json数据上报给数仓使用,由于格式的不统一造成数据处理很麻烦,经过讨论将公共字段抽取出来,将业务线自己的字段放在 extends字段里面各个业务线的人自己写sql解析extends字段处理.里面涉及到一个json转map的知识点再此记录一下. 一:JSON转Map 为什需要将JSON转Map 公司里面产品很多,上报的数据很多,格式极其不规范同名的事情是常有的,对于解析来说是非常困难的,需要统一的脚本把字段解析出来. 上报的数据类似:{"id":"7"

python常识系列07--&gt;python利用xlwt写入excel文件

前言 读书之法,在循序而渐进,熟读而精思.--朱熹 抽空又来写一篇,毕竟知识在于分享! 一.xlwt模块是什么 python第三方工具包,用于往excel中写入数据:(ps:只能创建新表格,不能修改表格内容!!) 它支持 xlsx 和 xls 格式的excel表格: 与之对应的还有一个xlrd包,用于读取excel中的数据. 二.安装xlwt模块 命令行中输入:pip install xlwt 下载安装包进行离线安装 三.xlwt应用举例 3.1 xlwt基本应用实例 import xlwt #

struts2官方 中文教程 系列七:消息资源文件

介绍 在本教程中,我们将探索使用Struts 2消息资源功能(也称为 resource bundles 资源绑定).消息资源提供了一种简单的方法,可以将文本放在一个视图页面中,通过应用程序,创建表单字段标签,并根据用户的语言环境将文本更改为特定的语言. 贴个本帖的地址,以免被爬:struts2官方 中文教程 系列七:消息资源文件  即 http://www.cnblogs.com/linghaoxinpian/p/6906720.html 下载本章节代码 信息资源属性文件 在Struts2 we

C语言快速入门系列(七)

C语言快速入门系列(七) C语言指针进阶 本章引言: 在前面第5节中我们对C语言的指针进行了初步的学习理解;作为C语言的灵魂, C指针肯定没那么简单,在这一节中,我们将会对指针进行进一步的学习,比如二级指针, 指针数组,内存分配和const修饰指针常量等!下面就请大家跟随笔者的脚步,对 C指针神秘的一面进行进一步的解析吧! 本节学习路线图: 函数与指针: ①指针作为函数的形参: ②指向函数的指针: ③指针函数: ④带参数的主函数 ps:该代码的运行:先要编译生成exe文件后,来到exe所在文件目

小编带你了解Netty 系列七(那些开箱即用的 ChannelHandler).

一.前言Netty 为许多通用协议提供了编×××和处理器,几乎可以开箱即用, 这减少了你在那些相当繁琐的事务上本来会花费的时间与精力.另外,这篇文章中,就不涉及 Netty 对 WebSocket协议 的支持了,因为涉及的篇幅有点大,会在下一篇文章做一个具体的介绍. 回到顶部二.SSL 协议SSL 协议是安全协议,层叠在其他协议之上.为了支持 SSL/TLS, Java 提供了 javax.net.ssl 包,它的 SSLContext 和 SSLEngine 类使得实现解密和加密相当简单直接.

Exchange Server2013 系列七:客户端访问服务器高可用性部署实战

杜飞 在前面的文章中我们介绍了客户端访问服务器的高可用性技术,从这篇文章开始,我们就来看一个详细的高可用性部署方案. 首先,看一下我们的服务器列表: 编号 服务名 IP地址 功能 1 HYV01 IP:10.41.3.6 \16  网关:10.41.1.254 宿主机 2 HYV02 IP:10.41.4.6 \16  网关:10.41.1.254 宿主机 3 DF-DC01 IP:10.41.4.210\16 网关:10.41.1.254 DNS:10.41.4.210   10.41.4.2

利用XPath读取Xml文件

之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素.可以把XPath比作文件管理路径:通过文件管理路 径,可以按照一定的规则查找到所需要的文件:同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点. 不过,由于XPath可应用于不止一个的标准,因此W3C将其独立出来作为XSLT的配套标准颁布,它是XSLT以及我们后面要讲到的XPointer的重要组成部分. 在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基