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);
}
(2) 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);
//读取坐标文件头的内容结束
//根据几何类型读取实体信息
……
}
2) 实体信息的内容
实体信息负责记录坐标信息,它以记录段为基本单位,每一个记录段记录一个地理实体目标的坐标信息,每个记录段分为记录头和记录内容两部分。
记录头的内容包括记录号(RecordNumber)和坐标记录长度(ContentLength)两个记录项。
它们的位序都是big。
记录号(RecordNumber)和坐标记录长度(ContentLength)两个记录项都是int型,并且shapefile文件中的记录号都是从1开始的。
记录内容包括目标的几何类型(ShapeType)和具体的坐标记录(X、Y),记录内容因要素几何类型的不同其具体的内容及格式都有所不同。
下面分别介绍点状目标(Point)、线状目标(PolyLine)和面状目标(Polygon)三种几何类型的.shp文件的记录内容:
(1) 点状目标
shapefile中的点状目标由一对X、Y坐标构成,坐标值为双精度型(double)。
点状目标的记录内容如表2.4:
记录项
数值
数据类型
长度
个数
位序
几何类型(ShapeType)
1(表示点状目标)
int型
4
1
Little
X方向坐标
X方向坐标值
double型
8
1
Little
Y方向坐标
Y方向坐标值
double型
8
1
Little
表2.4点状目标的记录内容
下面是读取点状目标的记录内容的代码:
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);
}
}
(2) 线状目标
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;
}
}
(3) 面状目标
shapefile中的面状目标是由多个子环构成,每个子环是由至少四个顶点构成的封闭的、无自相交现象的环。
对于含有岛的多边形,构成它的环有内外环之分,每个环的顶点的排列顺序或者方向说明了这个环到底是内环还是外环。
一个内环的顶点是按照逆时针顺序排列的;而对于外环,它的顶点排列顺序是顺时针方向。
如果一个多边形只由一个环构成,那么它的顶点排列顺序肯定是顺时针方向。
每条多边形记录的数据结构与线目标的数据结构完全相同,
Polygon
{
Double[4] Box //当前面状目标的坐标范围
Integer NumParts //当