您的位置:首页 > 编程语言 > C语言/C++

C++底层读取Shp文件

2014-02-25 13:58 274 查看
FeatureClass* CGISMapDoc::ImportShapeFileData( FILE* fpShp, FILE* fpDbf )
{
//读Shp文件头开始
int fileCode = -1;
int fileLength = -1;
int version = -1;
int shapeType = -1;
fread(&fileCode , sizeof(int) , 1 , fpShp) ;
fileCode = ReverseBytes(fileCode) ;

if (fileCode != 9994)
{
CString strTemp ;
strTemp.Format(" WARNING filecode %d ", fileCode );
AfxMessageBox(strTemp);
}

for( int i = 0 ; i < 5 ; i ++ )
fread(&fileCode , sizeof(int) , 1 , fpShp) ;

fread(&fileLength , sizeof(int) , 1 , fpShp) ;
fileLength = ReverseBytes(fileLength) ;

fread(&version , sizeof(int) , 1 , fpShp) ;
fread(&shapeType , sizeof(int) , 1 , fpShp) ;

double tempOriginX , tempOriginY ;
fread( &tempOriginX , sizeof(double) , 1 , fpShp ) ;
fread( &tempOriginY , sizeof(double) , 1 , fpShp ) ;

double xMaxLayer , yMaxLayer ;
fread( &xMaxLayer , sizeof(double) , 1 , fpShp ) ;
fread( &yMaxLayer , sizeof(double) , 1 , fpShp ) ;

double* skip = new double[4] ;
fread( skip , sizeof(double) , 4 , fpShp ) ;
delete []skip ;
skip = 0 ;
//读Shp文件头结束

int uniqueID = this->m_pDataSource->GetUniqueID() ;
FeatureClass* pShpDataSet = 0 ;
//根据目标类型创建相应的图层DataSet。

switch( shapeType )
{
case 1 :
pShpDataSet = (FeatureClass*)&(m_pDataSource->CreateDataSet(uniqueID , POINTDATASET , layerName)) ;
break ;
case 3 :
case 23 :
pShpDataSet = (FeatureClass*)&(m_pDataSource->CreateDataSet(uniqueID , LINEDATASET , layerName)) ;
break ;
case 5 :
pShpDataSet = (FeatureClass*)&(m_pDataSource->CreateDataSet(uniqueID , POLYGONDATASET , layerName)) ;
break ;
}

if ( pShpDataSet == 0 ) return 0;

// 读DBF文件头---------begin------------

struct DBFHeader
{
char m_nValid;
char m_aDate[3];
char m_nNumRecords[4];
char m_nHeaderBytes[2];
char m_nRecordBytes[2];
char m_nReserved1[3];
char m_nReserved2[13];
char m_nReserved3[4];
}dbfheader;

struct DBFFIELDDescriptor
{
char m_sName[10];//应该为char m_sName[11]

char m_nType;
char m_nAddress[4];
char m_nFieldLength;
char m_nFieldDecimal;
char m_nReserved1[2];
char m_nWorkArea;
char m_nReserved2[2];
char m_nSetFieldsFlag;
char m_nReserved3[8];
};

fread(&dbfheader,sizeof(DBFHeader),1,fpDbf);
/*int recordsNum = *((int*)dbfheader.m_nNumRecords);
int headLen = *((short*)dbfheader.m_nHeaderBytes);
int everyRecordLen = *((short*)dbfheader.m_nRecordBytes);

if ( recordsNum == 0 || headLen == 0 || everyRecordLen == 0 )
return 0 ;

int fieldCount = (headLen - 1 - sizeof(DBFHeader))/sizeof(DBFFIELDDescriptor);

DBFFIELDDescriptor *pFields = new DBFFIELDDescriptor[fieldCount];
for ( i = 0; i < fieldCount; i ++ )
fread(&pFields[i],sizeof(DBFFIELDDescriptor),1,fpDbf);

char endByte;
fread(&endByte,sizeof(char),1,fpDbf);

if ( endByte != 0x0D)
{
delete []pFields;
pFields = 0;
return 0;
}*/

Fields& fields = pShpDataSet->GetFields();
DBFFIELDDescriptor field ;
BYTE endByte = ' ';
char fieldName[12];
int fieldDecimal, fieldLen, everyRecordLen = 0 ;
while ( !feof(fpDbf) )
{
fread(&endByte,sizeof(BYTE),1,fpDbf);
if ( endByte == 0x0D) break ;
fread(&field,sizeof(DBFFIELDDescriptor),1,fpDbf);

fieldName[0] = endByte;
for ( i = 0; i < 10; i ++ )
fieldName[i+1] = field.m_sName[i];
fieldName[11] = '/0';

fieldDecimal = field.m_nFieldDecimal;
fieldLen = field.m_nFieldLength;
switch( field.m_nType )
{
case 'C':
fields.AddField(fieldName,fieldName,FIELD_STRING,fieldLen);
break;
case 'F':
fields.AddField(fieldName,fieldName,FIELD_DOUBLE,fieldLen);
break;
case 'N':
{
if ( fieldDecimal == 0 )
fields.AddField(fieldName,fieldName,FIELD_INT,fieldLen);
else fields.AddField(fieldName,fieldName,FIELD_DOUBLE,fieldLen);
}
break;
}
everyRecordLen += fieldLen ;
}
// 读DBF文件头---------end------------

while( !feof(fpShp) )
{
//读记录头开始
int recordNumber = -1 ;
int contentLength = -1 ;
fread(&recordNumber , sizeof(int) , 1 , fpShp) ;
fread(&contentLength , sizeof(int) , 1 , fpShp) ;
recordNumber = ReverseBytes(recordNumber) ;
contentLength = ReverseBytes(contentLength) ;
//读记录头结束

switch( shapeType )
{
case 1: // '/001'

//读取点目标开始
{
Fields &featureFields = pShpDataSet->GetFields();
Feature *pFeature = new Feature(recordNumber , 1 , &featureFields) ;

int pointShapeType ;
fread(&pointShapeType , sizeof(int) , 1 , fpShp) ;
double xValue , yValue ;
fread(&xValue , sizeof(double) , 1 , fpShp) ;
fread(&yValue , sizeof(double) , 1 , fpShp) ;

GeoPoint *pNewGeoPoint = new GeoPoint( xValue , yValue ) ;
pFeature->SetBound(xValue , yValue , 0 , 0 ) ;
pFeature->SetGeometry(pNewGeoPoint) ;
this->LoadAttributeData(pFeature,fpDbf,everyRecordLen);
pShpDataSet->AddRow(pFeature) ;
}
break ;
//读取点目标结束

case 3: // '/003'

//读取线目标开始
{
Fields &featureFields = pShpDataSet->GetFields();
Feature *pFeature = new Feature(recordNumber , 1 , &featureFields) ;

int arcShapeType ;
fread(&arcShapeType , sizeof(int) , 1 , fpShp) ;

double objMinX , objMinY , objMaxX , objMaxY ;
fread(&objMinX , sizeof(double) , 1 , fpShp) ;
fread(&objMinY , sizeof(double) , 1 , fpShp) ;
fread(&objMaxX , sizeof(double) , 1 , fpShp) ;
fread(&objMaxY , sizeof(double) , 1 , fpShp) ;

GeoPolyline *pNewGeoLine = new GeoPolyline();
double width = objMaxX - objMinX ;
double height = objMaxY - objMinY ;
pFeature->SetBound(objMinX , objMinY , width , height) ;

int numParts , numPoints ;
fread(&numParts , sizeof(int) , 1 , fpShp) ;
fread(&numPoints , sizeof(int) , 1 , fpShp) ;
//存储各段线的起点索引
int* startOfPart = new int[numParts] ;
for( int i = 0 ; i < numParts ; i++ )
{
int indexFirstPoint ;
fread(&indexFirstPoint , sizeof(int) , 1 , fpShp) ;
startOfPart[i] = indexFirstPoint ;
}

//处理单个目标有多条线的问题

pNewGeoLine->SetPointsCount( numParts ) ;

for( i = 0 ; i < numParts ; i++ )
{
GeoPoints& points = pNewGeoLine->GetPoints(i) ;
int curPosIndex = startOfPart[i] ;
int nextPosIndex = 0 ;
int curPointCount = 0 ;
if( i == numParts - 1 )
curPointCount = numPoints - curPosIndex ;
else
{
nextPosIndex = startOfPart[i + 1] ;
curPointCount = nextPosIndex - curPosIndex ;
}
points.SetPointCount( curPointCount ) ;
//加载一条线段的坐标
for( int iteratorPoint = 0 ; iteratorPoint < curPointCount ; iteratorPoint ++ )
{
double x , y ;
fread(&x , sizeof(double) , 1 , fpShp) ;
fread(&y , sizeof(double) , 1 , fpShp) ;
GeoPoint newVertex(x, y);
points.SetPoint(iteratorPoint, newVertex);
}
}
delete []startOfPart ;
startOfPart = 0 ;
pFeature->SetGeometry(pNewGeoLine) ;
this->LoadAttributeData(pFeature,fpDbf,everyRecordLen);
pShpDataSet->AddRow(pFeature) ;
}
break ;
//读取线目标结束

case 5: // '/005'

//读取面目标开始
{
Fields &featureFields = pShpDataSet->GetFields();
Feature *pFeature = new Feature(recordNumber , 1 , &featureFields) ;
int polygonShapeType ;
fread(&polygonShapeType , sizeof(int) , 1 ,fpShp) ;
if( polygonShapeType != 5 )
AfxMessageBox( "Error: Attempt to load non polygon shape as polygon." ) ;

double objMinX , objMinY , objMaxX , objMaxY ;
fread(&objMinX , sizeof(double) , 1 , fpShp) ;
fread(&objMinY , sizeof(double) , 1 , fpShp) ;
fread(&objMaxX , sizeof(double) , 1 , fpShp) ;
fread(&objMaxY , sizeof(double) , 1 , fpShp) ;

GeoPolygon *pNewGeoPolygon = new GeoPolygon();
double width = objMaxX - objMinX ;
double height = objMaxY - objMinY ;
pFeature->SetBound(objMinX , objMinY , width , height) ;

int numParts , numPoints ;
fread(&numParts , sizeof(int) , 1 , fpShp) ;
fread(&numPoints , sizeof(int) , 1 , fpShp) ;
//存储各个面的起点索引

int* startOfPart = new int[numParts] ;
for( int i = 0 ; i < numParts ; i++ )
{
int indexFirstPoint ;
fread(&indexFirstPoint , sizeof(int) , 1 , fpShp) ;
startOfPart[i] = indexFirstPoint ;
}

//处理单个目标有多面问题
pNewGeoPolygon->SetPointsCount( numParts ) ;

for( i = 0 ; i < numParts ; i++ )
{
GeoPoints& points = pNewGeoPolygon->GetPoints(i) ;
int curPosIndex = startOfPart[i] ;
int nextPosIndex = 0 ;
int curPointCount = 0 ;
if( i == numParts - 1 )
curPointCount = numPoints - curPosIndex ;
else
{
nextPosIndex = startOfPart[i + 1];
curPointCount = nextPosIndex - curPosIndex ;
}
points.SetPointCount( curPointCount ) ;
//加载一个面(多边形)的坐标

for( int iteratorPoint = 0 ; iteratorPoint < curPointCount ; iteratorPoint ++ )
{
double x , y ;
fread(&x , sizeof(double) , 1 , fpShp) ;
fread(&y , sizeof(double) , 1 , fpShp) ;
GeoPoint newVertex(x, y);
points.SetPoint(iteratorPoint, newVertex);
}
}
delete []startOfPart ;
startOfPart = 0 ;
pFeature->SetGeometry(pNewGeoPolygon) ;
this->LoadAttributeData(pFeature,fpDbf,everyRecordLen);
pShpDataSet->AddRow(pFeature) ;
}
break ;
//读取面目标结束

case 23: // '/027'

//读取Measure形线目标开始

{
Fields &featureFields = pShpDataSet->GetFields();
Feature *pFeature = new Feature(recordNumber , 1 , &featureFields) ;
int arcMShapeType ;
fread(&arcMShapeType , sizeof(int) , 1 , fpShp) ;

double objMinX , objMinY , objMaxX , objMaxY ;
fread(&objMinX , sizeof(double) , 1 , fpShp) ;
fread(&objMinY , sizeof(double) , 1 , fpShp) ;
fread(&objMaxX , sizeof(double) , 1 , fpShp) ;
fread(&objMaxY , sizeof(double) , 1 , fpShp) ;

GeoPolyline *pNewGeoLine = new GeoPolyline();
double width = objMaxX - objMinX ;
double height = objMaxY - objMinY ;
pFeature->SetBound(objMinX , objMinY , width , height) ;

int numParts , numPoints ;
fread(&numParts , sizeof(int) , 1 , fpShp) ;
fread(&numPoints , sizeof(int) , 1 , fpShp) ;
//存储各段线的起点索引
int* startOfPart = new int[numParts] ;
for( int i = 0 ; i < numParts ; i++ )
{
int indexFirstPoint ;
fread(&indexFirstPoint , sizeof(int) , 1 , fpShp) ;
startOfPart[i] = indexFirstPoint ;
}

//处理单个目标有多条线的问题

pNewGeoLine->SetPointsCount( numParts ) ;

for( i = 0 ; i < numParts ; i++ )
{
GeoPoints& points = pNewGeoLine->GetPoints(i) ;
int curPosIndex = startOfPart[i] ;
int nextPosIndex = 0 ;
int curPointCount = 0 ;
if( i == numParts - 1 )
curPointCount = numPoints - curPosIndex ;
else
{
nextPosIndex = startOfPart[i + 1] ;
curPointCount = nextPosIndex - curPosIndex ;
}
points.SetPointCount( curPointCount ) ;
//加载一条线段的坐标
for( int iteratorPoint = 0 ; iteratorPoint < curPointCount ; iteratorPoint ++ )
{
double x , y ;
fread(&x , sizeof(double) , 1 , fpShp) ;
fread(&y , sizeof(double) , 1 , fpShp) ;
GeoPoint newVertex(x, y);
points.SetPoint(iteratorPoint, newVertex);
}
}
delete []startOfPart ;
startOfPart = 0 ;

double* value = new double[2 + numPoints] ;
fread( value , sizeof(double) , 2+numPoints, fpShp) ;
delete []value ;
value = 0 ;

pFeature->SetGeometry(pNewGeoLine) ;
this->LoadAttributeData(pFeature,fpDbf,everyRecordLen);
pShpDataSet->AddRow(pFeature);
}
break ;
//读取Measure形线目标结束

}
}
return pShpDataSet ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: