Shp数据结构解析及一种底层读取方法

2020-08-12 06:48陈明超刘朋飞
科学技术创新 2020年21期
关键词:字段折线数据结构

陈明超 刘朋飞*

(天津师范大学 地理与环境科学学院,天津300387)

Shapefile 文件是ESRI 公司提出的用于描述空间数据的几何和属性特征的非拓扑实体矢量数据结构的一种格式[1],利用欧几里得几何学中的点、线、面、体来表示地理实体的一种数据组织方式。该文件格式已经成为GIS 界的一个开放标准,同时也是一种重要的矢量数据交换格式。能很好的表达地理实体分布特征、数据精度高、冗余度低,在桌面版GIS 应用程序和WebGIS中有广泛的应用。

1 Shapefile 数据文件结构

一个完整的Shapfile 文件包含如下(如表1 所示)几个子文件,常用的子文件包括.shx 格式的几何特征索引文件,.shp 格式的几何文件,.dbf 格式的属性文件[2]和.prj 格式的投影文件。.shp文件为其中的主文件,本文的研究基于此展开。

表1 Shapefile 文件子文件

Shp 数据结构:

Shp 文件主要由文件头和信息记录两部分组成,文件头存储与文件基本特征相对应的数据,信息记录由多条子记录组成,每条记录表示相应的几何实体信息。文件头总长度为100 字节,分为基本识别信息和空间概况信息。基本识别信息包含八个int类型字段,总长度32 字节。空间概况信息包含一个int 类型字段和八个double 类型字段,总长度68 字节。具体字段信息如表2和表3 所示。

表2 基本识别信息结构

表3 空间概况信息字段信息结构

其中最大最小X,Y 坐标值构成了最小外接矩形(MER),Z 坐标为非必要字段。读取时按照起始位置依次读取,如读取FileCode 字段从第零位开始,读Unused 字段从第四位开始读。

信息记录部分由多个子记录组成,没有固定的长度,最终长度取决于子记录的个数和每个子记录的长度。每个子记录由记录头信息和空间信息记录组成,记录头信息包含记录号和记录长度,均为int 型,总长度为八字节。空间记录信息包含数据类型和坐标对信息,具体结构如图1 所示。

表4 空间实体类型

图1 空间记录信息结构

其中的Shapetype 字段表示该shp 数据表示的实体类型,常见的类型包括点(point)、线(polyline)和面(polygon)等。全部的实体类型如表4 所示。

1.1 point 数据结构

Point 是shp 数据中最简单的实体类型,由一个int 型的Shapetype 和一对double 型的坐标对组成,单个Point 实体长度固定为20 字节,存储结构如图2 所示。

图2 Point 对象存储结构

1.2 polyline 数据结构

Polyline 是我们常用的另一种实体类型,GIS 中的河流,路网等都属于polyline 实体。一个polyline 实体可能包含一条折线,也可能包含多条折线,每条折线叫做一个分段,每次读取依次从每条折线首个节点索引位置开始。在polyline 存储结构中,存储最小外接多边形、折线数、每条折线的起始点位置、节点数目以及所有的节点坐标等。具体的存储字段如表5 所示,存储结构如图3 所示,示例如图4 和图5 所示。

表5 polyline 数据存储字段

图3 polyline 存储结构

图4 示例polyline

图5 多段线存储结构

1.3 polygon 数据结构

polygon 是shapefile 数据中又一重要的实体类型,常用来表示公园、小区、省市等面状实体。一个polygon 可由一个polyline实体首尾相连组成,也可由多个polyline 实体首尾相连组成,每个节点的坐标可由polyline 存储结构中获取,该方法保证了多边形公共边的唯一性[3]。同时每条边具有方向性,最外层的polyline 由起点沿顺时针到终点,其手边为polygon 区域,存在岛的polygon 为起点沿逆时针方向到终点的右手边方向。组成polygon 的边界polyline 不能存在交叉,即为一个“干净的多边形”[4]。由于polyline 为闭合环,存在首尾重合,所以在存储上会多一个point,比如存储一个四边形边界要存储五个点。polygon由polyline 组成,同时具有与polyline 相同的存储结构。

2 Shp 数据读取程序设计

2.1 设计原则及方法

本次程序设计使用Visual Studio 2019 平台,使用的语言为C#语言,采用纯底层面向对象的方法实现。

本次设计基于文件流的方式,使用BinaryReader 类读取二进制文件。通过解析数据结构,可知.shp 数据结构中存储的字段为长度为四个字节的int 型和长度为为八个字节的double 型,使用BinaryReader 类提供的ReadInt32()方法和ReadDouble()方法进行读取,ReadInt32()方法从当前流中读取四个字节的有符号整数,并使流的当前位置提升四个字节,ReadDouble()从当前流中读取八个字节的浮点值,并使流的当前位置提升八个字节,这两种方法保证了相邻两次读取文件的连续性。

2.2 核心代码说明

3 程序测试

本次程序测试使用的数据为point、ployline 和polygon 三种类型,测试结果如图6- 图8 所示。

图6 点数据测试结果

图7 线数据测试结果

图8 面数据测试结果

本文首先对Shapefile 文件结构做了详细的解析,使读者对我们常用的Shapefile 文件的组成有了清晰的了解。同时本文将研究重点放在了shp 数据结构解析上,使读者对shp 数据的理解从简单的的“点、线、面、坐标对”层次上升到更加详细的结构化层次,包括完整的shp 数据结构、点线面不同实体的数据结构以及不同位置字段的类型和长度。在文章的最后采用winForm形式基于文件流的方法实现从底层进行读取,并得到了很好的效果。由于能力有限,程序中还存在一些不足,比如无法实现点线面实体的叠加显示,无法显示属性信息等。在我们今后的学习中还会做深入的研究和完善。近年来,随着轻量化GIS 的 发展,.shp 数据在web 服务发布中更得到了进一步的应用,比如在GeoServer 中发布为地图服务[5],在QGIS 中转换成轻量级的JSON 格式数据供前后端交互等。今后的研究将在此研究的基础上,把一部分精力放在shp 数据格式研究和应用研究上,在GIS应用和发展中,发挥出shp 数据更大的作用和优势。

猜你喜欢
字段折线数据结构
平面分割问题的探究之旅
解信赖域子问题的多折线算法
带钩或不带钩选择方框批量自动换
数据结构线上线下混合教学模式探讨
为什么会有“数据结构”?
浅谈台湾原版中文图书的编目经验
折线
折线图案
高职高专数据结构教学改革探讨
无正题名文献著录方法评述