📄 shpopen.cpp
字号:
ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
}
/*
* Write the M values, if any.
*/
if( psObject->nSHPType == SHPT_POLYGONM
|| psObject->nSHPType == SHPT_ARCM
#ifndef DISABLE_MULTIPATCH_MEASURE
|| psObject->nSHPType == SHPT_MULTIPATCH
#endif
|| psObject->nSHPType == SHPT_POLYGONZ
|| psObject->nSHPType == SHPT_ARCZ )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
for( i = 0; i < psObject->nVertices; i++ )
{
ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
}
}
/* -------------------------------------------------------------------- */
/* Extract vertices for a MultiPoint. */
/* -------------------------------------------------------------------- */
else if( psObject->nSHPType == SHPT_MULTIPOINT
|| psObject->nSHPType == SHPT_MULTIPOINTZ
|| psObject->nSHPType == SHPT_MULTIPOINTM )
{
int32 nPoints;
int i;
nPoints = psObject->nVertices;
_SHPSetBounds( pabyRec + 12, psObject );
if( bBigEndian ) SwapWord( 4, &nPoints );
ByteCopy( &nPoints, pabyRec + 44, 4 );
for( i = 0; i < psObject->nVertices; i++ )
{
ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
}
nRecordSize = 48 + 16 * psObject->nVertices;
if( psObject->nSHPType == SHPT_MULTIPOINTZ )
{
ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
for( i = 0; i < psObject->nVertices; i++ )
{
ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
}
if( psObject->nSHPType == SHPT_MULTIPOINTZ
|| psObject->nSHPType == SHPT_MULTIPOINTM )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
for( i = 0; i < psObject->nVertices; i++ )
{
ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
}
}
/* -------------------------------------------------------------------- */
/* Write point. */
/* -------------------------------------------------------------------- */
else if( psObject->nSHPType == SHPT_POINT
|| psObject->nSHPType == SHPT_POINTZ
|| psObject->nSHPType == SHPT_POINTM )
{
ByteCopy( psObject->padfX, pabyRec + 12, 8 );
ByteCopy( psObject->padfY, pabyRec + 20, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
nRecordSize = 28;
if( psObject->nSHPType == SHPT_POINTZ )
{
ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
if( psObject->nSHPType == SHPT_POINTZ
|| psObject->nSHPType == SHPT_POINTM )
{
ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
}
/* -------------------------------------------------------------------- */
/* Not much to do for null geometries. */
/* -------------------------------------------------------------------- */
else if( psObject->nSHPType == SHPT_NULL )
{
nRecordSize = 12;
}
else
{
/* unknown type */
assert( FALSE );
}
/* -------------------------------------------------------------------- */
/* Establish where we are going to put this record. If we are */
/* rewriting and existing record, and it will fit, then put it */
/* back where the original came from. Otherwise write at the end. */
/* -------------------------------------------------------------------- */
if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
{
if( nShapeId == -1 )
nShapeId = psSHP->nRecords++;
psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize;
psSHP->panRecSize[nShapeId] = nRecordSize-8;
psSHP->nFileSize += nRecordSize;
}
else
{
nRecordOffset = psSHP->panRecOffset[nShapeId];
}
/* -------------------------------------------------------------------- */
/* Set the shape type, record number, and record size. */
/* -------------------------------------------------------------------- */
i32 = nShapeId+1; /* record # */
if( !bBigEndian ) SwapWord( 4, &i32 );
ByteCopy( &i32, pabyRec, 4 );
i32 = (nRecordSize-8)/2; /* record size */
if( !bBigEndian ) SwapWord( 4, &i32 );
ByteCopy( &i32, pabyRec + 4, 4 );
i32 = psObject->nSHPType; /* shape type */
if( bBigEndian ) SwapWord( 4, &i32 );
ByteCopy( &i32, pabyRec + 8, 4 );
/* -------------------------------------------------------------------- */
/* Write out record. */
/* -------------------------------------------------------------------- */
if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
|| fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
{
printf( "Error in fseek() or fwrite().\n" );
free( pabyRec );
return -1;
}
free( pabyRec );
/* -------------------------------------------------------------------- */
/* Expand file wide bounds based on this shape. */
/* -------------------------------------------------------------------- */
if( psSHP->adBoundsMin[0] == 0.0
&& psSHP->adBoundsMax[0] == 0.0
&& psSHP->adBoundsMin[1] == 0.0
&& psSHP->adBoundsMax[1] == 0.0
&& psObject->nSHPType != SHPT_NULL )
{
psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
}
for( i = 0; i < psObject->nVertices; i++ )
{
psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
}
return( nShapeId );
}
/************************************************************************/
/* SHPReadObject() */
/* */
/* Read the vertices, parts, and other non-attribute information */
/* for one shape. */
/************************************************************************/
SHPObject SHPAPI_CALL1(*)
SHPReadObject( SHPHandle psSHP, int hEntity )
{
SHPObject *psShape;
/* -------------------------------------------------------------------- */
/* Validate the record/entity number. */
/* -------------------------------------------------------------------- */
if( hEntity < 0 || hEntity >= psSHP->nRecords )
return( NULL );
/* -------------------------------------------------------------------- */
/* Ensure our record buffer is large enough. */
/* -------------------------------------------------------------------- */
if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
{
psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
}
/* -------------------------------------------------------------------- */
/* Read the record. */
/* -------------------------------------------------------------------- */
fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 );
fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );
/* -------------------------------------------------------------------- */
/* Allocate and minimally initialize the object. */
/* -------------------------------------------------------------------- */
psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
psShape->nShapeId = hEntity;
memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
/* ==================================================================== */
/* Extract vertices for a Polygon or Arc. */
/* ==================================================================== */
if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC
|| psShape->nSHPType == SHPT_POLYGONZ
|| psShape->nSHPType == SHPT_POLYGONM
|| psShape->nSHPType == SHPT_ARCZ
|| psShape->nSHPType == SHPT_ARCM
|| psShape->nSHPType == SHPT_MULTIPATCH )
{
int32 nPoints, nParts;
int i, nOffset;
/* -------------------------------------------------------------------- */
/* Get the X/Y bounds. */
/* -------------------------------------------------------------------- */
memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 );
memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
/* -------------------------------------------------------------------- */
/* Extract part/point count, and build vertex and part arrays */
/* to proper size. */
/* -------------------------------------------------------------------- */
memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
if( bBigEndian ) SwapWord( 4, &nPoints );
if( bBigEndian ) SwapWord( 4, &nParts );
psShape->nVertices = nPoints;
psShape->padfX = (double *) calloc(nPoints,sizeof(double));
psShape->padfY = (double *) calloc(nPoints,sizeof(double));
psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
psShape->padfM = (double *) calloc(nPoints,sizeof(double));
psShape->nParts = nParts;
psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
psShape->panPartType = (int *) calloc(nParts,sizeof(int));
for( i = 0; i < nParts; i++ )
psShape->panPartType[i] = SHPP_RING;
/* -------------------------------------------------------------------- */
/* Copy out the part array from the record. */
/* -------------------------------------------------------------------- */
memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
for( i = 0; i < nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
}
nOffset = 44 + 8 + 4*nParts;
/* -------------------------------------------------------------------- */
/* If this is a multipatch, we will also have parts types. */
/* -------------------------------------------------------------------- */
if( psShape->nSHPType == SHPT_MULTIPATCH )
{
memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
for( i = 0; i < nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
}
nOffset += 4*nParts;
}
/* -------------------------------------------------------------------- */
/* Copy out the vertices from the record. */
/* -------------------------------------------------------------------- */
for( i = 0; i < nPoints; i++ )
{
memcpy(psShape->padfX + i,
psSHP->pabyRec + nOffset + i * 16,
8 );
memcpy(psShape->padfY + i,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -