shp系列(七)——利用C++进行Shx文件的写(创建)
发布日期:2022-02-10 11:37:03 浏览次数:59 分类:技术文章

本文共 3424 字,大约阅读时间需要 11 分钟。

之前介绍了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://blog.csdn.net/Fan_z_0802/article/details/85203153 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:shp系列(六)——利用C++进行Dbf文件的写(创建)
下一篇:利用道格拉斯·普客法(DP法)压缩矢量多边形(C++)

发表评论

最新留言

不错!
[***.144.177.141]2024年03月29日 22时26分54秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章