之前介绍了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系列的博客全部终结。

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

  1. shp系列(四)——利用C++进行Shx文件的读(打开)

    1.shx文件的基本情况 shx文件又叫索引文件,主要包含坐标文件的索引信息,文件中每个记录包含对应的坐标文件记录距离坐标文件的初始位置的偏移量.通过索引文件可以很方便地在坐标文件中定位到指定目标的坐 ...

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

    上一篇介绍了shp文件的创建,接下来介绍dbf的创建. 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 1.Dbf头文件的创建 Dbf头文件的结构 ...

  3. python常识系列07-->python利用xlwt写入excel文件

    前言 读书之法,在循序而渐进,熟读而精思.--朱熹 抽空又来写一篇,毕竟知识在于分享! 一.xlwt模块是什么 python第三方工具包,用于往excel中写入数据:(ps:只能创建新表格,不能修改表 ...

  4. shp系列(五)——利用C++进行shp文件的写(创建)

    之前介绍了shp文件.dbf文件和shx文件的的读取,接下来将分别介绍它们的创建过程.一般来说,读和写的一一对应的,写出的文件就是为了保存数据供以后读取的.写的文件要符合shapefile的标准.之前 ...

  5. shp系列(一)——利用C++进行shp文件的读(打开)与写(创建)开言

    博客背景和目的 最近在用C++写一个底层的东西,需要读取和创建shp文件.虽然接触shp文件已经几年了,但是对于shp文件内到底包含什么东西一直是一知半解.以前使用shp文件都是利用软件(如ArcGI ...

  6. shp系列(三)——利用C++进行DBF文件的读(打开)

    1.DBF文件要点 DBF文件又叫属性文件,也叫dBASE文件,文件后缀是.dbf,实际上ArcGIS打开后的属性表就是DBF的信息.DBF文件遵循以下几个条件: 每个要素在表中必须要包含一个与之相对 ...

  7. 利用ThinkPHP自带的七牛云驱动上传文件到七牛云以及删除七牛云文件方法

    一.准备工作 1.注册七牛云账号 2.选择对象储存->创建空间->设置为公开 3.在config配置文件中添加以下代码 'UPLOAD_FILE_QINIU' => array ( ...

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

    介绍 在本教程中,我们将探索使用Struts 2消息资源功能(也称为 resource bundles 资源绑定).消息资源提供了一种简单的方法,可以将文本放在一个视图页面中,通过应用程序,创建表单字 ...

  9. C语言高速入口系列(七)

    C语言高速入口系列(七) C语言指针进阶 本章引言: 在前面第5节中我们对C语言的指针进行了初步的学习理解;作为C语言的灵魂, C指针肯定没那么简单,在这一节中,我们将会对指针进行进一步的学习,比方二 ...

随机推荐

  1. Eclipse安装配置——For Java

    1.下载安装JRE 2.下载Eclipse,解压到相应文件夹 3.配置Eclipse 3.1 配置字体大小  -12号 3.2配置workspace默认编码,utf-8,默认系统windows 3.3 ...

  2. 《Linux程序设计》笔记(二)shell程序设计

    1. 进程树形显示 ps -e f 2. 重定向 > 覆盖文件 >> 附加至文件 1> 标准输出 2> 标准错误输出 0 代表一个程序的标准输入 3. 程序可以在当前目录 ...

  3. 安卓JNI使用OpenCV

    OpenCV也有Java数据结构的包,不过计算速度还是很慢,非不得已不使用此种方式调用OpenCV.使用NDK编写底层OpenCv的调用代码,使用JNI对代码进行封装,可以稍微提高一点效率. 参考链接 ...

  4. PAT_A1098#Insertion or Heap Sort

    Source: PAT_A1098 Insertion or Heap Sort (25 分) Description: According to Wikipedia: Insertion sort  ...

  5. ActionChains定位元素

    ActionChains UI自动化测试过程中,经常遇到那种,需要鼠标悬浮后,要操作的才会元素出现的这种场景,那么我们就要模拟鼠标悬浮到某一个位置,做一系列的连贯操作,Selenium给我们提供了Ac ...

  6. 【剑指Offer】36、两个链表的第一个公共结点

      题目描述:   输入两个链表,找出它们的第一个公共结点.   解题思路:   本题首先可以很直观的想到蛮力法,即对链表1(假设长度为m)的每一个结点,遍历链表2(假设长度为n),找有没有与其相同的 ...

  7. 【剑指Offer】21、栈的压入、弹出序列

      题目描述:   输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2 ...

  8. [luogu4162 SCOI2009] 最长距离(最短路)

    传送门 Solution 题目是最长路,其实是最短路ヽ(ー_ー)ノ 把进入障碍点的边设为1,其他为0.枚举每个点为起点找距离<=T的点,更新答案 Code //By Menteur_Hxy #i ...

  9. 08.Web服务器-3.Web静态服务器

    1.显示固定的页面 from socket import * from multiprocessing import * import os def handleClient(clientSocket ...

  10. lucene_04_解析语法查询

    解析语法查询就是调用方法查询的原始查询 例如: 查询所有的查询器的语法为:*:*,因为lucene查询是根据term来做的,既是:key:value类型.*:*表示所有域中的所有值. api调用语法解 ...