⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dgnread.cpp

📁 在Linux环境下读写DGN文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                  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 + -