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

📄 dgnread.cpp

📁 在Linux环境下读写DGN文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        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 );            CPLFree( psTagSet->tagList[iTag].prompt );            if( psTagSet->tagList[iTag].type == 1 )                CPLFree( psTagSet->tagList[iTag].defaultValue.string );        }        CPLFree( psTagSet->tagList );    }    else if( psElement->stype == DGNST_TAG_VALUE )    {        if( ((DGNElemTagValue *) psElement)->tagType == 1 )            CPLFree( ((DGNElemTagValue *) psElement)->tagValue.string );    }    CPLFree( psElement );}/************************************************************************//*                             DGNRewind()                              *//************************************************************************//** * Rewind element reading. * * Rewind the indicated DGN file, so the next element read with  * DGNReadElement() will be the first.  Does not require indexing like * the more general DGNReadElement() function. * * @param hDGN handle to file. */void DGNRewind( DGNHandle hDGN ){    DGNInfo	*psDGN = (DGNInfo *) hDGN;    VSIRewind( psDGN->fp );    psDGN->next_element_id = 0;    psDGN->in_complex_group = FALSE;}/************************************************************************//*                         DGNTransformPoint()                          *//************************************************************************/void DGNTransformPoint( DGNInfo *psDGN, DGNPoint *psPoint ){    psPoint->x = psPoint->x * psDGN->scale - psDGN->origin_x;    psPoint->y = psPoint->y * psDGN->scale - psDGN->origin_y;    psPoint->z = psPoint->z * psDGN->scale - psDGN->origin_z;}/************************************************************************//*                      DGNInverseTransformPoint()                      *//************************************************************************/void DGNInverseTransformPoint( DGNInfo *psDGN, DGNPoint *psPoint ){    psPoint->x = (psPoint->x + psDGN->origin_x) / psDGN->scale;    psPoint->y = (psPoint->y + psDGN->origin_y) / psDGN->scale;    psPoint->z = (psPoint->z + psDGN->origin_z) / psDGN->scale;    psPoint->x = MAX(-2147483647,MIN(2147483647,psPoint->x));    psPoint->y = MAX(-2147483647,MIN(2147483647,psPoint->y));    psPoint->z = MAX(-2147483647,MIN(2147483647,psPoint->z));}/************************************************************************//*                   DGNInverseTransformPointToInt()                    *//************************************************************************/void DGNInverseTransformPointToInt( DGNInfo *psDGN, DGNPoint *psPoint,                                    unsigned char *pabyTarget ){    double     adfCT[3];    int        i;    adfCT[0] = (psPoint->x + psDGN->origin_x) / psDGN->scale;    adfCT[1] = (psPoint->y + psDGN->origin_y) / psDGN->scale;    adfCT[2] = (psPoint->z + psDGN->origin_z) / psDGN->scale;    for( i = 0; i < psDGN->dimension; i++ )    {        GInt32 nCTI;        unsigned char *pabyCTI = (unsigned char *) &nCTI;        nCTI = (GInt32) MAX(-2147483647,MIN(2147483647,adfCT[i]));        #ifdef WORDS_BIGENDIAN         pabyTarget[i*4+0] = pabyCTI[1];        pabyTarget[i*4+1] = pabyCTI[0];        pabyTarget[i*4+2] = pabyCTI[3];        pabyTarget[i*4+3] = pabyCTI[2];#else        pabyTarget[i*4+3] = pabyCTI[1];        pabyTarget[i*4+2] = pabyCTI[0];        pabyTarget[i*4+1] = pabyCTI[3];        pabyTarget[i*4+0] = pabyCTI[2];#endif            }}/************************************************************************//*                         DGNGetElementIndex()                         *//************************************************************************//** * Fetch element index. * * This function will return an array with brief information about every * element in a DGN file.  It requires one pass through the entire file to * generate (this is not repeated on subsequent calls).  * * The returned array of DGNElementInfo structures contain the level, type,  * stype, and other flags for each element in the file.  This can facilitate * application level code representing the number of elements of various types * effeciently.  * * Note that while building the index requires one pass through the whole file, * it does not generally request much processing for each element.  * * @param hDGN the file to get an index for. * @param pnElementCount the integer to put the total element count into.  * * @return a pointer to an internal array of DGNElementInfo structures (there  * will be *pnElementCount entries in the array), or NULL on failure.  The * returned array should not be modified or freed, and will last only as long * as the DGN file remains open.  */const DGNElementInfo *DGNGetElementIndex( DGNHandle hDGN, int *pnElementCount ){    DGNInfo	*psDGN = (DGNInfo *) hDGN;    DGNBuildIndex( psDGN );    if( pnElementCount != NULL )        *pnElementCount = psDGN->element_count;        return psDGN->element_index;}/************************************************************************//*                           DGNGetExtents()                            *//************************************************************************//** * Fetch overall file extents. * * The extents are collected for each element while building an index, so * if an index has not already been built, it will be built when  * DGNGetExtents() is called.   *  * The Z min/max values are generally meaningless (0 and 0xffffffff in uor * space).  *  * @param hDGN the file to get extents for. * @param padfExtents pointer to an array of six doubles into which are loaded * the values xmin, ymin, zmin, xmax, ymax, and zmax. * * @return TRUE on success or FALSE on failure. */int DGNGetExtents( DGNHandle hDGN, double * padfExtents ){    DGNInfo	*psDGN = (DGNInfo *) hDGN;    DGNPoint	sMin, sMax;    DGNBuildIndex( psDGN );    if( !psDGN->got_bounds )        return FALSE;    sMin.x = psDGN->min_x - 2147483648.0;    sMin.y = psDGN->min_y - 2147483648.0;    sMin.z = psDGN->min_z - 2147483648.0;        DGNTransformPoint( psDGN, &sMin );    padfExtents[0] = sMin.x;    padfExtents[1] = sMin.y;    padfExtents[2] = sMin.z;        sMax.x = psDGN->max_x - 2147483648.0;    sMax.y = psDGN->max_y - 2147483648.0;    sMax.z = psDGN->max_z - 2147483648.0;    DGNTransformPoint( psDGN, &sMax );    padfExtents[3] = sMax.x;    padfExtents[4] = sMax.y;    padfExtents[5] = sMax.z;    return TRUE;}/************************************************************************//*                           DGNBuildIndex()                            *//************************************************************************/void DGNBuildIndex( DGNInfo *psDGN ){    int	nMaxElements, nType, nLevel;    long nLastOffset;    GUInt32 anRegion[6];    if( psDGN->index_built )         return;    psDGN->index_built = TRUE;        DGNRewind( psDGN );    nMaxElements = 0;    nLastOffset = VSIFTell( psDGN->fp );    while( DGNLoadRawElement( psDGN, &nType, &nLevel ) )    {        DGNElementInfo	*psEI;        if( psDGN->element_count == nMaxElements )        {            nMaxElements = (int) (nMaxElements * 1.5) + 500;                        psDGN->element_index = (DGNElementInfo *)                 CPLRealloc( psDGN->element_index,                             nMaxElements * sizeof(DGNElementInfo) );        }        psEI = psDGN->element_index + psDGN->element_count;        psEI->level = nLevel;        psEI->type = nType;        psEI->flags = 0;        psEI->offset = nLastOffset;        if( psDGN->abyElem[0] & 0x80 )            psEI->flags |= DGNEIF_COMPLEX;        if( psDGN->abyElem[1] & 0x80 )            psEI->flags |= DGNEIF_DELETED;        if( nType == DGNT_LINE || nType == DGNT_LINE_STRING            || nType == DGNT_SHAPE || nType == DGNT_CURVE            || nType == DGNT_BSPLINE )            psEI->stype = DGNST_MULTIPOINT;        else if( nType == DGNT_GROUP_DATA && nLevel == DGN_GDL_COLOR_TABLE )        {            DGNElemCore	*psCT = DGNParseColorTable( psDGN );            DGNFreeElement( (DGNHandle) psDGN, psCT );            psEI->stype = DGNST_COLORTABLE;        }        else if( nType == DGNT_ELLIPSE || nType == DGNT_ARC )            psEI->stype = DGNST_ARC;                else if( nType == DGNT_COMPLEX_SHAPE_HEADER                  || nType == DGNT_COMPLEX_CHAIN_HEADER )            psEI->stype = DGNST_COMPLEX_HEADER;                else if( nType == DGNT_TEXT )            psEI->stype = DGNST_TEXT;        else if( nType == DGNT_TAG_VALUE )            psEI->stype = DGNST_TAG_VALUE;        else if( nType == DGNT_APPLICATION_ELEM )        {            if( nLevel == 24 )                psEI->stype = DGNST_TAG_SET;            else                psEI->stype = DGNST_CORE;        }        else if( nType == DGNT_TCB )        {            DGNElemCore	*psTCB = DGNParseTCB( psDGN );            DGNFreeElement( (DGNHandle) psDGN, psTCB );            psEI->stype = DGNST_TCB;        }        else            psEI->stype = DGNST_CORE;        if( !(psEI->flags & DGNEIF_DELETED)            && !(psEI->flags & DGNEIF_COMPLEX)             && DGNGetRawExtents( psDGN, nType, NULL,                                 anRegion+0, anRegion+1, anRegion+2,                                 anRegion+3, anRegion+4, anRegion+5 ) )        {#ifdef notdef            printf( "panRegion[%d]=%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n",                     psDGN->element_count,                    anRegion[0] - 2147483648.0,                    anRegion[1] - 2147483648.0,                    anRegion[2] - 2147483648.0,                    anRegion[3] - 2147483648.0,                    anRegion[4] - 2147483648.0,                    anRegion[5] - 2147483648.0 );#endif                        if( psDGN->got_bounds )            {                psDGN->min_x = MIN(psDGN->min_x, anRegion[0]);                psDGN->min_y = MIN(psDGN->min_y, anRegion[1]);                psDGN->min_z = MIN(psDGN->min_z, anRegion[2]);                psDGN->max_x = MAX(psDGN->max_x, anRegion[3]);                psDGN->max_y = MAX(psDGN->max_y, anRegion[4]);                psDGN->max_z = MAX(psDGN->max_z, anRegion[5]);            }            else            {                memcpy( &(psDGN->min_x), anRegion, sizeof(GInt32) * 6 );                psDGN->got_bounds = TRUE;            }        }        psDGN->element_count++;        nLastOffset = VSIFTell( psDGN->fp );    }    DGNRewind( psDGN );    psDGN->max_element_count = nMaxElements;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -