您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > SHP文件的常识介绍及C++算法与C#算法实现
shp文件的读取首先了解一下shp文件的一些简单知识Shapefile文件是美国环境系统研究所(ESRI)所研制的GIS文件系统格式文件,是工业标准的矢量数据文件。Shapefile将空间特征表中的非拓扑几何对象和属性信息存储在数据集中,特征表中的几何对象存为以坐标点集表示的图形文件—SHP文件,Shapefile文件并不含拓扑(Topological)数据结构。一个Shape文件包括三个文件:一个主文件(*.shp),一个索引文件(*.shx),和一个dBASE(*.dbf)表。主文件是一个直接存取,变长度记录的文件,其中每个记录描述构成一个地理特征(Feature)的所有vertices坐标值。在索引文件中,每条记录包含对应主文件记录距离主文件头开始的偏移量,dBASE表包含SHP文件中每一个Feature的特征属性,表中几何记录和属性数据之间的一一对应关系是基于记录数目的ID。在dBASE文件中的属性记录必须和主文件中的记录顺序是相同的。图形数据和属性数据通过索引号建立一一对应的关系Shapefile中坐标文件(.shp)由固定长度的文件头和接着的变长度空间数据记录组成。文件头由100字节的说明信息组成的,主要说明文件的长度、Shape类型、整个Shape图层的范围等等,这些信息构成了空间数据的元数据。在导入空间数据时首先要读入文件头获取Shape文件的基本信息,并以此信息为基础建立相应的元数据表。而变长度空间数据记录是由固定长度的记录头和变长度记录内容组成,其记录结构基本类似,每条记录都有记录头和记录内容组成(空间坐标对)。记录头的内容包括记录号(RecordNumber)和坐标记录长度(ContentLength)两个记录项,Shapefile文件中的记录号都是从1开始的,坐标记录长度是按16位字来衡量的。记录内容包括目标的几何类型(ShapeType)和具体的坐标记录(X,Y),记录内容因要素几何类型的不同,其具体的内容和格式都有所不同。对于具体的记录主要包括空Shape记录,点记录,线记录和多边形记录。属性文件(.dbf)用于记录属性信息。它是一个标准的DBF文件,也是由头文件和实体信息两部分构成。其中文件头部分的长度是不定长的,它主要对DBF文件作了一些总体说明,其中最主要的是对这个DBF文件的记录项的信息进行了详细的描述,比如对每个记录项的名称,数据类型,长度等信息都有具体的说明。属性文件的实体信息部分就是一条条属性记录,每条记录都是由若干个记录项构成,因此只要依次循环读取每条记录就可以了。索引文件(.shx)主要包含坐标文件的索引信息,文件中每个记录包含对应的坐标文件记录距离坐标文件的文件头的偏移量。通过索引文件可以很方便地在坐标文件中定位到指定目标地坐标信息。索引文件也是由文件头和实体信息两部分构成的,其中文件头部分是一个长度固定(100bytes)的记录段,其内容与坐标文件的文件头基本一致。它的实体信息以记录为基本单位,每一条记录包括偏移量(Offset)和记录段长度(ContentLength)两个记录项。接下来我们再看一下代码(c++):SHP文件的读取viewplain1.FeatureClass*CGISMapDoc::ImportShapeFileData(FILE*fpShp,FILE*fpDbf)2.{3.//读Shp文件头开始4.intfileCode=-1;5.intfileLength=-1;6.intversion=-1;7.intshapeType=-1;8.fread(&fileCode,sizeof(int),1,fpShp);9.fileCode=ReverseBytes(fileCode);10.11.if(fileCode!=9994)12.{13.CStringstrTemp;14.strTemp.Format(WARNINGfilecode%d,fileCode);15.AfxMessageBox(strTemp);16.}17.18.for(inti=0;i5;i++)19.fread(&fileCode,sizeof(int),1,fpShp);20.21.fread(&fileLength,sizeof(int),1,fpShp);22.fileLength=ReverseBytes(fileLength);23.24.fread(&version,sizeof(int),1,fpShp);25.fread(&shapeType,sizeof(int),1,fpShp);26.27.doubletempOriginX,tempOriginY;28.fread(&tempOriginX,sizeof(double),1,fpShp);29.fread(&tempOriginY,sizeof(double),1,fpShp);30.31.doublexMaxLayer,yMaxLayer;32.fread(&xMaxLayer,sizeof(double),1,fpShp);33.fread(&yMaxLayer,sizeof(double),1,fpShp);34.35.double*skip=newdouble[4];36.fread(skip,sizeof(double),4,fpShp);37.delete[]skip;38.skip=0;39.//读Shp文件头结束40.41.intuniqueID=this-m_pDataSource-GetUniqueID();42.FeatureClass*pShpDataSet=0;43.//根据目标类型创建相应的图层DataSet。44.switch(shapeType)45.{46.case1:47.pShpDataSet=(FeatureClass*)&(m_pDataSource-CreateDataSet(uniqueID,POINTDATASET,layerName));48.break;49.case3:50.case23:51.pShpDataSet=(FeatureClass*)&(m_pDataSource-CreateDataSet(uniqueID,LINEDATASET,layerName));52.break;53.case5:54.pShpDataSet=(FeatureClass*)&(m_pDataSource-CreateDataSet(uniqueID,POLYGONDATASET,layerName));55.break;56.}57.58.if(pShpDataSet==0)return0;59.60.//读DBF文件头---------begin------------61.structDBFHeader62.{63.charm_nValid;64.charm_aDate[3];65.charm_nNumRecords[4];66.charm_nHeaderBytes[2];67.charm_nRecordBytes[2];68.charm_nReserved1[3];69.charm_nReserved2[13];70.charm_nReserved3[4];71.}dbfheader;72.73.structDBFFIELDDescriptor74.{75.charm_sName[10];//应该为charm_sName[11]76.charm_nType;77.charm_nAddress[4];78.charm_nFieldLength;79.charm_nFieldDecimal;80.charm_nReserved1[2];81.charm_nWorkArea;82.charm_nReserved2[2];83.charm_nSetFieldsFlag;84.charm_nReserved3[8];85.};86.87.fread(&dbfheader,sizeof(DBFHeader),1,fpDbf);88./*intrecordsNum=*((int*)dbfheader.m_nNumRecords);89.intheadLen=*((short*)dbfheader.m_nHeaderBytes);90.inteveryRecordLen=*((short*)dbfheader.m_nRecordBytes);91.92.if(recordsNum==0||headLen==0||everyRecordLen==0)93.return0;94.95.intfieldCount=(headLen-1-sizeof(DBFHeader))/sizeof(DBFFIELDDescriptor);96.97.DBFFIELDDescriptor*pFields=newDBFFIELDDescriptor[fieldCount];98.for(i=0;ifieldCount;i++)99.fread(&pFields[i],sizeof(DBFFIELDDescriptor),1,fpDbf);100.101.charendByte;102.fread(&endByte,sizeof(char),1,fpDbf);103.104.if(endByte!=0x0D)105.{106.delete[]pFields;107.pFields=0;108.return0;109.}*/110.111.112.113.Fields&fields=pShpDataSet-GetFields();114.DBFFIELDDescriptorfield;115.BYTEendByte='';116.charfieldName[12];117.intfieldDecimal,fieldLen,everyRecordLen=0;118.while(!feof(fpDbf))119.{120.fread(&endByte,sizeof(BYTE),1,fpDbf);121.if(endByte==0x0D)break;122.fread(&field,sizeof(DBFFIELDDescriptor),1,fpDbf);123.124.fieldName[0]=endByte;125.for(i=0;i10;i++)126.fieldName[i+1]=field.m_sName[i];127.fieldName[11]='/0';128.129.fieldDecimal=field.m_nFieldDecimal;130.fieldLen=field.m_nFieldLength;131.switch(field.m_nType)132.{133.case'C':134.fields.AddField(fieldName,fieldName,FIELD_STRING,fieldLen);135.break;136.case'F':137.fields.AddField(fieldName,fieldName,FIELD_DOUBLE,fieldLen);138.break;139.case'N':140.{141.if(fieldDecimal==0)142.fields.AddField(fieldName,fieldName,FIELD_INT,fieldLen);143.elsefields.AddField(fieldName,fieldName,FIELD_DOUBLE,fieldLen);144.}145.break;146.}147.everyRecordLen+=fieldLen;148.}149.//读DBF文件头---------end------------150.151.while(!feof(fpShp))152.{153.//读记录头开始154.intrecordNumber=-1;155.intcontentLe
本文标题:SHP文件的常识介绍及C++算法与C#算法实现
链接地址:https://www.777doc.com/doc-5200349 .html