📄 dgnwrite.cpp
字号:
abyEOF[1] = 0xff; VSIFWrite( abyEOF, 2, 1, fpNew ); DGNFreeElement( psSeed, psSrcTCB );/* -------------------------------------------------------------------- *//* Close and re-open using DGN API. *//* -------------------------------------------------------------------- */ VSIFClose( fpNew ); psDGN = (DGNInfo *) DGNOpen( pszNewFilename, TRUE );/* -------------------------------------------------------------------- *//* Now copy over elements according to options in effect. *//* -------------------------------------------------------------------- */ DGNElemCore *psSrcElement, *psDstElement; while( (psSrcElement = DGNReadElement( psSeed )) != NULL ) { if( (nCreationFlags & DGNCF_COPY_WHOLE_SEED_FILE) || (psSrcElement->stype == DGNST_COLORTABLE && nCreationFlags & DGNCF_COPY_SEED_FILE_COLOR_TABLE) || psSrcElement->element_id <= 2 ) { psDstElement = DGNCloneElement( psSeed, psDGN, psSrcElement ); DGNWriteElement( psDGN, psDstElement ); DGNFreeElement( psDGN, psDstElement ); } DGNFreeElement( psSeed, psSrcElement ); } DGNClose( psSeed ); return psDGN;}/************************************************************************//* DGNCloneElement() *//************************************************************************//** * Clone a retargetted element. * * Creates a copy of an element in a suitable form to write to a * different file than that it was read from. * * NOTE: At this time the clone operation will fail if the source * and destination file have a different origin or master/sub units. * * @param hDGNSrc the source file (from which psSrcElement was read). * @param hDGNDst the destination file (to which the returned element may be * written). * @param psSrcElement the element to be cloned (from hDGNSrc). * * @return NULL on failure, or an appropriately modified copy of * the source element suitable to write to hDGNDst. */DGNElemCore *DGNCloneElement( DGNHandle hDGNSrc, DGNHandle hDGNDst, DGNElemCore *psSrcElement ){ DGNElemCore *psClone;/* -------------------------------------------------------------------- *//* Per structure specific copying. The core is fixed up later. *//* -------------------------------------------------------------------- */ if( psSrcElement->stype == DGNST_CORE ) { psClone = (DGNElemCore *) CPLMalloc(sizeof(DGNElemCore)); memcpy( psClone, psSrcElement, sizeof(DGNElemCore) ); } else if( psSrcElement->stype == DGNST_MULTIPOINT ) { DGNElemMultiPoint *psMP, *psSrcMP; int nSize; psSrcMP = (DGNElemMultiPoint *) psSrcElement; nSize = sizeof(DGNElemMultiPoint) + sizeof(DGNPoint) * (psSrcMP->num_vertices-2); psMP = (DGNElemMultiPoint *) CPLMalloc( nSize ); memcpy( psMP, psSrcElement, nSize ); psClone = (DGNElemCore *) psMP; } else if( psSrcElement->stype == DGNST_ARC ) { DGNElemArc *psArc; psArc = (DGNElemArc *) CPLMalloc(sizeof(DGNElemArc)); memcpy( psArc, psSrcElement, sizeof(DGNElemArc) ); psClone = (DGNElemCore *) psArc; } else if( psSrcElement->stype == DGNST_TEXT ) { DGNElemText *psText, *psSrcText; int nSize; psSrcText = (DGNElemText *) psSrcElement; nSize = sizeof(DGNElemText) + strlen(psSrcText->string); psText = (DGNElemText *) CPLMalloc( nSize ); memcpy( psText, psSrcElement, nSize ); psClone = (DGNElemCore *) psText; } else if( psSrcElement->stype == DGNST_COMPLEX_HEADER ) { DGNElemComplexHeader *psCH; psCH = (DGNElemComplexHeader *) CPLMalloc(sizeof(DGNElemComplexHeader)); memcpy( psCH, psSrcElement, sizeof(DGNElemComplexHeader) ); psClone = (DGNElemCore *) psCH; } else if( psSrcElement->stype == DGNST_COLORTABLE ) { DGNElemColorTable *psCT; psCT = (DGNElemColorTable *) CPLMalloc(sizeof(DGNElemColorTable)); memcpy( psCT, psSrcElement, sizeof(DGNElemColorTable) ); psClone = (DGNElemCore *) psCT; } else if( psSrcElement->stype == DGNST_TCB ) { DGNElemTCB *psTCB; psTCB = (DGNElemTCB *) CPLMalloc(sizeof(DGNElemTCB)); memcpy( psTCB, psSrcElement, sizeof(DGNElemTCB) ); psClone = (DGNElemCore *) psTCB; } else if( psSrcElement->stype == DGNST_CELL_HEADER ) { DGNElemCellHeader *psCH; psCH = (DGNElemCellHeader *) CPLMalloc(sizeof(DGNElemCellHeader)); memcpy( psCH, psSrcElement, sizeof(DGNElemCellHeader) ); psClone = (DGNElemCore *) psCH; } else if( psSrcElement->stype == DGNST_CELL_LIBRARY ) { DGNElemCellLibrary *psCL; psCL = (DGNElemCellLibrary *) CPLMalloc(sizeof(DGNElemCellLibrary)); memcpy( psCL, psSrcElement, sizeof(DGNElemCellLibrary) ); psClone = (DGNElemCore *) psCL; } else if( psSrcElement->stype == DGNST_TAG_VALUE ) { DGNElemTagValue *psTV; psTV = (DGNElemTagValue *) CPLMalloc(sizeof(DGNElemTagValue)); memcpy( psTV, psSrcElement, sizeof(DGNElemTagValue) ); if( psTV->tagType == 1 ) psTV->tagValue.string = CPLStrdup( psTV->tagValue.string ); psClone = (DGNElemCore *) psTV; } else if( psSrcElement->stype == DGNST_TAG_SET ) { DGNElemTagSet *psTS; int iTag; DGNTagDef *pasTagList; psTS = (DGNElemTagSet *) CPLMalloc(sizeof(DGNElemTagSet)); memcpy( psTS, psSrcElement, sizeof(DGNElemTagSet) ); psTS->tagSetName = CPLStrdup( psTS->tagSetName ); pasTagList = (DGNTagDef *) CPLMalloc( sizeof(DGNTagDef) * psTS->tagCount ); memcpy( pasTagList, psTS->tagList, sizeof(DGNTagDef) * psTS->tagCount ); for( iTag = 0; iTag < psTS->tagCount; iTag++ ) { pasTagList[iTag].name = CPLStrdup( pasTagList[iTag].name ); pasTagList[iTag].prompt = CPLStrdup( pasTagList[iTag].prompt ); } psClone = (DGNElemCore *) psTS; }/* -------------------------------------------------------------------- *//* Copy core raw data, and attributes. *//* -------------------------------------------------------------------- */ if( psClone->raw_bytes != 0 ) { psClone->raw_data = (unsigned char *) CPLMalloc(psClone->raw_bytes); memcpy( psClone->raw_data, psSrcElement->raw_data, psClone->raw_bytes ); } if( psClone->attr_bytes != 0 ) { psClone->attr_data = (unsigned char *) CPLMalloc(psClone->attr_bytes); memcpy( psClone->attr_data, psSrcElement->attr_data, psClone->attr_bytes ); }/* -------------------------------------------------------------------- *//* Clear location and id information. *//* -------------------------------------------------------------------- */ psClone->offset = -1; psClone->element_id = -1; return psClone;}/************************************************************************//* DGNUpdateElemCore() *//************************************************************************//** * Change element core values. * * The indicated values in the element are updated in the structure, as well * as in the raw data. The updated element is not written to disk. That * must be done with DGNWriteElement(). The element must have raw_data * loaded. * * @param hDGN the file on which the element belongs. * @param psElement the element to modify. * @param nLevel the new level value. * @param nGraphicGroup the new graphic group value. * @param nColor the new color index. * @param nWeight the new element weight. * @param nStyle the new style value for the element. * * @return Returns TRUE on success or FALSE on failure. */int DGNUpdateElemCore( DGNHandle hDGN, DGNElemCore *psElement, int nLevel, int nGraphicGroup, int nColor, int nWeight, int nStyle ){ psElement->level = nLevel; psElement->graphic_group = nGraphicGroup; psElement->color = nColor; psElement->weight = nWeight; psElement->style = nStyle; return DGNUpdateElemCoreExtended( hDGN, psElement );}/************************************************************************//* DGNUpdateElemCoreExtended() *//************************************************************************//** * Update internal raw data representation. * * The raw_data representation of the passed element is updated to reflect * the various core fields. The DGNElemCore level, type, complex, deleted, * graphic_group, properties, color, weight and style values are all * applied to the raw_data representation. Spatial bounds, element type * specific information and attributes are not updated in the raw data. * * @param hDGN the file to which the element belongs. * @param psElement the element to be updated. * * @return TRUE on success, or FALSE on failure. */int DGNUpdateElemCoreExtended( DGNHandle hDGN, DGNElemCore *psElement ){ GByte *rd = psElement->raw_data; int nWords = (psElement->raw_bytes / 2) - 2; if( psElement->raw_data == NULL || psElement->raw_bytes < 36 ) { CPLAssert( FALSE ); return FALSE; }/* -------------------------------------------------------------------- *//* Setup first four bytes. *//* -------------------------------------------------------------------- */ rd[0] = psElement->level; if( psElement->complex ) rd[0] |= 0x80; rd[1] = psElement->type; if( psElement->deleted ) rd[1] |= 0x80; rd[2] = nWords % 256; rd[3] = nWords / 256;/* -------------------------------------------------------------------- *//* If the attribute offset hasn't been set, set it now under *//* the assumption it should point to the end of the element. *//* -------------------------------------------------------------------- */ if( psElement->raw_data[30] == 0 && psElement->raw_data[31] == 0 ) { int nAttIndex = (psElement->raw_bytes - 32) / 2; psElement->raw_data[30] = nAttIndex % 256; psElement->raw_data[31] = nAttIndex / 256; }/* -------------------------------------------------------------------- *//* Handle the graphic properties. *//* -------------------------------------------------------------------- */ if( psElement->raw_bytes > 36 && psElement->type != DGNT_CELL_LIBRARY ) { rd[28] = psElement->graphic_group % 256; rd[29] = psElement->graphic_group / 256; rd[32] = psElement->properties % 256; rd[33] = psElement->properties / 256; rd[34] = psElement->style | (psElement->weight << 3); rd[35] = psElement->color; } return TRUE;}/************************************************************************//* DGNInitializeCore() *//************************************************************************/static void DGNInitializeElemCore( DGNHandle hDGN, DGNElemCore *psElement ){ memset( psElement, 0, sizeof(DGNElemCore) ); psElement->offset = -1; psElement->element_id = -1;}/************************************************************************//* DGNWriteBounds() *//* *//* Write bounds to element raw data. *//************************************************************************/static void DGNWriteBounds( DGNInfo *psInfo, DGNElemCore *psElement, DGNPoint *psMin, DGNPoint *psMax ){ CPLAssert( psElement->raw_bytes >= 28 ); DGNInverseTransformPointToInt( psInfo, psMin, psElement->raw_data + 4 ); DGNInverseTransformPointToInt( psInfo, psMax, psElement->raw_data + 16 ); /* convert from twos completement to "binary offset" format. */ psElement->raw_data[5] ^= 0x80; psElement->raw_data[9] ^= 0x80; psElement->raw_data[13] ^= 0x80; psElement->raw_data[17] ^= 0x80; psElement->raw_data[21] ^= 0x80; psElement->raw_data[25] ^= 0x80;}/************************************************************************//* DGNCreateMultiPointElem() *//************************************************************************//** * Create new multi-point element. * * 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. * * NOTE: There are restrictions on the nPointCount for some elements. For * instance, DGNT_LINE can only have 2 points. Maximum element size * precludes very large numbers of points. * * @param hDGN the file on which the element will eventually be written. * @param nType the type of the element to be created. It must be one of * DGNT_LINE, DGNT_LINE_STRING, DGNT_SHAPE, DGNT_CURVE or DGNT_BSPLINE. * @param nPointCount the number of points in the pasVertices list. * @param pasVertices the list of points to be written. * * @return the new element (a DGNElemMultiPoint structure) or NULL on failure. */DGNElemCore *DGNCreateMultiPointElem( DGNHandle hDGN, int nType, int nPointCount, DGNPoint *pasVertices ){ DGNElemMultiPoint *psMP; DGNElemCore *psCore; DGNInfo *psDGN = (DGNInfo *) hDGN; int i; DGNPoint sMin, sMax;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -