.shp文件的存储结构是怎样的?底层读取shapefile文件

基础知识
大家都比较熟悉shp文件,它是GIS软件可以读取的矢量文件。但是大家知道它的存储结构吗?这次带着大家聊聊shp文件的存储结构,并尝试用python从底层读取一个点shp文件。
在此之前,需要大家了解一下字节和字节流的概念。
首先我们从最开始的二进制位讲起,二进制位就是计算机最最底层的语言,又可以表示为逻辑开(1)和关(0)。一位二进制位只能表示两种状态,要么是0,要么是1,但是如果多个二进制位组合在一起,那就可以表示很多状态(2^n)。另外我们都学过不同进制之间的转换,例如我们都会将10进制与2进制之间互相转换。
下面进入正题:我们将一个二进制位称为1bit,8bit,也就是8个二进制位构成一个字节。我们看一下一个字节可以表达的十进制范围
00000000(二进制)→0(十进制)
11111111(二进制)→255(十进制)
可以看到,一个字节可以表达256个数字,c语言中的char变量就是占用1个字节。另外,我们需要了解常见变量类型所占字节数,例如c语言中int整型变量占用4个字节,float类型占用4个字节,double占用8个字节。
实际上4个字节就可以表达很大的整数了,可以表达2^32个值,也就是4294967296个值,但通常整型加上正负号范围也就是:-2147483647~+2147483647,可以满足大部分需求,当然还有占用很多字节的长整型,可以占用8个字节(天文数字)。为了降低空间浪费,也有占用2个字节的短整型。
shp的存储结构
接下来我们就看一下shp的存储,对于非文本文件,例如图片和音视频,当然还包括各种乱七八糟的格式,我们需要以字节流的方式读取文件,而了解文件的存储结构是读取文件的基础。在用python读取之前,我们需要了解shapefile是如何字节存储的。
首先每个shp文件都有一个文件头,包括两部分内容:基本识别信息和空间信息概况,而且文件头的长度是固定的,一定包括100字节!文件头之后就是详细的空间记录信息。

文件头包括内容如下:
变量 | 类型 | 占用字节 |
---|---|---|
文件代码=9994 | int | 4 |
预留 | Int | 4 |
预留 | Int | 4 |
预留 | Int | 4 |
预留 | Int | 4 |
预留 | Int | 4 |
整个文件的长度(包括文件头,以双字节为单位) | int | 4 |
文件版本=1000 | Int | 4 |
几何体类型 | int | 4 |
所有X坐标最小值 | double | 8 |
所有Y坐标最小值 | double | 8 |
所有X坐标最大值 | double | 8 |
所有Y坐标最大值 | double | 8 |
所有Z坐标最小值 | double | 8 |
所有Z坐标最大值 | double | 8 |
所有M坐标最小值 | double | 8 |
所有M坐标最大值 | double | 8 |
合计 | 100 |
然后每个单独的空间记录信息都包括记录头和几何体记录信息两部分。其中,记录头共包括两个int类型,8个字节如下:
变量 | 类型 | 占用字节 |
---|---|---|
记录号 | Int | Int |
记录长度(这个记录长度是几何体记录信息,也就是不包括记录头的空间信息记录长度,以双字节为单位) | Int | 4 |
进一步,每个几何体记录信息分为两部分:shape类型(int类型,占用4字节)和空间坐标记录。
例如,最简单的,一个点坐标的记录固定占用20个字节,可以表示如下:

python 字节流读取Shp文件
下面开始用Python代码尝试用字节流读取shp文件!!!
首先,shp文件:
file_name= r'C:\Users\csh_g\Desktop\testdata\routeseg_ND_Junctions.shp'
然后,以二进制流读取模式打开文件:
f =open(file_name, "rb+")
python open() 函数打开文件的读取模式(参考菜鸟教程)

然后读取第一个4字节,这个变量是文件代码,一定等于9994:
readStream= f.read(4)
fileCode&