📄 dgnread.cpp
字号:
/****************************************************************************** * $Id: dgnread.cpp,v 1.46 2004/06/02 15:53:00 warmerda Exp $ * * Project: Microstation DGN Access Library * Purpose: DGN Access Library element reading code. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2000, Avenza Systems Inc, http://www.avenza.com/ * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dgnread.cpp,v $ * Revision 1.46 2004/06/02 15:53:00 warmerda * improve divide by zero error checking * * Revision 1.45 2004/04/06 04:24:51 warmerda * Always make any new color table encountered the default color * table when it is read. * * Revision 1.44 2004/01/23 16:15:22 warmerda * DGN_LEVEL_SYMBOLOGY has no disphdr, DGNParseCore() wont read negative attr * * Revision 1.43 2003/11/24 14:17:40 warmerda * Added a bunch more no-disphdr elements as per email from Marius. * * Revision 1.42 2003/11/18 21:11:40 warmerda * Added DGNElemTypeHasDispHdr() function. * * Revision 1.41 2003/11/07 13:59:45 warmerda * added DGNLoadTCB() * * Revision 1.40 2003/09/22 05:59:24 warmerda * Fixed setting of offset for element index. * Don't try to extract attribute data on TCB elements. * * Revision 1.39 2003/08/19 20:16:56 warmerda * Added support for reading Cone (23), 3D surface (18) and 3D solid (19) * elements. Added code to read transformation matrices for Cell headers * Marius Kintel * * Revision 1.38 2003/06/27 14:38:26 warmerda * avoid warnings * * Revision 1.37 2003/05/21 03:42:01 warmerda * Expanded tabs * * Revision 1.36 2003/05/12 18:48:57 warmerda * added preliminary 3D write support * * Revision 1.35 2002/11/13 21:26:32 warmerda * added more documentation * * Revision 1.34 2002/11/12 23:11:52 warmerda * fixed error with tags in DGNFreeElement() * * Revision 1.33 2002/11/12 19:45:27 warmerda * added support to parse view infos in TCB * * Revision 1.32 2002/11/11 20:38:13 warmerda * provide external extents call, add inverse to int function * * Revision 1.31 2002/10/29 19:44:08 warmerda * fixed complex group handling with spatial queries * * Revision 1.30 2002/10/29 19:25:18 warmerda * fixed serious bug in applying color table to DGNInfo structure * * Revision 1.29 2002/09/24 14:34:19 warmerda * fix collection of background color * * Revision 1.28 2002/05/30 19:24:38 warmerda * add partial support for tag type 5 * * Revision 1.27 2002/04/22 20:42:40 warmerda * fixed problem with tag set ids > 255 * * Revision 1.26 2002/04/08 21:25:59 warmerda * removed tagDef->id = iTag+1 assumption * * Revision 1.25 2002/03/14 21:40:03 warmerda * expose DGNLoadRawElement, add max_element_count in psDGN * * Revision 1.24 2002/03/12 17:11:31 warmerda * ensure tag elements are indexed * * Revision 1.23 2002/03/12 17:07:26 warmerda * added tagset and tag value element support * * Revision 1.22 2002/02/22 22:17:42 warmerda * Ensure that components of complex chain/shapes are spatially selected * based on the decision made for their owner (header). * * Revision 1.21 2002/02/06 22:39:08 warmerda * dont filter out non-spatial features with spatial filter * * Revision 1.20 2002/02/06 20:32:33 warmerda * handle improbably large elements * * Revision 1.19 2002/01/21 20:53:33 warmerda * a bunch of reorganization to support spatial filtering * * Revision 1.18 2002/01/15 06:38:51 warmerda * moved some functions to dgnhelp.cpp * * Revision 1.17 2001/12/19 15:29:56 warmerda * added preliminary cell header support * * Revision 1.16 2001/11/09 14:55:29 warmerda * fixed 3D support for arcs * * Revision 1.15 2001/09/27 14:28:44 warmerda * first hack at 3D support * * Revision 1.14 2001/08/28 21:27:07 warmerda * added prototype multi-byte character support * * Revision 1.13 2001/08/21 03:01:39 warmerda * added raw_data support * * Revision 1.12 2001/07/18 04:55:16 warmerda * added CPL_CSVID * * Revision 1.11 2001/06/25 15:07:51 warmerda * Added support for DGNElemComplexHeader * Don't include elements with the complex bit (such as shared cell definition * elements) in extents computation for fear they are in a different coord sys. * * Revision 1.10 2001/03/07 13:56:44 warmerda * updated copyright to be held by Avenza Systems * * Revision 1.9 2001/03/07 13:52:15 warmerda * Don't include deleted elements in the total extents. * Capture attribute data. * * Revision 1.7 2001/02/02 22:20:29 warmerda * compute text height/width properly * * Revision 1.6 2001/01/17 16:07:33 warmerda * ensure that TCB and ColorTable side effects occur on indexing pass too * * Revision 1.5 2001/01/16 18:12:52 warmerda * Added arc support, DGNLookupColor * * Revision 1.4 2001/01/10 16:13:45 warmerda * added docs and extents api * * Revision 1.3 2000/12/28 21:28:59 warmerda * added element index support * * Revision 1.2 2000/12/14 17:10:57 warmerda * implemented TCB, Ellipse, TEXT * * Revision 1.1 2000/11/28 19:03:47 warmerda * New * */#include "dgnlibp.h"CPL_CVSID("$Id: dgnread.cpp,v 1.46 2004/06/02 15:53:00 warmerda Exp $");static DGNElemCore *DGNParseTCB( DGNInfo * );static DGNElemCore *DGNParseColorTable( DGNInfo * );static DGNElemCore *DGNParseTagSet( DGNInfo * );/************************************************************************//* DGNGotoElement() *//************************************************************************//** * Seek to indicated element. * * Changes what element will be read on the next call to DGNReadElement(). * Note that this function requires and index, and one will be built if * not already available. * * @param hDGN the file to affect. * @param element_id the element to seek to. These values are sequentially * ordered starting at zero for the first element. * * @return returns TRUE on success or FALSE on failure. */int DGNGotoElement( DGNHandle hDGN, int element_id ){ DGNInfo *psDGN = (DGNInfo *) hDGN; DGNBuildIndex( psDGN ); if( element_id < 0 || element_id >= psDGN->element_count ) return FALSE; if( VSIFSeek( psDGN->fp, psDGN->element_index[element_id].offset, SEEK_SET ) != 0 ) return FALSE; psDGN->next_element_id = element_id; psDGN->in_complex_group = FALSE; return TRUE;}/************************************************************************//* DGNLoadRawElement() *//************************************************************************/int DGNLoadRawElement( DGNInfo *psDGN, int *pnType, int *pnLevel ){/* -------------------------------------------------------------------- *//* Read the first four bytes to get the level, type, and word *//* count. *//* -------------------------------------------------------------------- */ int nType, nWords, nLevel; if( VSIFRead( psDGN->abyElem, 1, 4, psDGN->fp ) != 4 ) return FALSE; /* Is this an 0xFFFF endof file marker? */ if( psDGN->abyElem[0] == 0xff && psDGN->abyElem[1] == 0xff ) return FALSE; nWords = psDGN->abyElem[2] + psDGN->abyElem[3]*256; nType = psDGN->abyElem[1] & 0x7f; nLevel = psDGN->abyElem[0] & 0x3f;/* -------------------------------------------------------------------- *//* Read the rest of the element data into the working buffer. *//* -------------------------------------------------------------------- */ CPLAssert( nWords * 2 + 4 <= (int) sizeof(psDGN->abyElem) ); if( (int) VSIFRead( psDGN->abyElem + 4, 2, nWords, psDGN->fp ) != nWords ) return FALSE; psDGN->nElemBytes = nWords * 2 + 4; psDGN->next_element_id++;/* -------------------------------------------------------------------- *//* Return requested info. *//* -------------------------------------------------------------------- */ if( pnType != NULL ) *pnType = nType; if( pnLevel != NULL ) *pnLevel = nLevel; return TRUE;}/************************************************************************//* DGNGetRawExtents() *//* *//* Returns FALSE if the element type does not have reconisable *//* element extents, other TRUE and the extents will be updated. *//* *//* It is assumed the raw element data has been loaded into the *//* working area by DGNLoadRawElement(). *//************************************************************************/static int DGNGetRawExtents( DGNInfo *psDGN, int nType, unsigned char *pabyRawData, GUInt32 *pnXMin, GUInt32 *pnYMin, GUInt32 *pnZMin, GUInt32 *pnXMax, GUInt32 *pnYMax, GUInt32 *pnZMax ){ if( pabyRawData == NULL ) pabyRawData = psDGN->abyElem + 0; switch( nType ) { case DGNT_LINE: case DGNT_LINE_STRING: case DGNT_SHAPE: case DGNT_CURVE: case DGNT_BSPLINE: case DGNT_ELLIPSE: case DGNT_ARC: case DGNT_TEXT: case DGNT_COMPLEX_CHAIN_HEADER: case DGNT_COMPLEX_SHAPE_HEADER: case DGNT_CONE: case DGNT_3DSURFACE_HEADER: case DGNT_3DSOLID_HEADER: *pnXMin = DGN_INT32( pabyRawData + 4 ); *pnYMin = DGN_INT32( pabyRawData + 8 ); if( pnZMin != NULL ) *pnZMin = DGN_INT32( pabyRawData + 12 ); *pnXMax = DGN_INT32( pabyRawData + 16 ); *pnYMax = DGN_INT32( pabyRawData + 20 ); if( pnZMax != NULL ) *pnZMax = DGN_INT32( pabyRawData + 24 ); return TRUE; default: return FALSE; }}/************************************************************************//* DGNGetElementExtents() *//************************************************************************//** * Fetch extents of an element. * * This function will return the extents of the passed element if possible. * The extents are extracted from the element header if it contains them, * and transformed into master georeferenced format. Some element types * do not have extents at all and will fail. * * This call will also fail if the extents raw data for the element is not * available. This will occur if it was not the most recently read element, * and if the raw_data field is not loaded. * * @param hDGN the handle of the file to read from. * * @param psElement the element to extract extents from. * * @param psMin structure loaded with X, Y and Z minimum values for the * extent. * * @param psMax structure loaded with X, Y and Z maximum values for the * extent. * * @return TRUE on success of FALSE if extracting extents fails. */int DGNGetElementExtents( DGNHandle hDGN, DGNElemCore *psElement, DGNPoint *psMin, DGNPoint *psMax ){ DGNInfo *psDGN = (DGNInfo *) hDGN; GUInt32 anMin[3], anMax[3]; int bResult;/* -------------------------------------------------------------------- *//* Get the extents if we have raw data in the element, or *//* loaded in the file buffer. *//* -------------------------------------------------------------------- */ if( psElement->raw_data != NULL ) bResult = DGNGetRawExtents( psDGN, psElement->type, psElement->raw_data, anMin + 0, anMin + 1, anMin + 2, anMax + 0, anMax + 1, anMax + 2 ); else if( psElement->element_id == psDGN->next_element_id - 1 ) bResult = DGNGetRawExtents( psDGN, psElement->type,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -