📄 ogrpolygon.cpp
字号:
/************************************************************************/
/* 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. */
/* -------------------------------------------------------------------- */
CPLFree( paoPoints );
CPLFree( padfZ );
if( szToken[0] != ')' )
return OGRERR_CORRUPT_DATA;
*ppszInput = (char *) pszInput;
return OGRERR_NONE;
}
/************************************************************************/
/* exportToWkt() */
/* */
/* Translate this structure into it's well known text format */
/* equivelent. This could be made alot more CPU efficient! */
/************************************************************************/
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText ) const
{
char **papszRings;
int iRing, nCumulativeLength = 0, nNonEmptyRings = 0;
OGRErr eErr;
/* -------------------------------------------------------------------- */
/* Build a list of strings containing the stuff for each ring. */
/* -------------------------------------------------------------------- */
papszRings = (char **) CPLCalloc(sizeof(char *),nRingCount);
for( iRing = 0; iRing < nRingCount; iRing++ )
{
papoRings[iRing]->setCoordinateDimension( getCoordinateDimension() );
if( papoRings[iRing]->getNumPoints() == 0 )
{
papszRings[iRing] = NULL;
continue;
}
eErr = papoRings[iRing]->exportToWkt( &(papszRings[iRing]) );
if( eErr != OGRERR_NONE )
return eErr;
CPLAssert( EQUALN(papszRings[iRing],"LINEARRING (", 12) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -