📄 dgnwrite.cpp
字号:
/* -------------------------------------------------------------------- *//* Allocate element. *//* -------------------------------------------------------------------- */ psCT = (DGNElemColorTable *) CPLCalloc( sizeof(DGNElemColorTable), 1 ); psCore = &(psCT->core); DGNInitializeElemCore( hDGN, psCore ); psCore->stype = DGNST_COLORTABLE; psCore->type = DGNT_GROUP_DATA; psCore->level = DGN_GDL_COLOR_TABLE;/* -------------------------------------------------------------------- *//* Set colortable specific information in the structure. *//* -------------------------------------------------------------------- */ psCT->screen_flag = nScreenFlag; memcpy( psCT->color_info, abyColorInfo, 768 );/* -------------------------------------------------------------------- *//* Setup Raw data for the text specific portion. *//* -------------------------------------------------------------------- */ psCore->raw_bytes = 806; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); psCore->raw_data[36] = nScreenFlag % 256; psCore->raw_data[37] = nScreenFlag / 256; memcpy( psCore->raw_data + 38, abyColorInfo[255], 3 ); memcpy( psCore->raw_data + 41, abyColorInfo, 783 ); /* -------------------------------------------------------------------- *//* Set the core raw data. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psCore ); return psCore;}/************************************************************************//* DGNCreateComplexHeaderElem() *//************************************************************************/DGNElemCore *DGNCreateComplexHeaderElem( DGNHandle hDGN, int nType, int nTotLength, int nNumElems )/** * Create complex chain/shape header. * * The newly created element will still need to be written to file using * DGNWriteElement(). Also the level and other core values will be defaulted. * Use DGNUpdateElemCore() on the element before writing to set these values. * * The nTotLength is the sum of the size of all elements in the complex * group plus 5. The DGNCreateComplexHeaderFromGroup() can be used to build * a complex element from the members more conveniently. * * @param hDGN the file on which the element will be written. * @param nType either DGNT_COMPLEX_CHAIN_HEADER or DGNT_COMPLEX_SHAPE_HEADER * depending on whether the list is open or closed (last point equal to last). * @param nTotLength the value of the totlength field in the element. * @param nNumElems the number of elements in the complex group not including * the header element. * * @return the new element (DGNElemComplexHeader) or NULL on failure. */{ DGNElemComplexHeader *psCH; DGNElemCore *psCore; CPLAssert( nType == DGNT_COMPLEX_CHAIN_HEADER || nType == DGNT_COMPLEX_SHAPE_HEADER );/* -------------------------------------------------------------------- *//* Allocate element. *//* -------------------------------------------------------------------- */ psCH = (DGNElemComplexHeader *) CPLCalloc( sizeof(DGNElemComplexHeader), 1 ); psCore = &(psCH->core); DGNInitializeElemCore( hDGN, psCore ); psCore->stype = DGNST_COMPLEX_HEADER; psCore->type = nType;/* -------------------------------------------------------------------- *//* Set complex header specific information in the structure. *//* -------------------------------------------------------------------- */ psCH->totlength = nTotLength; psCH->numelems = nNumElems;/* -------------------------------------------------------------------- *//* Setup Raw data for the text specific portion. *//* -------------------------------------------------------------------- */ psCore->raw_bytes = 48; psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1); psCore->raw_data[36] = nTotLength % 256; psCore->raw_data[37] = nTotLength / 256; psCore->raw_data[38] = nNumElems % 256; psCore->raw_data[39] = nNumElems / 256;/* -------------------------------------------------------------------- *//* Set the core raw data. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psCore ); return psCore;}/************************************************************************//* DGNCreateComplexHeaderFromGroup() *//************************************************************************//** * Create complex chain/shape header. * * This function is similar to DGNCreateComplexHeaderElem(), but it takes * care of computing the total size of the set of elements being written, * and collecting the bounding extents. It also takes care of some other * convenience issues, like marking all the member elements as complex, and * setting the level based on the level of the member elements. * * @param hDGN the file on which the element will be written. * @param nType either DGNT_COMPLEX_CHAIN_HEADER or DGNT_COMPLEX_SHAPE_HEADER * depending on whether the list is open or closed (last point equal to last). * @param nNumElems the number of elements in the complex group not including * the header element. * @param papsElems array of pointers to nNumElems elements in the complex * group. Some updates may be made to these elements. * * @return the new element (DGNElemComplexHeader) or NULL on failure. */DGNElemCore *DGNCreateComplexHeaderFromGroup( DGNHandle hDGN, int nType, int nNumElems, DGNElemCore **papsElems ){ int nTotalLength = 5; int i, nLevel; DGNElemCore *psCH; DGNPoint sMin, sMax; if( nNumElems < 1 || papsElems == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Need at least one element to form a complex group." ); return NULL; }/* -------------------------------------------------------------------- *//* Collect the total size, and bounds. *//* -------------------------------------------------------------------- */ nLevel = papsElems[0]->level; for( i = 0; i < nNumElems; i++ ) { DGNPoint sThisMin, sThisMax; nTotalLength += papsElems[i]->raw_bytes / 2; papsElems[i]->complex = TRUE; papsElems[i]->raw_data[0] |= 0x80; if( papsElems[i]->level != nLevel ) { CPLError( CE_Warning, CPLE_AppDefined, "Not all level values matching in a complex set group!"); } DGNGetElementExtents( hDGN, papsElems[i], &sThisMin, &sThisMax ); if( i == 0 ) { sMin = sThisMin; sMax = sThisMax; } else { sMin.x = MIN(sMin.x,sThisMin.x); sMin.y = MIN(sMin.y,sThisMin.y); sMin.z = MIN(sMin.z,sThisMin.z); sMax.x = MAX(sMax.x,sThisMax.x); sMax.y = MAX(sMax.y,sThisMax.y); sMax.z = MAX(sMax.z,sThisMax.z); } }/* -------------------------------------------------------------------- *//* Create the corresponding complex header. *//* -------------------------------------------------------------------- */ psCH = DGNCreateComplexHeaderElem( hDGN, nType, nTotalLength, nNumElems ); DGNUpdateElemCore( hDGN, psCH, papsElems[0]->level, psCH->graphic_group, psCH->color, psCH->weight, psCH->style ); DGNWriteBounds( (DGNInfo *) hDGN, psCH, &sMin, &sMax ); return psCH;}/************************************************************************//* DGNAddMSLink() *//************************************************************************//** * Add a database link to element. * * The target element must already have raw_data loaded, and it will be * resized (see DGNResizeElement()) as needed for the new attribute data. * Note that the element is not written to disk immediate. Use * DGNWriteElement() for that. * * @param hDGN the file to which the element corresponds. * @param psElement the element being updated. * @param nLinkageType link type (DGNLT_*). Usually one of DGNLT_DMRS, * DGNLT_INFORMIX, DGNLT_ODBC, DGNLT_ORACLE, DGNLT_RIS, DGNLT_SYBASE, * or DGNLT_XBASE. * @param nEntityNum indicator of the table referenced on target database. * @param nMSLink indicator of the record referenced on target table. * * @return -1 on failure, or the link index. */ int DGNAddMSLink( DGNHandle hDGN, DGNElemCore *psElement, int nLinkageType, int nEntityNum, int nMSLink ){ unsigned char abyLinkage[32]; int nLinkageSize; if( nLinkageType == DGNLT_DMRS ) { nLinkageSize = 8; abyLinkage[0] = 0x00; abyLinkage[1] = 0x00; abyLinkage[2] = nEntityNum % 256; abyLinkage[3] = nEntityNum / 256;; abyLinkage[4] = nMSLink % 256; abyLinkage[5] = (nMSLink / 256) % 256; abyLinkage[6] = nMSLink / 65536; abyLinkage[7] = 0x01; } else { nLinkageSize = 16; abyLinkage[0] = 0x07; abyLinkage[1] = 0x10; abyLinkage[2] = nLinkageType % 256; abyLinkage[3] = nLinkageType / 256; abyLinkage[4] = 0x81; abyLinkage[5] = 0x0F; abyLinkage[6] = nEntityNum % 256; abyLinkage[7] = nEntityNum / 256;; abyLinkage[8] = nMSLink % 256; abyLinkage[9] = (nMSLink / 256) % 256; abyLinkage[10] = (nMSLink / 65536) % 256; abyLinkage[11] = nMSLink / 16777216; abyLinkage[12] = 0x00; abyLinkage[13] = 0x00; abyLinkage[14] = 0x00; abyLinkage[15] = 0x00; } return DGNAddRawAttrLink( hDGN, psElement, nLinkageSize, abyLinkage );}/************************************************************************//* DGNAddRawAttrLink() *//************************************************************************//** * Add a raw attribute linkage to element. * * Given a raw data buffer, append it to this element as an attribute linkage * without trying to interprete the linkage data. * * The target element must already have raw_data loaded, and it will be * resized (see DGNResizeElement()) as needed for the new attribute data. * Note that the element is not written to disk immediate. Use * DGNWriteElement() for that. * * This function will take care of updating the "totlength" field of * complex chain or shape headers to account for the extra attribute space * consumed in the header element. * * @param hDGN the file to which the element corresponds. * @param psElement the element being updated. * @param nLinkSize the size of the linkage in bytes. * @param pabyRawLinkData the raw linkage data (nLinkSize bytes worth). * * @return -1 on failure, or the link index. */ int DGNAddRawAttrLink( DGNHandle hDGN, DGNElemCore *psElement, int nLinkSize, unsigned char *pabyRawLinkData ){ int iLinkage; if( nLinkSize % 2 == 1 ) nLinkSize++; if( psElement->size + nLinkSize > 768 ) { CPLError( CE_Failure, CPLE_ElementTooBig, "Attempt to add %d byte linkage to element exceeds maximum" " element size.", nLinkSize ); return -1; } /* -------------------------------------------------------------------- *//* Ensure the attribute linkage bit is set. *//* -------------------------------------------------------------------- */ psElement->properties |= DGNPF_ATTRIBUTES;/* -------------------------------------------------------------------- *//* Append the attribute linkage to the linkage area. *//* -------------------------------------------------------------------- */ psElement->attr_bytes += nLinkSize; psElement->attr_data = (unsigned char *) CPLRealloc( psElement->attr_data, psElement->attr_bytes ); memcpy( psElement->attr_data + (psElement->attr_bytes-nLinkSize), pabyRawLinkData, nLinkSize ); /* -------------------------------------------------------------------- *//* Grow the raw data, if we have rawdata. *//* -------------------------------------------------------------------- */ psElement->raw_bytes = psElement->raw_bytes += nLinkSize; psElement->raw_data = (unsigned char *) CPLRealloc( psElement->raw_data, psElement->raw_bytes ); memcpy( psElement->raw_data + (psElement->raw_bytes-nLinkSize), pabyRawLinkData, nLinkSize ); /* -------------------------------------------------------------------- *//* If the element is a shape or chain complex header, then we *//* need to increase the total complex group size appropriately. *//* -------------------------------------------------------------------- */ if( psElement->stype == DGNST_COMPLEX_HEADER ) { DGNElemComplexHeader *psCT = (DGNElemComplexHeader *) psElement; psCT->totlength += (nLinkSize / 2); psElement->raw_data[36] = psCT->totlength % 256; psElement->raw_data[37] = psCT->totlength / 256; }/* -------------------------------------------------------------------- *//* Ensure everything is updated properly, including element *//* length and properties. *//* -------------------------------------------------------------------- */ DGNUpdateElemCoreExtended( hDGN, psElement );/* -------------------------------------------------------------------- *//* Figure out what the linkage index is. *//* -------------------------------------------------------------------- */ for( iLinkage = 0; ; iLinkage++ ) { if( DGNGetLinkage( hDGN, psElement, iLinkage, NULL, NULL, NULL, NULL ) == NULL ) return iLinkage - 1; } return -1;}/************************************************************************//* DGNAddShapeFileInfo() *//************************************************************************//** * Add a shape fill attribute linkage. * * The target element must already have raw_data loaded, and it will be * resized (see DGNResizeElement()) as needed for the new attribute data. * Note that the element is not written to disk immediate. Use * DGNWriteElement() for that. * * @param hDGN the file to which the element corresponds. * @param psElement the element being updated. * @param nColor fill color (color index from palette). * * @return -1 on failure, or the link index. */ int DGNAddShapeFillInfo( DGNHandle hDGN, DGNElemCore *psElement, int nColor ){ unsigned char abyFillInfo[16] = { 0x07, 0x10, 0x41, 0x00, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; abyFillInfo[8] = nColor; return DGNAddRawAttrLink( hDGN, psElement, 16, abyFillInfo );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -