📄 ogrpolygon.cpp
字号:
/************************************************************************//* addRing() *//************************************************************************//** * Add a ring to a polygon. * * If the polygon has no external ring (it is empty) this will be used as * the external ring, otherwise it is used as an internal ring. The passed * OGRLinearRing remains the responsibility of the caller (an internal copy * is made). * * This method has no SFCOM analog. * * @param poNewRing ring to be added to the polygon. */void OGRPolygon::addRing( OGRLinearRing * poNewRing ){ papoRings = (OGRLinearRing **) OGRRealloc( papoRings, sizeof(void*) * (nRingCount+1)); papoRings[nRingCount] = new OGRLinearRing( poNewRing ); nRingCount++; if( poNewRing->getCoordinateDimension() == 3 ) nCoordDimension = 3;}/************************************************************************//* addRingDirectly() *//************************************************************************//** * Add a ring to a polygon. * * If the polygon has no external ring (it is empty) this will be used as * the external ring, otherwise it is used as an internal ring. Ownership * of the passed ring is assumed by the OGRPolygon, but otherwise this * method operates the same as OGRPolygon::AddRing(). * * This method has no SFCOM analog. * * @param poNewRing ring to be added to the polygon. */void OGRPolygon::addRingDirectly( OGRLinearRing * poNewRing ){ papoRings = (OGRLinearRing **) OGRRealloc( papoRings, sizeof(void*) * (nRingCount+1)); papoRings[nRingCount] = poNewRing; nRingCount++; if( poNewRing->getCoordinateDimension() == 3 ) nCoordDimension = 3;}/************************************************************************//* WkbSize() *//* *//* Return the size of this object in well known binary *//* representation including the byte order, and type information. *//************************************************************************/int OGRPolygon::WkbSize() const{ int nSize = 9; int b3D = getCoordinateDimension() == 3; for( int i = 0; i < nRingCount; i++ ) { nSize += papoRings[i]->_WkbSize( b3D ); } return nSize;}/************************************************************************//* importFromWkb() *//* *//* Initialize from serialized stream in well known binary *//* format. *//************************************************************************/OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nSize ){ OGRwkbByteOrder eByteOrder; int nDataOffset, b3D; if( nSize < 21 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA;/* -------------------------------------------------------------------- *//* Get the byte order byte. *//* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); CPLAssert( eByteOrder == wkbXDR || eByteOrder == wkbNDR );/* -------------------------------------------------------------------- *//* Get the geometry feature type. For now we assume that *//* geometry type is between 0 and 255 so we only have to fetch *//* one byte. *//* -------------------------------------------------------------------- */#ifdef DEBUG OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) eGeometryType = (OGRwkbGeometryType) pabyData[1]; else eGeometryType = (OGRwkbGeometryType) pabyData[4]; CPLAssert( eGeometryType == wkbPolygon );#endif if( eByteOrder == wkbNDR ) b3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; else b3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; if( b3D ) nCoordDimension = 3; else nCoordDimension = 2;/* -------------------------------------------------------------------- *//* Do we already have some rings? *//* -------------------------------------------------------------------- */ if( nRingCount != 0 ) { for( int iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; OGRFree( papoRings ); papoRings = NULL; } /* -------------------------------------------------------------------- *//* Get the ring count. *//* -------------------------------------------------------------------- */ memcpy( &nRingCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nRingCount = CPL_SWAP32(nRingCount); papoRings = (OGRLinearRing **) OGRMalloc(sizeof(void*) * nRingCount); nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset;/* -------------------------------------------------------------------- *//* Get the rings. *//* -------------------------------------------------------------------- */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { OGRErr eErr; papoRings[iRing] = new OGRLinearRing(); eErr = papoRings[iRing]->_importFromWkb( eByteOrder, b3D, pabyData + nDataOffset, nSize ); if( eErr != OGRERR_NONE ) { nRingCount = iRing; return eErr; } if( nSize != -1 ) nSize -= papoRings[iRing]->_WkbSize( b3D ); nDataOffset += papoRings[iRing]->_WkbSize( b3D ); } return OGRERR_NONE;}/************************************************************************//* exportToWkb() *//* *//* Build a well known binary representation of this object. *//************************************************************************/OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const{ int nOffset; int b3D = getCoordinateDimension() == 3; /* -------------------------------------------------------------------- *//* Set the byte order. *//* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder);/* -------------------------------------------------------------------- *//* Set the geometry feature type. *//* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- *//* Copy in the raw data. *//* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== *//* Serialize each of the rings. *//* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, b3D, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(b3D); } return OGRERR_NONE;}/************************************************************************//* importFromWkt() *//* *//* Instantiate from well known text format. Currently this is *//* `POLYGON ((x y, x y, ...),(x y, ...),...)'. *//************************************************************************/OGRErr OGRPolygon::importFromWkt( char ** ppszInput ){ char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; int iRing;/* -------------------------------------------------------------------- *//* Clear existing rings. *//* -------------------------------------------------------------------- */ if( nRingCount > 0 ) { for( iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; nRingCount = 0; CPLFree( papoRings ); }/* -------------------------------------------------------------------- *//* Read and verify the ``POLYGON'' keyword token. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,"POLYGON") ) return OGRERR_CORRUPT_DATA;/* -------------------------------------------------------------------- *//* The next character should be a ( indicating the start of the *//* list of rings. We also need to support POLYGON EMPTY and *//* POLYGON(EMPTY). *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszInput; return OGRERR_NONE; } if( szToken[0] != '(' ) return OGRERR_CORRUPT_DATA; OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszInput, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; }/* ==================================================================== *//* Read each ring in turn. Note that we try to reuse the same *//* point list buffer from ring to ring to cut down on *//* allocate/deallocate overhead. *//* ==================================================================== */ OGRRawPoint *paoPoints = NULL; int nMaxPoints = 0, nMaxRings = 0; double *padfZ = NULL; nCoordDimension = 2; do { int nPoints = 0;/* -------------------------------------------------------------------- *//* Read points for one ring from input. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoints, &nPoints ); if( pszInput == NULL ) { CPLFree( paoPoints ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- *//* Do we need to grow the ring array? *//* -------------------------------------------------------------------- */ if( nRingCount == nMaxRings ) { nMaxRings = nMaxRings * 2 + 1; papoRings = (OGRLinearRing **) CPLRealloc(papoRings, nMaxRings * sizeof(OGRLinearRing*)); }/* -------------------------------------------------------------------- *//* Create the new ring, and assign to ring list. *//* -------------------------------------------------------------------- */ papoRings[nRingCount] = new OGRLinearRing(); papoRings[nRingCount]->setPoints( nPoints, paoPoints, padfZ ); nRingCount++; if( padfZ ) nCoordDimension = 3;/* -------------------------------------------------------------------- *//* Read the delimeter following the ring. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' );/* -------------------------------------------------------------------- *//* freak if we don't get a closing bracket. *//* -------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -