📄 dgnread.cpp
字号:
* * @param nElemType element type (0-63) to test. * * @return TRUE if elements of passed in type have a display header after the * core element header, or FALSE otherwise. */int DGNElemTypeHasDispHdr( int nElemType ){ switch( nElemType ) { case 0: case DGNT_TCB: case DGNT_CELL_LIBRARY: case DGNT_LEVEL_SYMBOLOGY: case 32: case 44: case 48: case 49: case 50: case 51: case 57: case 63: return FALSE; default: return TRUE; }}/************************************************************************//* DGNParseCore() *//************************************************************************/int DGNParseCore( DGNInfo *psDGN, DGNElemCore *psElement ){ GByte *psData = psDGN->abyElem+0; psElement->level = psData[0] & 0x3f; psElement->complex = psData[0] & 0x80; psElement->deleted = psData[1] & 0x80; psElement->type = psData[1] & 0x7f; if( psDGN->nElemBytes >= 36 && DGNElemTypeHasDispHdr( psElement->type ) ) { psElement->graphic_group = psData[28] + psData[29] * 256; psElement->properties = psData[32] + psData[33] * 256; psElement->style = psData[34] & 0x7; psElement->weight = (psData[34] & 0xf8) >> 3; psElement->color = psData[35]; } else { psElement->graphic_group = 0; psElement->properties = 0; psElement->style = 0; psElement->weight = 0; psElement->color = 0; } if( psElement->properties & DGNPF_ATTRIBUTES ) { int nAttIndex; nAttIndex = psData[30] + psData[31] * 256; psElement->attr_bytes = psDGN->nElemBytes - nAttIndex*2 - 32; if( psElement->attr_bytes > 0 ) { psElement->attr_data = (unsigned char *) CPLMalloc(psElement->attr_bytes); memcpy( psElement->attr_data, psData + nAttIndex * 2 + 32, psElement->attr_bytes ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Computed %d bytes for attribute info on element,\n" "perhaps this element type doesn't really have a disphdr?", psElement->attr_bytes ); psElement->attr_bytes = 0; } } return TRUE;}/************************************************************************//* DGNParseColorTable() *//************************************************************************/static DGNElemCore *DGNParseColorTable( DGNInfo * psDGN ){ DGNElemCore *psElement; DGNElemColorTable *psColorTable; psColorTable = (DGNElemColorTable *) CPLCalloc(sizeof(DGNElemColorTable),1); psElement = (DGNElemCore *) psColorTable; psElement->stype = DGNST_COLORTABLE; DGNParseCore( psDGN, psElement ); psColorTable->screen_flag = psDGN->abyElem[36] + psDGN->abyElem[37] * 256; memcpy( psColorTable->color_info[255], psDGN->abyElem+38, 3 ); memcpy( psColorTable->color_info, psDGN->abyElem+41, 765 ); // We used to only install a color table as the default color // table if it was the first in the file. But apparently we should // really be using the last one. This doesn't necessarily accomplish // that either if the elements are being read out of order but it will // usually do better at least. memcpy( psDGN->color_table, psColorTable->color_info, 768 ); psDGN->got_color_table = 1; return psElement;}/************************************************************************//* DGNParseTagSet() *//************************************************************************/static DGNElemCore *DGNParseTagSet( DGNInfo * psDGN ){ DGNElemCore *psElement; DGNElemTagSet *psTagSet; int nDataOffset, iTag; psTagSet = (DGNElemTagSet *) CPLCalloc(sizeof(DGNElemTagSet),1); psElement = (DGNElemCore *) psTagSet; psElement->stype = DGNST_TAG_SET; DGNParseCore( psDGN, psElement );/* -------------------------------------------------------------------- *//* Parse the overall information. *//* -------------------------------------------------------------------- */ psTagSet->tagCount = psDGN->abyElem[44] + psDGN->abyElem[45] * 256; psTagSet->flags = psDGN->abyElem[46] + psDGN->abyElem[47] * 256; psTagSet->tagSetName = CPLStrdup( (const char *) (psDGN->abyElem + 48) );/* -------------------------------------------------------------------- *//* Get the tag set number out of the attributes, if available. *//* -------------------------------------------------------------------- */ psTagSet->tagSet = -1; if( psElement->attr_bytes >= 8 && psElement->attr_data[0] == 0x03 && psElement->attr_data[1] == 0x10 && psElement->attr_data[2] == 0x2f && psElement->attr_data[3] == 0x7d ) psTagSet->tagSet = psElement->attr_data[4] + psElement->attr_data[5] * 256;/* -------------------------------------------------------------------- *//* Parse each of the tag definitions. *//* -------------------------------------------------------------------- */ psTagSet->tagList = (DGNTagDef *) CPLMalloc(sizeof(DGNTagDef) * psTagSet->tagCount); nDataOffset = 48 + strlen(psTagSet->tagSetName) + 1 + 1; for( iTag = 0; iTag < psTagSet->tagCount; iTag++ ) { DGNTagDef *tagDef = psTagSet->tagList + iTag; CPLAssert( nDataOffset < psDGN->nElemBytes ); /* collect tag name. */ tagDef->name = CPLStrdup( (char *) psDGN->abyElem + nDataOffset ); nDataOffset += strlen(tagDef->name)+1; /* Get tag id */ tagDef->id = psDGN->abyElem[nDataOffset] + psDGN->abyElem[nDataOffset+1] * 256; nDataOffset += 2; /* Get User Prompt */ tagDef->prompt = CPLStrdup( (char *) psDGN->abyElem + nDataOffset ); nDataOffset += strlen(tagDef->prompt)+1; /* Get type */ tagDef->type = psDGN->abyElem[nDataOffset] + psDGN->abyElem[nDataOffset+1] * 256; nDataOffset += 2; /* skip five zeros */ nDataOffset += 5; /* Get the default */ if( tagDef->type == 1 ) { tagDef->defaultValue.string = CPLStrdup( (char *) psDGN->abyElem + nDataOffset ); nDataOffset += strlen(tagDef->defaultValue.string)+1; } else if( tagDef->type == 3 || tagDef->type == 5 ) { memcpy( &(tagDef->defaultValue.integer), psDGN->abyElem + nDataOffset, 4 ); tagDef->defaultValue.integer = CPL_LSBWORD32( tagDef->defaultValue.integer ); nDataOffset += 4; } else if( tagDef->type == 4 ) { memcpy( &(tagDef->defaultValue.real), psDGN->abyElem + nDataOffset, 8 ); DGN2IEEEDouble( &(tagDef->defaultValue.real) ); nDataOffset += 8; } else nDataOffset += 4; } return psElement;}/************************************************************************//* DGNParseTCB() *//************************************************************************/static DGNElemCore *DGNParseTCB( DGNInfo * psDGN ){ DGNElemTCB *psTCB; DGNElemCore *psElement; int iView; psTCB = (DGNElemTCB *) CPLCalloc(sizeof(DGNElemTCB),1); psElement = (DGNElemCore *) psTCB; psElement->stype = DGNST_TCB; DGNParseCore( psDGN, psElement ); if( psDGN->abyElem[1214] & 0x40 ) psTCB->dimension = 3; else psTCB->dimension = 2; psTCB->subunits_per_master = DGN_INT32( psDGN->abyElem + 1112 ); psTCB->master_units[0] = (char) psDGN->abyElem[1120]; psTCB->master_units[1] = (char) psDGN->abyElem[1121]; psTCB->master_units[2] = '\0'; psTCB->uor_per_subunit = DGN_INT32( psDGN->abyElem + 1116 ); psTCB->sub_units[0] = (char) psDGN->abyElem[1122]; psTCB->sub_units[1] = (char) psDGN->abyElem[1123]; psTCB->sub_units[2] = '\0'; /* Get global origin */ memcpy( &(psTCB->origin_x), psDGN->abyElem+1240, 8 ); memcpy( &(psTCB->origin_y), psDGN->abyElem+1248, 8 ); memcpy( &(psTCB->origin_z), psDGN->abyElem+1256, 8 ); /* Transform to IEEE */ DGN2IEEEDouble( &(psTCB->origin_x) ); DGN2IEEEDouble( &(psTCB->origin_y) ); DGN2IEEEDouble( &(psTCB->origin_z) ); /* Convert from UORs to master units. */ if( psTCB->uor_per_subunit != 0 && psTCB->subunits_per_master != 0 ) { psTCB->origin_x = psTCB->origin_x / (psTCB->uor_per_subunit * psTCB->subunits_per_master); psTCB->origin_y = psTCB->origin_y / (psTCB->uor_per_subunit * psTCB->subunits_per_master); psTCB->origin_z = psTCB->origin_z / (psTCB->uor_per_subunit * psTCB->subunits_per_master); } if( !psDGN->got_tcb ) { psDGN->got_tcb = TRUE; psDGN->dimension = psTCB->dimension; psDGN->origin_x = psTCB->origin_x; psDGN->origin_y = psTCB->origin_y; psDGN->origin_z = psTCB->origin_z; if( psTCB->uor_per_subunit != 0 && psTCB->subunits_per_master != 0 ) psDGN->scale = 1.0 / (psTCB->uor_per_subunit * psTCB->subunits_per_master); } /* Collect views */ for( iView = 0; iView < 8; iView++ ) { unsigned char *pabyRawView = psDGN->abyElem + 46 + iView*118; DGNViewInfo *psView = psTCB->views + iView; int i; psView->flags = pabyRawView[0] + pabyRawView[1] * 256; memcpy( psView->levels, pabyRawView + 2, 8 ); psView->origin.x = DGN_INT32( pabyRawView + 10 ); psView->origin.y = DGN_INT32( pabyRawView + 14 ); psView->origin.z = DGN_INT32( pabyRawView + 18 ); DGNTransformPoint( psDGN, &(psView->origin) ); psView->delta.x = DGN_INT32( pabyRawView + 22 ); psView->delta.y = DGN_INT32( pabyRawView + 26 ); psView->delta.z = DGN_INT32( pabyRawView + 30 ); psView->delta.x *= psDGN->scale; psView->delta.y *= psDGN->scale; psView->delta.z *= psDGN->scale; memcpy( psView->transmatrx, pabyRawView + 34, sizeof(double) * 9 ); for( i = 0; i < 9; i++ ) DGN2IEEEDouble( psView->transmatrx + i ); memcpy( &(psView->conversion), pabyRawView + 106, sizeof(double) ); DGN2IEEEDouble( &(psView->conversion) ); psView->activez = DGN_INT32( pabyRawView + 114 ); } return psElement;}/************************************************************************//* DGNFreeElement() *//************************************************************************//** * Free an element structure. * * This function will deallocate all resources associated with any element * structure returned by DGNReadElement(). * * @param hDGN handle to file from which the element was read. * @param psElement the element structure returned by DGNReadElement(). */void DGNFreeElement( DGNHandle hDGN, DGNElemCore *psElement ){ if( psElement->attr_data != NULL ) VSIFree( psElement->attr_data ); if( psElement->raw_data != NULL ) VSIFree( psElement->raw_data ); if( psElement->stype == DGNST_TAG_SET ) { int iTag; DGNElemTagSet *psTagSet = (DGNElemTagSet *) psElement; CPLFree( psTagSet->tagSetName ); for( iTag = 0; iTag < psTagSet->tagCount; iTag++ ) { CPLFree( psTagSet->tagList[iTag].name );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -