- 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 ;
- }
C++底层读取Shp文件
最新推荐文章于 2025-06-12 15:28:51 发布