📄 shpopen.cpp
字号:
fwrite( abyHeader, 100, 1, fpSHP );
/* -------------------------------------------------------------------- */
/* Prepare, and write .shx file header. */
/* -------------------------------------------------------------------- */
i32 = 50; /* file size */
ByteCopy( &i32, abyHeader+24, 4 );
if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
fwrite( abyHeader, 100, 1, fpSHX );
/* -------------------------------------------------------------------- */
/* Close the files, and then open them as regular existing files. */
/* -------------------------------------------------------------------- */
fclose( fpSHP );
fclose( fpSHX );
return( SHPOpen( pszLayer, "r+b" ) );
}
/************************************************************************/
/* _SHPSetBounds() */
/* */
/* Compute a bounds rectangle for a shape, and set it into the */
/* indicated location in the record. */
/************************************************************************/
static void _SHPSetBounds( uchar * pabyRec, SHPObject * psShape )
{
ByteCopy( &(psShape->dfXMin), pabyRec + 0, 8 );
ByteCopy( &(psShape->dfYMin), pabyRec + 8, 8 );
ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 );
ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 );
if( bBigEndian )
{
SwapWord( 8, pabyRec + 0 );
SwapWord( 8, pabyRec + 8 );
SwapWord( 8, pabyRec + 16 );
SwapWord( 8, pabyRec + 24 );
}
}
/************************************************************************/
/* SHPComputeExtents() */
/* */
/* Recompute the extents of a shape. Automatically done by */
/* SHPCreateObject(). */
/************************************************************************/
void SHPAPI_CALL
SHPComputeExtents( SHPObject * psObject )
{
int i;
/* -------------------------------------------------------------------- */
/* Build extents for this object. */
/* -------------------------------------------------------------------- */
if( psObject->nVertices > 0 )
{
psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];
psObject->dfYMin = psObject->dfYMax = psObject->padfY[0];
psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0];
psObject->dfMMin = psObject->dfMMax = psObject->padfM[0];
}
for( i = 0; i < psObject->nVertices; i++ )
{
psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]);
psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]);
psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]);
psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]);
psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]);
psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]);
psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]);
psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]);
}
}
/************************************************************************/
/* SHPCreateObject() */
/* */
/* Create a shape object. It should be freed with */
/* SHPDestroyObject(). */
/************************************************************************/
SHPObject SHPAPI_CALL1(*)
SHPCreateObject( int nSHPType, int nShapeId, int nParts,
int * panPartStart, int * panPartType,
int nVertices, double * padfX, double * padfY,
double * padfZ, double * padfM )
{
SHPObject *psObject;
int i, bHasM, bHasZ;
psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
psObject->nSHPType = nSHPType;
psObject->nShapeId = nShapeId;
/* -------------------------------------------------------------------- */
/* Establish whether this shape type has M, and Z values. */
/* -------------------------------------------------------------------- */
if( nSHPType == SHPT_ARCM
|| nSHPType == SHPT_POINTM
|| nSHPType == SHPT_POLYGONM
|| nSHPType == SHPT_MULTIPOINTM )
{
bHasM = TRUE;
bHasZ = FALSE;
}
else if( nSHPType == SHPT_ARCZ
|| nSHPType == SHPT_POINTZ
|| nSHPType == SHPT_POLYGONZ
|| nSHPType == SHPT_MULTIPOINTZ
|| nSHPType == SHPT_MULTIPATCH )
{
bHasM = TRUE;
bHasZ = TRUE;
}
else
{
bHasM = FALSE;
bHasZ = FALSE;
}
/* -------------------------------------------------------------------- */
/* Capture parts. Note that part type is optional, and */
/* defaults to ring. */
/* -------------------------------------------------------------------- */
if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON
|| nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM
|| nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ
|| nSHPType == SHPT_MULTIPATCH )
{
psObject->nParts = MAX(1,nParts);
psObject->panPartStart = (int *)
malloc(sizeof(int) * psObject->nParts);
psObject->panPartType = (int *)
malloc(sizeof(int) * psObject->nParts);
psObject->panPartStart[0] = 0;
psObject->panPartType[0] = SHPP_RING;
for( i = 0; i < nParts; i++ )
{
psObject->panPartStart[i] = panPartStart[i];
if( panPartType != NULL )
psObject->panPartType[i] = panPartType[i];
else
psObject->panPartType[i] = SHPP_RING;
}
}
/* -------------------------------------------------------------------- */
/* Capture vertices. Note that Z and M are optional, but X and */
/* Y are not. */
/* -------------------------------------------------------------------- */
if( nVertices > 0 )
{
psObject->padfX = (double *) calloc(sizeof(double),nVertices);
psObject->padfY = (double *) calloc(sizeof(double),nVertices);
psObject->padfZ = (double *) calloc(sizeof(double),nVertices);
psObject->padfM = (double *) calloc(sizeof(double),nVertices);
assert( padfX != NULL );
assert( padfY != NULL );
for( i = 0; i < nVertices; i++ )
{
psObject->padfX[i] = padfX[i];
psObject->padfY[i] = padfY[i];
if( padfZ != NULL && bHasZ )
psObject->padfZ[i] = padfZ[i];
if( padfM != NULL && bHasM )
psObject->padfM[i] = padfM[i];
}
}
/* -------------------------------------------------------------------- */
/* Compute the extents. */
/* -------------------------------------------------------------------- */
psObject->nVertices = nVertices;
SHPComputeExtents( psObject );
return( psObject );
}
/************************************************************************/
/* SHPCreateSimpleObject() */
/* */
/* Create a simple (common) shape object. Destroy with */
/* SHPDestroyObject(). */
/************************************************************************/
SHPObject SHPAPI_CALL1(*)
SHPCreateSimpleObject( int nSHPType, int nVertices,
double * padfX, double * padfY,
double * padfZ )
{
return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
nVertices, padfX, padfY, padfZ, NULL ) );
}
/************************************************************************/
/* SHPWriteObject() */
/* */
/* Write out the vertices of a new structure. Note that it is */
/* only possible to write vertices at the end of the file. */
/************************************************************************/
int SHPAPI_CALL
SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
{
int nRecordOffset, i, nRecordSize;
uchar *pabyRec;
int32 i32;
psSHP->bUpdated = TRUE;
/* -------------------------------------------------------------------- */
/* Ensure that shape object matches the type of the file it is */
/* being written to. */
/* -------------------------------------------------------------------- */
assert( psObject->nSHPType == psSHP->nShapeType
|| psObject->nSHPType == SHPT_NULL );
/* -------------------------------------------------------------------- */
/* Ensure that -1 is used for appends. Either blow an */
/* assertion, or if they are disabled, set the shapeid to -1 */
/* for appends. */
/* -------------------------------------------------------------------- */
assert( nShapeId == -1
|| (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
if( nShapeId != -1 && nShapeId >= psSHP->nRecords )
nShapeId = -1;
/* -------------------------------------------------------------------- */
/* Add the new entity to the in memory index. */
/* -------------------------------------------------------------------- */
if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
{
psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
psSHP->panRecOffset = (int *)
SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
psSHP->panRecSize = (int *)
SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
}
/* -------------------------------------------------------------------- */
/* Initialize record. */
/* -------------------------------------------------------------------- */
pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double)
+ psObject->nParts * 8 + 128);
/* -------------------------------------------------------------------- */
/* Extract vertices for a Polygon or Arc. */
/* -------------------------------------------------------------------- */
if( psObject->nSHPType == SHPT_POLYGON
|| psObject->nSHPType == SHPT_POLYGONZ
|| psObject->nSHPType == SHPT_POLYGONM
|| psObject->nSHPType == SHPT_ARC
|| psObject->nSHPType == SHPT_ARCZ
|| psObject->nSHPType == SHPT_ARCM
|| psObject->nSHPType == SHPT_MULTIPATCH )
{
int32 nPoints, nParts;
int i;
nPoints = psObject->nVertices;
nParts = psObject->nParts;
_SHPSetBounds( pabyRec + 12, psObject );
if( bBigEndian ) SwapWord( 4, &nPoints );
if( bBigEndian ) SwapWord( 4, &nParts );
ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
nRecordSize = 52;
/*
* Write part start positions.
*/
ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
4 * psObject->nParts );
for( i = 0; i < psObject->nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
nRecordSize += 4;
}
/*
* Write multipatch part types if needed.
*/
if( psObject->nSHPType == SHPT_MULTIPATCH )
{
memcpy( pabyRec + nRecordSize, psObject->panPartType,
4*psObject->nParts );
for( i = 0; i < psObject->nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
nRecordSize += 4;
}
}
/*
* Write the (x,y) vertex values.
*/
for( i = 0; i < psObject->nVertices; i++ )
{
ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
if( bBigEndian )
SwapWord( 8, pabyRec + nRecordSize );
if( bBigEndian )
SwapWord( 8, pabyRec + nRecordSize + 8 );
nRecordSize += 2 * 8;
}
/*
* Write the Z coordinates (if any).
*/
if( psObject->nSHPType == SHPT_POLYGONZ
|| psObject->nSHPType == SHPT_ARCZ
|| psObject->nSHPType == SHPT_MULTIPATCH )
{
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++ )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -