📄 s57reader.cpp
字号:
case RCNM_VI: poIndex = &oVI_Index; pszFDName = OGRN_VI; break; case RCNM_VC: poIndex = &oVC_Index; pszFDName = OGRN_VC; break; case RCNM_VE: poIndex = &oVE_Index; pszFDName = OGRN_VE; break; case RCNM_VF: poIndex = &oVF_Index; pszFDName = OGRN_VF; break; default: CPLAssert( FALSE ); return NULL; } if( nFeatureId < 0 || nFeatureId >= poIndex->GetCount() ) return NULL; DDFRecord *poRecord = poIndex->GetByIndex( nFeatureId );/* -------------------------------------------------------------------- *//* Find the feature definition to use. *//* -------------------------------------------------------------------- */ OGRFeatureDefn *poFDefn = NULL; for( int i = 0; i < nFDefnCount; i++ ) { if( EQUAL(papoFDefnList[i]->GetName(),pszFDName) ) { poFDefn = papoFDefnList[i]; break; } } if( poFDefn == NULL ) { CPLAssert( FALSE ); return NULL; }/* -------------------------------------------------------------------- *//* Create feature, and assign standard fields. *//* -------------------------------------------------------------------- */ OGRFeature *poFeature = new OGRFeature( poFDefn ); poFeature->SetFID( nFeatureId ); poFeature->SetField( "RCNM", poRecord->GetIntSubfield( "VRID", 0, "RCNM",0) ); poFeature->SetField( "RCID", poRecord->GetIntSubfield( "VRID", 0, "RCID",0) ); poFeature->SetField( "RVER", poRecord->GetIntSubfield( "VRID", 0, "RVER",0) ); poFeature->SetField( "RUIN", poRecord->GetIntSubfield( "VRID", 0, "RUIN",0) );/* -------------------------------------------------------------------- *//* Collect point geometries. *//* -------------------------------------------------------------------- */ if( nRCNM == RCNM_VI || nRCNM == RCNM_VC ) { double dfX=0.0, dfY=0.0, dfZ=0.0; if( poRecord->FindField( "SG2D" ) != NULL ) { dfX = poRecord->GetIntSubfield("SG2D",0,"XCOO",0) / (double)nCOMF; dfY = poRecord->GetIntSubfield("SG2D",0,"YCOO",0) / (double)nCOMF; poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY ) ); } else if( poRecord->FindField( "SG3D" ) != NULL ) /* presume sounding*/ { int i, nVCount = poRecord->FindField("SG3D")->GetRepeatCount(); if( nVCount == 1 ) { dfX =poRecord->GetIntSubfield("SG3D",0,"XCOO",0)/(double)nCOMF; dfY =poRecord->GetIntSubfield("SG3D",0,"YCOO",0)/(double)nCOMF; dfZ =poRecord->GetIntSubfield("SG3D",0,"VE3D",0)/(double)nSOMF; poFeature->SetGeometryDirectly( new OGRPoint( dfX, dfY, dfZ )); } else { OGRMultiPoint *poMP = new OGRMultiPoint(); for( i = 0; i < nVCount; i++ ) { dfX = poRecord->GetIntSubfield("SG3D",0,"XCOO",i) / (double)nCOMF; dfY = poRecord->GetIntSubfield("SG3D",0,"YCOO",i) / (double)nCOMF; dfZ = poRecord->GetIntSubfield("SG3D",0,"VE3D",i) / (double)nSOMF; poMP->addGeometryDirectly( new OGRPoint( dfX, dfY, dfZ ) ); } poFeature->SetGeometryDirectly( poMP ); } } }/* -------------------------------------------------------------------- *//* Collect an edge geometry. *//* -------------------------------------------------------------------- */ else if( nRCNM == RCNM_VE && poRecord->FindField( "SG2D" ) != NULL ) { int i, nVCount = poRecord->FindField("SG2D")->GetRepeatCount(); OGRLineString *poLine = new OGRLineString(); poLine->setNumPoints( nVCount ); for( i = 0; i < nVCount; i++ ) { poLine->setPoint( i, poRecord->GetIntSubfield("SG2D",0,"XCOO",i) / (double)nCOMF, poRecord->GetIntSubfield("SG2D",0,"YCOO",i) / (double)nCOMF ); } poFeature->SetGeometryDirectly( poLine ); }/* -------------------------------------------------------------------- *//* Special edge fields. *//* -------------------------------------------------------------------- */ DDFField *poVRPT; if( nRCNM == RCNM_VE && (poVRPT = poRecord->FindField( "VRPT" )) != NULL ) { poFeature->SetField( "NAME_RCNM_0", RCNM_VC ); poFeature->SetField( "NAME_RCID_0", ParseName( poVRPT, 0 ) ); poFeature->SetField( "ORNT_0", poRecord->GetIntSubfield("VRPT",0,"ORNT",0) ); poFeature->SetField( "USAG_0", poRecord->GetIntSubfield("VRPT",0,"USAG",0) ); poFeature->SetField( "TOPI_0", poRecord->GetIntSubfield("VRPT",0,"TOPI",0) ); poFeature->SetField( "MASK_0", poRecord->GetIntSubfield("VRPT",0,"MASK",0) ); poFeature->SetField( "NAME_RCNM_1", RCNM_VC ); poFeature->SetField( "NAME_RCID_1", ParseName( poVRPT, 1 ) ); poFeature->SetField( "ORNT_1", poRecord->GetIntSubfield("VRPT",0,"ORNT",1) ); poFeature->SetField( "USAG_1", poRecord->GetIntSubfield("VRPT",0,"USAG",1) ); poFeature->SetField( "TOPI_1", poRecord->GetIntSubfield("VRPT",0,"TOPI",1) ); poFeature->SetField( "MASK_1", poRecord->GetIntSubfield("VRPT",0,"MASK",1) ); } return poFeature;}/************************************************************************//* FetchPoint() *//* *//* Fetch the location of a spatial point object. *//************************************************************************/int S57Reader::FetchPoint( int nRCNM, int nRCID, double * pdfX, double * pdfY, double * pdfZ ){ DDFRecord *poSRecord; if( nRCNM == RCNM_VI ) poSRecord = oVI_Index.FindRecord( nRCID ); else poSRecord = oVC_Index.FindRecord( nRCID ); if( poSRecord == NULL ) return FALSE; double dfX = 0.0, dfY = 0.0, dfZ = 0.0; if( poSRecord->FindField( "SG2D" ) != NULL ) { dfX = poSRecord->GetIntSubfield("SG2D",0,"XCOO",0) / (double)nCOMF; dfY = poSRecord->GetIntSubfield("SG2D",0,"YCOO",0) / (double)nCOMF; } else if( poSRecord->FindField( "SG3D" ) != NULL ) { dfX = poSRecord->GetIntSubfield("SG3D",0,"XCOO",0) / (double)nCOMF; dfY = poSRecord->GetIntSubfield("SG3D",0,"YCOO",0) / (double)nCOMF; dfZ = poSRecord->GetIntSubfield("SG3D",0,"VE3D",0) / (double)nSOMF; } else return FALSE; if( pdfX != NULL ) *pdfX = dfX; if( pdfY != NULL ) *pdfY = dfY; if( pdfZ != NULL ) *pdfZ = dfZ; return TRUE;}/************************************************************************//* FetchLine() *//************************************************************************/int S57Reader::FetchLine( DDFRecord *poSRecord, int iStartVertex, int iDirection, OGRLineString *poLine ){ int nVCount; DDFField *poSG2D = poSRecord->FindField( "SG2D" ); DDFSubfieldDefn *poXCOO=NULL, *poYCOO=NULL; int bStandardFormat = TRUE;/* -------------------------------------------------------------------- *//* Get some basic definitions. *//* -------------------------------------------------------------------- */ if( poSG2D != NULL ) { poXCOO = poSG2D->GetFieldDefn()->FindSubfieldDefn("XCOO"); poYCOO = poSG2D->GetFieldDefn()->FindSubfieldDefn("YCOO"); if( poXCOO == NULL || poYCOO == NULL ) { CPLDebug( "S57", "XCOO or YCOO are NULL" ); return FALSE; } nVCount = poSG2D->GetRepeatCount(); } else { return TRUE; } if( nVCount == 0 ) { CPLDebug( "S57", "VCount is zero." ); return FALSE; }/* -------------------------------------------------------------------- *//* Make sure out line is long enough to hold all the vertices *//* we will apply. *//* -------------------------------------------------------------------- */ int nVBase; if( iDirection < 0 ) nVBase = iStartVertex + nVCount; else nVBase = iStartVertex; if( poLine->getNumPoints() < iStartVertex + nVCount ) poLine->setNumPoints( iStartVertex + nVCount ); /* -------------------------------------------------------------------- *//* Are the SG2D and XCOO/YCOO definitions in the form we expect? *//* -------------------------------------------------------------------- */ if( poSG2D->GetFieldDefn()->GetSubfieldCount() != 2 ) bStandardFormat = FALSE; if( !EQUAL(poXCOO->GetFormat(),"b24") || !EQUAL(poYCOO->GetFormat(),"b24") ) bStandardFormat = FALSE;/* -------------------------------------------------------------------- *//* Collect the vertices: *//* *//* This approach assumes that the data is LSB organized int32 *//* binary data as per the specification. We avoid lots of *//* extra calls to low level DDF methods as they are quite *//* expensive. *//* -------------------------------------------------------------------- */ if( bStandardFormat ) { const char *pachData; int nBytesRemaining; pachData = poSG2D->GetSubfieldData(poYCOO,&nBytesRemaining,0); for( int i = 0; i < nVCount; i++ ) { double dfX, dfY; GInt32 nXCOO, nYCOO; memcpy( &nYCOO, pachData, 4 ); pachData += 4; memcpy( &nXCOO, pachData, 4 ); pachData += 4;#ifdef CPL_MSB CPL_SWAP32PTR( &nXCOO ); CPL_SWAP32PTR( &nYCOO );#endif dfX = nXCOO / (double) nCOMF; dfY = nYCOO / (double) nCOMF; poLine->setPoint( nVBase, dfX, dfY ); nVBase += iDirection; } }/* -------------------------------------------------------------------- *//* Collect the vertices: *//* *//* The generic case where we use low level but expensive DDF *//* methods to get the data. This should work even if some *//* things are changed about the SG2D fields such as making them *//* floating point or a different byte order. *//* -------------------------------------------------------------------- */ else { for( int i = 0; i < nVCount; i++ ) { double dfX, dfY; const char *pachData; int nBytesRemaining; pachData = poSG2D->GetSubfieldData(poXCOO,&nBytesRemaining,i); dfX = poXCOO->ExtractIntData(pachData,nBytesRemaining,NULL) / (double) nCOMF; pachData = poSG2D->GetSubfieldData(poYCOO,&nBytesRemaining,i); dfY = poXCOO->ExtractIntData(pachData,nBytesRemaining,NULL) / (double) nCOMF; poLine->setPoint( nVBase, dfX, dfY ); nVBase += iDirection; } } return TRUE;}/************************************************************************//* AssemblePointGeometry() *//************************************************************************/void S57Reader::AssemblePointGeometry( DDFRecord * poFRecord, OGRFeature * poFeature ){ DDFField *poFSPT; int nRCNM, nRCID;/* -------------------------------------------------------------------- *//* Feature the spatial record containing the point. *//* -------------------------------------------------------------------- */ poFSPT = poFRecord->FindField( "FSPT" ); if( poFSPT == NULL ) return; if( poFSPT->GetRepeatCount() != 1 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -