?? ogrlinestring.cpp
字號:
else
nGType = CPL_MSBWORD32( nGType );
memcpy( pabyData + 1, &nGType, 4 );
/* -------------------------------------------------------------------- */
/* Copy in the data count. */
/* -------------------------------------------------------------------- */
memcpy( pabyData+5, &nPointCount, 4 );
/* -------------------------------------------------------------------- */
/* Copy in the raw data. */
/* -------------------------------------------------------------------- */
int i;
if( getCoordinateDimension() == 3 )
{
for( i = 0; i < nPointCount; i++ )
{
memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 );
memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 );
}
}
else
memcpy( pabyData+9, paoPoints, 16 * nPointCount );
/* -------------------------------------------------------------------- */
/* Swap if needed. */
/* -------------------------------------------------------------------- */
if( OGR_SWAP( eByteOrder ) )
{
int nCount;
nCount = CPL_SWAP32( nPointCount );
memcpy( pabyData+5, &nCount, 4 );
for( i = getCoordinateDimension() * nPointCount - 1; i >= 0; i-- )
{
CPL_SWAP64PTR( pabyData + 9 + 8 * i );
}
}
return OGRERR_NONE;
}
/************************************************************************/
/* importFromWkt() */
/* */
/* Instantiate from well known text format. Currently this is */
/* `LINESTRING ( x y, x y, ...)', */
/************************************************************************/
OGRErr OGRLineString::importFromWkt( char ** ppszInput )
{
char szToken[OGR_WKT_TOKEN_MAX];
const char *pszInput = *ppszInput;
if( paoPoints != NULL )
{
nPointCount = 0;
CPLFree( paoPoints );
paoPoints = NULL;
CPLFree( padfZ );
padfZ = NULL;
}
/* -------------------------------------------------------------------- */
/* Read and verify the ``LINESTRING'' keyword token. */
/* -------------------------------------------------------------------- */
pszInput = OGRWktReadToken( pszInput, szToken );
if( !EQUAL(szToken,getGeometryName()) )
return OGRERR_CORRUPT_DATA;
/* -------------------------------------------------------------------- */
/* Check for EMPTY or (EMPTY). */
/* -------------------------------------------------------------------- */
const char *pszPreScan;
pszPreScan = OGRWktReadToken( pszInput, szToken );
if( EQUAL(szToken,"EMPTY") )
{
*ppszInput = (char *) pszPreScan;
return OGRERR_NONE;
}
if( !EQUAL(szToken,"(") )
return OGRERR_CORRUPT_DATA;
pszPreScan = OGRWktReadToken( pszPreScan, szToken );
if( EQUAL(szToken,"EMPTY") )
{
pszPreScan = OGRWktReadToken( pszPreScan, szToken );
*ppszInput = (char *) pszPreScan;
if( !EQUAL(szToken,")") )
return OGRERR_CORRUPT_DATA;
else
return OGRERR_NONE;
}
/* -------------------------------------------------------------------- */
/* Read the point list. */
/* -------------------------------------------------------------------- */
int nMaxPoint = 0;
nPointCount = 0;
pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoint,
&nPointCount );
if( pszInput == NULL )
return OGRERR_CORRUPT_DATA;
*ppszInput = (char *) pszInput;
if( padfZ == NULL )
nCoordDimension = 2;
else
nCoordDimension = 3;
return OGRERR_NONE;
}
/************************************************************************/
/* exportToWkt() */
/* */
/* Translate this structure into it's well known text format */
/* equivelent. This could be made alot more CPU efficient! */
/************************************************************************/
OGRErr OGRLineString::exportToWkt( char ** ppszDstText ) const
{
int nMaxString = nPointCount * 40 * 3 + 20;
int nRetLen = 0;
/* -------------------------------------------------------------------- */
/* Handle special empty case. */
/* -------------------------------------------------------------------- */
if( nPointCount == 0 )
{
CPLString osEmpty;
osEmpty.Printf("%s EMPTY",getGeometryName());
*ppszDstText = CPLStrdup(osEmpty);
return OGRERR_NONE;
}
/* -------------------------------------------------------------------- */
/* General case. */
/* -------------------------------------------------------------------- */
*ppszDstText = (char *) VSIMalloc( nMaxString );
if( *ppszDstText == NULL )
return OGRERR_NOT_ENOUGH_MEMORY;
sprintf( *ppszDstText, "%s (", getGeometryName() );
for( int i = 0; i < nPointCount; i++ )
{
if( nMaxString <= (int) strlen(*ppszDstText+nRetLen) + 32 + nRetLen )
{
CPLDebug( "OGR",
"OGRLineString::exportToWkt() ... buffer overflow.\n"
"nMaxString=%d, strlen(*ppszDstText) = %d, i=%d\n"
"*ppszDstText = %s",
nMaxString, strlen(*ppszDstText), i, *ppszDstText );
VSIFree( *ppszDstText );
*ppszDstText = NULL;
return OGRERR_NOT_ENOUGH_MEMORY;
}
if( i > 0 )
strcat( *ppszDstText + nRetLen, "," );
nRetLen += strlen(*ppszDstText + nRetLen);
if( getCoordinateDimension() == 3 )
OGRMakeWktCoordinate( *ppszDstText + nRetLen,
paoPoints[i].x,
paoPoints[i].y,
padfZ[i],
nCoordDimension );
else
OGRMakeWktCoordinate( *ppszDstText + nRetLen,
paoPoints[i].x,
paoPoints[i].y,
0.0,
nCoordDimension );
nRetLen += strlen(*ppszDstText + nRetLen);
}
strcat( *ppszDstText+nRetLen, ")" );
return OGRERR_NONE;
}
/************************************************************************/
/* get_Length() */
/* */
/* For now we return a simple euclidian 2D distance. */
/************************************************************************/
double OGRLineString::get_Length() const
{
double dfLength = 0;
int i;
for( i = 0; i < nPointCount-1; i++ )
{
double dfDeltaX, dfDeltaY;
dfDeltaX = paoPoints[i+1].x - paoPoints[i].x;
dfDeltaY = paoPoints[i+1].y - paoPoints[i].y;
dfLength += sqrt(dfDeltaX*dfDeltaX + dfDeltaY*dfDeltaY);
}
return dfLength;
}
/************************************************************************/
/* StartPoint() */
/************************************************************************/
void OGRLineString::StartPoint( OGRPoint * poPoint ) const
{
getPoint( 0, poPoint );
}
/************************************************************************/
/* EndPoint() */
/************************************************************************/
void OGRLineString::EndPoint( OGRPoint * poPoint ) const
{
getPoint( nPointCount-1, poPoint );
}
/************************************************************************/
/* Value() */
/* */
/* Get an interpolated point at some distance along the curve. */
/************************************************************************/
void OGRLineString::Value( double dfDistance, OGRPoint * poPoint ) const
{
double dfLength = 0;
int i;
if( dfDistance < 0 )
{
StartPoint( poPoint );
return;
}
for( i = 0; i < nPointCount-1; i++ )
{
double dfDeltaX, dfDeltaY, dfSegLength;
dfDeltaX = paoPoints[i+1].x - paoPoints[i].x;
dfDeltaY = paoPoints[i+1].y - paoPoints[i].y;
dfSegLength = sqrt(dfDeltaX*dfDeltaX + dfDeltaY*dfDeltaY);
if (dfSegLength > 0)
{
if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >=
dfDistance) )
{
double dfRatio;
dfRatio = (dfDistance - dfLength) / dfSegLength;
poPoint->setX( paoPoints[i].x * (1 - dfRatio)
+ paoPoints[i+1].x * dfRatio );
poPoint->setY( paoPoints[i].y * (1 - dfRatio)
+ paoPoints[i+1].y * dfRatio );
if( getCoordinateDimension() == 3 )
poPoint->setZ( padfZ[i] * (1 - dfRatio)
+ padfZ[i] * dfRatio );
return;
}
dfLength += dfSegLength;
}
}
EndPoint( poPoint );
}
/************************************************************************/
/* getEnvelope() */
/************************************************************************/
void OGRLineString::getEnvelope( OGREnvelope * psEnvelope ) const
{
double dfMinX, dfMinY, dfMaxX, dfMaxY;
if( nPointCount == 0 )
return;
dfMinX = dfMaxX = paoPoints[0].x;
dfMinY = dfMaxY = paoPoints[0].y;
for( int iPoint = 1; iPoint < nPointCount; iPoint++ )
{
if( dfMaxX < paoPoints[iPoint].x )
dfMaxX = paoPoints[iPoint].x;
if( dfMaxY < paoPoints[iPoint].y )
dfMaxY = paoPoints[iPoint].y;
if( dfMinX > paoPoints[iPoint].x )
dfMinX = paoPoints[iPoint].x;
if( dfMinY > paoPoints[iPoint].y )
dfMinY = paoPoints[iPoint].y;
}
psEnvelope->MinX = dfMinX;
psEnvelope->MaxX = dfMaxX;
psEnvelope->MinY = dfMinY;
psEnvelope->MaxY = dfMaxY;
}
/************************************************************************/
/* Equals() */
/************************************************************************/
OGRBoolean OGRLineString::Equals( OGRGeometry * poOther ) const
{
OGRLineString *poOLine = (OGRLineString *) poOther;
if( poOLine == this )
return TRUE;
if( poOther->getGeometryType() != getGeometryType() )
return FALSE;
// we should eventually test the SRS.
if( getNumPoints() != poOLine->getNumPoints() )
return FALSE;
for( int iPoint = 0; iPoint < getNumPoints(); iPoint++ )
{
if( getX(iPoint) != poOLine->getX(iPoint)
|| getY(iPoint) != poOLine->getY(iPoint)
|| getZ(iPoint) != poOLine->getZ(iPoint) )
return FALSE;
}
return TRUE;
}
/************************************************************************/
/* transform() */
/************************************************************************/
OGRErr OGRLineString::transform( OGRCoordinateTransformation *poCT )
{
#ifdef DISABLE_OGRGEOM_TRANSFORM
return OGRERR_FAILURE;
#else
double *xyz;
int i;
/* -------------------------------------------------------------------- */
/* Because we don't want to partially transform this geometry */
/* (if some points fail after some have succeeded) we will */
/* instead make a copy of the points to operate on. */
/* -------------------------------------------------------------------- */
xyz = (double *) CPLMalloc(sizeof(double) * nPointCount * 3);
if( xyz == NULL )
return OGRERR_NOT_ENOUGH_MEMORY;
for( i = 0; i < nPointCount; i++ )
{
xyz[i ] = paoPoints[i].x;
xyz[i+nPointCount] = paoPoints[i].y;
if( padfZ )
xyz[i+nPointCount*2] = padfZ[i];
else
xyz[i+nPointCount*2] = 0.0;
}
/* -------------------------------------------------------------------- */
/* Transform and reapply. */
/* -------------------------------------------------------------------- */
if( !poCT->Transform( nPointCount, xyz, xyz + nPointCount,
xyz+nPointCount*2 ) )
{
CPLFree( xyz );
return OGRERR_FAILURE;
}
else
{
setPoints( nPointCount, xyz, xyz+nPointCount, xyz+nPointCount*2 );
CPLFree( xyz );
assignSpatialReference( poCT->GetTargetCS() );
return OGRERR_NONE;
}
#endif
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -