📄 dgnread.cpp
字号:
CPLStrdup( (char *) psDGN->abyElem + 154 ); } else if( psTag->tagType == 3 ) { memcpy( &(psTag->tagValue.integer), psDGN->abyElem + 154, 4 ); psTag->tagValue.integer = CPL_LSBWORD32( psTag->tagValue.integer ); } else if( psTag->tagType == 4 ) { memcpy( &(psTag->tagValue.real), psDGN->abyElem + 154, 8 ); DGN2IEEEDouble( &(psTag->tagValue.real) ); } } break; case DGNT_APPLICATION_ELEM: if( nLevel == 24 ) { psElement = DGNParseTagSet( psDGN ); } else { psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1); psElement->stype = DGNST_CORE; DGNParseCore( psDGN, psElement ); } break; default: { psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1); psElement->stype = DGNST_CORE; DGNParseCore( psDGN, psElement ); } break; }/* -------------------------------------------------------------------- *//* If the element structure type is "core" or if we are running *//* in "capture all" mode, record the complete binary image of *//* the element. *//* -------------------------------------------------------------------- */ if( psElement->stype == DGNST_CORE || (psDGN->options & DGNO_CAPTURE_RAW_DATA) ) { psElement->raw_bytes = psDGN->nElemBytes; psElement->raw_data = (unsigned char *)CPLMalloc(psElement->raw_bytes); memcpy( psElement->raw_data, psDGN->abyElem, psElement->raw_bytes ); }/* -------------------------------------------------------------------- *//* Collect some additional generic information. *//* -------------------------------------------------------------------- */ psElement->element_id = psDGN->next_element_id - 1; psElement->offset = VSIFTell( psDGN->fp ) - psDGN->nElemBytes; psElement->size = psDGN->nElemBytes; return psElement;}/************************************************************************//* DGNReadElement() *//************************************************************************//** * Read a DGN element. * * This function will return the next element in the file, starting with the * first. It is affected by DGNGotoElement() calls. * * The element is read into a structure which includes the DGNElemCore * structure. It is expected that applications will inspect the stype * field of the returned DGNElemCore and use it to cast the pointer to the * appropriate element structure type such as DGNElemMultiPoint. * * @param hDGN the handle of the file to read from. * * @return pointer to element structure, or NULL on EOF or processing error. * The structure should be freed with DGNFreeElement() when no longer needed. */DGNElemCore *DGNReadElement( DGNHandle hDGN ){ DGNInfo *psDGN = (DGNInfo *) hDGN; DGNElemCore *psElement = NULL; int nType, nLevel; int bInsideFilter;/* -------------------------------------------------------------------- *//* Load the element data into the current buffer. If a spatial *//* filter is in effect, loop until we get something within our *//* spatial constraints. *//* -------------------------------------------------------------------- */ do { bInsideFilter = TRUE; if( !DGNLoadRawElement( psDGN, &nType, &nLevel ) ) return NULL; if( psDGN->has_spatial_filter ) { GUInt32 nXMin, nXMax, nYMin, nYMax; if( !psDGN->sf_converted_to_uor ) DGNSpatialFilterToUOR( psDGN ); if( !DGNGetRawExtents( psDGN, nType, NULL, &nXMin, &nYMin, NULL, &nXMax, &nYMax, NULL ) ) { /* If we don't have spatial characterists for the element we will pass it through. */ bInsideFilter = TRUE; } else if( nXMin > psDGN->sf_max_x || nYMin > psDGN->sf_max_y || nXMax < psDGN->sf_min_x || nYMax < psDGN->sf_min_y ) bInsideFilter = FALSE; /* ** We want to select complex elements based on the extents of ** the header, not the individual elements. */ if( nType == DGNT_COMPLEX_CHAIN_HEADER || nType == DGNT_COMPLEX_SHAPE_HEADER ) { psDGN->in_complex_group = TRUE; psDGN->select_complex_group = bInsideFilter; } else if( psDGN->abyElem[0] & 0x80 /* complex flag set */ ) { if( psDGN->in_complex_group ) bInsideFilter = psDGN->select_complex_group; } else psDGN->in_complex_group = FALSE; } } while( !bInsideFilter );/* -------------------------------------------------------------------- *//* Convert into an element structure. *//* -------------------------------------------------------------------- */ psElement = DGNProcessElement( psDGN, nType, nLevel ); return psElement;}/************************************************************************//* 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 && psElement->type != DGNT_CELL_LIBRARY ) { 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]; } if( psElement->properties & DGNPF_ATTRIBUTES ) { int nAttIndex; nAttIndex = psData[30] + psData[31] * 256; psElement->attr_bytes = psDGN->nElemBytes - nAttIndex*2 - 32; psElement->attr_data = (unsigned char *) CPLMalloc(psElement->attr_bytes); memcpy( psElement->attr_data, psData + nAttIndex * 2 + 32, psElement->attr_bytes ); } 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 ); if( !psDGN->got_color_table ) { 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++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -