S57-文件结构分析(2)

2019-02-26 10:36

定义的子字段存入papoSubfields中,而papoSubfields定义为:

DDFSubfieldDefn **papoSubfields;

注意:每一个字段对应一个对象,存入DDFModule类中的

DDFFieldDefn **papoFieldDefns;数组内。

而每一个子字段DDFSubfieldDefn **papoSubfields又存入字段类DDFFieldDefn中。

ApplyFormats功能为将字段区内的格式域应用于各子字段中。

int DDFFieldDefn::ApplyFormats() {

char *pszFormatList; char **papszFormatItems;

if( strlen(_formatControls) < 2 || _formatControls[0] != '(' || _formatControls[strlen(_formatControls)-1] != ')' ) {

CPLError( CE_Failure, CPLE_AppDefined, \controls for `%s'

field missing brackets:%s\\n\, pszTag, _formatControls );

return FALSE; }

pszFormatList = ExpandFormat( _formatControls ); //展开格式控制, 如3A, 展开后为: A,A,A papszFormatItems =

CSLTokenizeStringComplex(pszFormatList, \, FALSE, FALSE ); 将展开后的格式控制字符串, 变成单个格式控制组成的指针.如 “(A,A,A,B10,F4)”

则指针分别指向: A,A,A,B10,F4各单项 CPLFree( pszFormatList ); int iFormatItem;

for( iFormatItem = 0; papszFormatItems[iFormatItem] != NULL; iFormatItem++ ) {

const char *pszPastPrefix;

pszPastPrefix = papszFormatItems[iFormatItem];

while( *pszPastPrefix >= '0' && *pszPastPrefix <= '9' ) pszPastPrefix++;

if( iFormatItem >= nSubfieldCount ) {

CPLError( CE_Warning, CPLE_AppDefined, \格式项与子字段项不等 `%s'.\\n\, pszTag ); break; }

if( !papoSubfields[iFormatItem]->SetFormat(pszPastPrefix) ) return FALSE; }

CSLDestroy( papszFormatItems );

if( iFormatItem < nSubfieldCount ) {

CPLError( CE_Failure, CPLE_AppDefined,

\, pszTag ); return FALSE; }

判断该字段是否为定长, nFixedWidth = 0;

for( int i = 0; i < nSubfieldCount; i++ ) {

if( papoSubfields[i]->GetWidth() == 0 ) {

nFixedWidth = 0;

只要有一个子字段不定长时, 则该字段不定长,即nFixedWidth = 0; break; } else

nFixedWidth += papoSubfields[i]->GetWidth(); }

return TRUE; }

二、DR结构 1. 文件头区

24个字节, 内容如下表

记录长度是指DR的总长度.

3. 记录区 与DDR相同

3.字段区 与DDR相同

DR程序分析:

在DR区内每次读入一条记录,存入DDFModule类内的poRecord。而poRecord类型

为:

DDFRecord *poRecord;

注意:每一个DR读入后,即开始处理,并未保存 poRecord;

在每次DR的读入过程中,首先判断上一次读入的DR文件头是否要重要使用,若否,则先读入该DR的文件头。

if( !nReuseHeader ) {

return( ReadHeader() );

}

其中,nReuseHeader在上一个DR的文件头中定义。

if( _leaderIden == 'R' ) nReuseHeader = TRUE;

DR中的数据存入DDFRecord 类的pachData中。本DR的字段个数存入DDFRecord

类中的nFieldCount。

DR中的字段存入 paoFields = new DDFField[nFieldCount]中;

初始化paoFields后得到各字段的数据、长度,并在DDFModule类中定义的

DDFFieldDefn **papoFieldDefns; 找到对应项,取到相应的格式。

然后,调用CParseS57_VC6Doc中的函数:ViewRecordField来解析本DR中的全部字段。得到物标的特征属性数据和空间属性数据。

DDFFieldDefn *poFieldDefn = poModule->FindFieldDefn(szTag);

读DR时, 调用oModule.ReadRecord(). 每个DR对应一个oModule.ReadRecord(). 在oModule.ReadRecord()中,先读出文件头区, 然后读出记录区, 每条记录对应一个字段. 然后调用ViewRecordField来解析该字段对应的数据.

while( (poRecord = oModule.ReadRecord()) != NULL ) {

// debuginfo(\start@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\n\

for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ ) {

DDFField *poField = poRecord->GetField( iField );

ViewRecordField( poField );

nFieldCount++; }

nRecordCount++; }

字段数据解析函数

void CParseS57Doc::ViewRecordField(DDFField * poField) {

int nBytesRemaining; const char *pachFieldData;

DDFFieldDefn *poFieldDefn = poField->GetFieldDefn(); char str[300];

if ((strncmp(poFieldDefn->GetName(), \, 4) == 0)||(strncmp(poFieldDefn->GetName(), \, 4)==0)) { //为空间数据就打印,并赋m_datatype值

m_datatype=NEED_TYPE; }

else if (strncmp(poFieldDefn->GetName(), \, 4) == 0) {

m_datatype=OBJT_TYPE|SUB3_TYPE; }

else if(strncmp(poFieldDefn->GetName(), \, 4) == 0) {

m_datatype=OBJT_TYPE|SUB4_TYPE; }

pachFieldData = poField->GetData();

nBytesRemaining = poField->GetDataSize(); int iRepeat;

for( iRepeat = 0; iRepeat < poField->GetRepeatCount(); iRepeat++ ) {

int iSF;

for( iSF = 0; iSF < poFieldDefn->GetSubfieldCount(); iSF++ ) {

DDFSubfieldDefn *poSFDefn = oFieldDefn->GetSubfield( iSF ); int nBytesConsumed; nBytesConsumed =

ViewSubfield( poSFDefn,pachFieldData,nBytesRemaining ); nBytesRemaining -= nBytesConsumed; pachFieldData += nBytesConsumed; } } }

如果字段是以*开头, 且是定长, 则可能有该字段重复数据 . poField->GetRepeatCount()

重复个数为=数据总长度/字段的长度(该字段必须是定长)

如果有子字段, 则调用ViewSubfield()函数来解析子字段数据.

读取字段数据,和子字段数据时,按特殊标识符(FT=30, UT=31)和定长来读取相应的数据.

每一个DR描述一种物标,包括:DSID、DSPM、FRID、VRID。

其中:DSID描述该文件的总体信息;DSPM描述该文件中的相关参数;FRID有多个,每个描述一种物标;VRID也有多个,每个可描述:离散点(SG2D、SG3D),或连接点,或一条边(边可能只有起点、终点,由VRPT确定(该DR形式为:0001、VRID、VRPT),边可能由起点、终点、中间点组成(该DR形式为:0001、VRID、VRPT、*SG2D),*表示重复多个)。


S57-文件结构分析(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:武鸣县2013年第十三期国有建设用地使用权

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: