shapefile格式说明及读写代码示例.docx
- 文档编号:24684169
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:31
- 大小:24.93KB
shapefile格式说明及读写代码示例.docx
《shapefile格式说明及读写代码示例.docx》由会员分享,可在线阅读,更多相关《shapefile格式说明及读写代码示例.docx(31页珍藏版)》请在冰豆网上搜索。
shapefile格式说明及读写代码示例
Shapefile格式说明及读写代码示例
Shapefiles数据说明
Shapefiles是ESRI提供的一种矢量数据格式,它没有拓扑信息,一个Shapefiles由一组文件组成,其中必要的基本文件包括坐标文件(.shp)、索引文件(.shx)和属性文件(.dbf)三个文件。
坐标文件的结构说明
坐标文件(.shp)用于记录空间坐标信息。
它由头文件和实体信息两部分构成(如图2.1所示)。
坐标文件的文件头
坐标文件的文件头是一个长度固定(100bytes)的记录段,一共有9个int型和7个double型数据,主要记录内容见表2.2。
文件头
记录头
记录内容
记录头
记录内容
记录头
记录内容
记录头
记录内容
图2.1坐标文件的结构
起始位置
名称
数值
类型
位序
0
FileCode
9994
Integer
big
4
Unused
0
Integer
big
8
Unused
0
Integer
big
12
Unused
0
Integer
big
16
Unused
0
Integer
big
20
Unused
0
Integer
big
24
文件长度
文件的实际长度
Integer
big
28
版本号
1000
Integer
Little
32
几何类型
表示这个Shapefile文件所记录的空间数据的几何类型
Integer
Little
36
Xmin
空间数据所占空间范围的X方向最小值
Double
Little
44
Ymin
空间数据所占空间范围的Y方向最小值
Double
Little
52
Xmax
空间数据所占空间范围的X方向最大值
Double
Little
60
Ymax
空间数据所占空间范围的Y方向最大值
Double
Little
68*
Zmin
空间数据所占空间范围的Z方向最小值
Double
Little
76*
Zmax
空间数据所占空间范围的Z方向最大值
Double
Little
84*
Mmin
最小Measure值
Double
Little
92*
Mmax
最大Measure值
Double
Little
表2.2shapefiles头文件表
注:
最后4个加星号特别标示的四个数据只有当这个Shapefile文件包含Z方向坐标或者具有Measure值时才有值,否则为0.0。
所谓Measure值,是用于存储需要的附加数据,可以用来记录各种数据,例如权值、道路长度等信息。
位序
细心的读者会注意到表2.2中的数值的位序有Little和big的区别,对于位序是big的数据我们在读取时要小心。
通常,数据的位序都是Little,但在有些情况下可能会是big,二者的区别在于它们位序的顺序相反。
一个位序为big的数据,如果我们想得到它的真实数值,需要将它的位序转换成Little即可。
转换原理非常简单,就是交换字节顺序,下面是作者实现的在两者间进行转换的程序,代码如下:
//位序转换程序
unsignedlongOnChangeByteOrder(intindata)
{
charss[8];
charee[8];
unsignedlongval=unsignedlong(indata);
_ultoa(val,ss,16);//将十六进制的数(val)转到一个字符串(ss)中
inti;
intlength=strlen(ss);
if(length!
=8)
{
for(i=0;i<8-length;i++)
ee[i]='0';
for(i=0;i ee[i+8-length]=ss[i]; for(i=0;i<8;i++) ss[i]=ee[i]; } ////******进行倒序 intt; t =ss[0]; ss[0] =ss[6]; ss[6] =t; t =ss[1]; ss[1] =ss[7]; ss[7] =t; t =ss[2]; ss[2] =ss[4]; ss[4] =t; t =ss[3]; ss[3] =ss[5]; ss[5] =t; ////****** //******将存有十六进制数(val)的字符串(ss)中的十六进制数转成十进制数 intvalue=0; for(i=0;i<8;i++) { intk; CStringmass; mass=ss[i]; if(ss[i]=='a'|| ss[i]=='b'|| ss[i]=='c'|| ss[i]=='d'|| ss[i]=='e'|| ss[i]=='f') k=10+ss[i]-'a'; else sscanf(mass,"%d",&k); value=value+int(k*pow(16,7-i)); } return(value); } Shapefile文件支持的几何类型(ShapeType) Shapefile文件所支持的几何类型如表2.3所示: 编号 几何类型 0 NullShape(表示这个Shapefile文件不含坐标) 1 Point(表示Shapefile文件记录的是点状目标,但不是多点) 3 PolyLine(表示Shapefile文件记录的是线状目标) 5 Polygon(表示Shapefile文件记录的是面状目标) 8 MultiPoint(表示Shapefile文件记录的是多点,即点集合) 11 PointZ(表示Shapefile文件记录的是三维点状目标) 13 PolyLineZ(表示Shapefile文件记录的是三维线状目标) 15 PolygonZ(表示Shapefile文件记录的是三维面状目标) 18 MultiPointZ(表示Shapefile文件记录的是三维点集合目标) 21 PointM(表示含有Measure值的点状目标) 23 PolyLineM(表示含有Measure值的线状目标) 25 PolygonM(表示含有Measure值的面状目标) 28 MultiPointM(表示含有Measure值的多点目标) 31 MultiPatch(表示复合目标) 表2.3shapefiles文件支持的几何类型 对于一个不是记录NullShape类型的Shapefile文件,它所记录的空间目标的几何类型必须一致,不能在一个Shapefile文件中同时记录两种不同类型的几何目标。 读取坐标文件(.shp)的文件头的代码如下: voidOnReadShp(CStringShpFileName) { FILE* m_ShpFile_fp; //****Shp文件指针 //打开坐标文件 if((m_ShpFile_fp=fopen(ShpFileName,"rb"))==NULL) { return; } //读取坐标文件头的内容开始 intFileCode; intUnused; intFileLength; intVersion; intShapeType; doubleXmin; doubleYmin; doubleXmax; doubleYmax; doubleZmin; doubleZmax; doubleMmin; doubleMmax; fread(&FileCode, sizeof(int), 1,m_ShpFile_fp); FileCode =OnChangeByteOrder(FileCode); for(i=0;i<5;i++) fread(&Unused,sizeof(int), 1,m_ShpFile_fp); fread(&FileLength, sizeof(int), 1,m_ShpFile_fp); FileLength =OnChangeByteOrder(FileLength); fread(&Version, sizeof(int), 1,m_ShpFile_fp); fread(&ShapeType, sizeof(int), 1,m_ShpFile_fp); fread(&Xmin, sizeof(double),1,m_ShpFile_fp); fread(&Ymin, sizeof(double),1,m_ShpFile_fp); fread(&Xmax, sizeof(double),1,m_ShpFile_fp); fread(&Ymax, sizeof(double),1,m_ShpFile_fp); fread(&Zmin, sizeof(double),1,m_ShpFile_fp); fread(&Zmax, sizeof(double),1,m_ShpFile_fp); fread(&Mmin, sizeof(double),1,m_ShpFile_fp); fread(&Mmax, sizeof(double),1,m_ShpFile_fp); //读取坐标文件头的内容结束 //根据几何类型读取实体信息 } 实体信息的内容 实体信息负责记录坐标信息,它以记录段为基本单位,每一个记录段记录一个地理实体目标的坐标信息,每个记录段分为记录头和记录内容两部分。 记录头的内容包括记录号(RecordNumber)和坐标记录长度(ContentLength)两个记录项。 它们的位序都是big。 记录号(RecordNumber)和坐标记录长度(ContentLength)两个记录项都是int型,并且shapefile文件中的记录号都是从1开始的。 记录内容包括目标的几何类型(ShapeType)和具体的坐标记录(X、Y),记录内容因要素几何类型的不同其具体的内容及格式都有所不同。 下面分别介绍点状目标(Point)、线状目标(PolyLine)和面状目标(Polygon)三种几何类型的.shp文件的记录内容: 点状目标 shapefile中的点状目标由一对X、Y坐标构成,坐标值为双精度型(double)。 点状目标的记录内容如表2.4: 记录项 数值 数据类型 长度 个数 位序 几何类型(ShapeType) 1(表示点状目标) int型 4 1 Little X方向坐标 X方向坐标值 double型 8 1 Little Y方向坐标 Y方向坐标值 double型 8 1 Little 下面是读取点状目标的记录内容的代码: OnReadPointShp(CStringShpFileName) { //打开坐标文件 …… //读取坐标文件头的内容开始 …… //读取点状目标的实体信息 intRecordNumber; intContentLength; intnum =0; while((fread(&RecordNumber, sizeof(int), 1,ShpFile_fp)! =0)) { num++; fread(&ContentLength,sizeof(int), 1,ShpFile_fp); RecordNumber =OnChangeByteOrder(RecordNumber); ContentLength =OnChangeByteOrder(ContentLength); intshapeType; doublex; doubley; fread(&shapeType,sizeof(int), 1,ShpFile_fp); fread(&x,sizeof(double), 1,ShpFile_fp); fread(&y,sizeof(double), 1,ShpFile_fp); } } 线状目标 shapefile中的线状目标是由一系列点坐标串构成,一个线目标可能包括多个子线段,子线段之间可以是相离的,同时子线段之间也可以相交。 Shapefile允许出现多个坐标完全相同的连续点,当读取文件时一定要注意这种情况,但是不允许出现某个退化的、长度为0的子线段出现。 线状目标的记录内容如表2.5: 记录项 数值 数据类型 长度 个数 位序 几何类型(ShapeType) 3(表示线状目标) int型 4 1 Little 坐标范围(Box) 表示当前线目标的坐标范围 double型 32 4 Little 子线段个数(NumParts) 表示构成当前线目标的子线段的个数 int型 4 1 Little 坐标点数(NumPoints) 表示构成当前线目标所包含的坐标点个数 int型 4 1 Little Parts数组 记录了每个子线段的坐标在Points数组中的起始位置 int型 4×NumParts NumParts Little Points数组 记录了所有的坐标信息 Point型 根据点个数来确定 NumPoints Little 表2.5线状目标的记录内容 具体的数据结构如下: PolyLine { Double[4] Box //当前线状目标的坐标范围 Integer NumParts //当前线目标所包含的子线段的个数 Integer NumPoints //当前线目标所包含的顶点个数 Integer[NumParts] Parts //每个子线段的第一个坐标点在Points的位置 Point[NumPoints] Points //记录所有坐标点的数组 } 这些记录项的具体含义如下: Box记录了当前的线目标的坐标范围,它是一个double型的数组,按照Xmin、Ymin、Xmax、Ymax的顺序记录了坐标范围; NumParts记录了当前线目标所包含的子线段的个数; NumPoints记录了当前线目标的坐标点总数; Parts记录了每个子线段的第一个坐标点在坐标数组points中的位置,以便读取数据; Points是用于存放当前线目标的X、Y坐标的数组。 下面是读取线状目标的记录内容的代码: OnReadLineShp(CStringShpFileName) { //打开坐标文件 …… //读取坐标文件头的内容开始 …… //读取线状目标的实体信息 intRecordNumber; intContentLength; intnum =0; while((fread(&RecordNumber, sizeof(int), 1,ShpFile_fp)! =0)) { fread(&ContentLength,sizeof(int), 1,ShpFile_fp); RecordNumber =OnChangeByteOrder(RecordNumber); ContentLength =OnChangeByteOrder(ContentLength); intshapeType; doubleBox[4]; intNumParts; intNumPoints; int*Parts; fread(&shapeType, sizeof(int), 1,ShpFile_fp); //读Box for(i=0;i<4;i++) fread(Box+i, sizeof(double),1,ShpFile_fp); //读NumParts和NumPoints fread(&NumParts, sizeof(int), 1,ShpFile_fp); fread(&NumPoints, sizeof(int), 1,ShpFile_fp); //读Parts和Points Parts =newint[NumParts]; for(i=0;i fread(Parts+i, sizeof(int), 1,ShpFile_fp); intpointNum; for(i=0;i { if(i! =NumParts-1) pointNum =Parts[i+1]-Parts[i]; else pointNum =NumPoints-Parts[i]; double*PointsX; double*PointsY; PointsX=newdouble[pointNum]; PointsY=newdouble[pointNum]; for(j=0;j { fread(PointsX+j,sizeof(double),1,ShpFile_fp); fread(PointsY+j,sizeof(double),1,ShpFile_fp); } delete[]PointsX; delete[]PointsY; } delete[]Parts; } } 面状目标 shapefile中的面状目标是由多个子环构成,每个子环是由至少四个顶点构成的封闭的、无自相交现象的环。 对于含有岛的多边形,构成它的环有内外环之分,每个环的顶点的排列顺序或者方向说明了这个环到底是内环还是外环。 一个内环的顶点是按照逆时针顺序排列的;而对于外环,它的顶点排列顺序是顺时针方向。 如果一个多边形只由一个环构成,那么它的顶点排列顺序肯定是顺时针方向。 每条多边形记录的数据结构与线目标的数据结构完全相同, Polygon { Double[4] Box //当
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- shapefile 格式 说明 读写 代码 示例
![提示](https://static.bdocx.com/images/bang_tan.gif)