📄 shpopen.cpp
字号:
int i;
double dValue;
/* -------------------------------------------------------------------- */
/* Ensure the access string is one of the legal ones. We */
/* ensure the result string indicates binary to avoid common */
/* problems on Windows. */
/* -------------------------------------------------------------------- */
if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
|| strcmp(pszAccess,"r+") == 0 )
pszAccess = "r+b";
else
pszAccess = "rb";
/* -------------------------------------------------------------------- */
/* Establish the byte order on this machine. */
/* -------------------------------------------------------------------- */
i = 1;
if( *((uchar *) &i) == 1 )
bBigEndian = FALSE;
else
bBigEndian = TRUE;
/* -------------------------------------------------------------------- */
/* Initialize the info structure. */
/* -------------------------------------------------------------------- */
psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
psSHP->bUpdated = FALSE;
/* -------------------------------------------------------------------- */
/* Compute the base (layer) name. If there is any extension */
/* on the passed in filename we will strip it off. */
/* -------------------------------------------------------------------- */
pszBasename = (char *) malloc(strlen(pszLayer)+5);
strcpy( pszBasename, pszLayer );
for( i = strlen(pszBasename)-1;
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
&& pszBasename[i] != '\\';
i-- ) {}
if( pszBasename[i] == '.' )
pszBasename[i] = '\0';
/* -------------------------------------------------------------------- */
/* Open the .shp and .shx files. Note that files pulled from */
/* a PC to Unix with upper case filenames won't work! */
/* -------------------------------------------------------------------- */
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
sprintf( pszFullname, "%s.shp", pszBasename );
psSHP->fpSHP = fopen(pszFullname, pszAccess );
if( psSHP->fpSHP == NULL )
{
sprintf( pszFullname, "%s.SHP", pszBasename );
psSHP->fpSHP = fopen(pszFullname, pszAccess );
}
if( psSHP->fpSHP == NULL )
{
free( psSHP );
free( pszBasename );
free( pszFullname );
return( NULL );
}
sprintf( pszFullname, "%s.shx", pszBasename );
psSHP->fpSHX = fopen(pszFullname, pszAccess );
if( psSHP->fpSHX == NULL )
{
sprintf( pszFullname, "%s.SHX", pszBasename );
psSHP->fpSHX = fopen(pszFullname, pszAccess );
}
if( psSHP->fpSHX == NULL )
{
fclose( psSHP->fpSHP );
free( psSHP );
free( pszBasename );
free( pszFullname );
return( NULL );
}
free( pszFullname );
free( pszBasename );
/* -------------------------------------------------------------------- */
/* Read the file size from the SHP file. */
/* -------------------------------------------------------------------- */
pabyBuf = (uchar *) malloc(100);
fread( pabyBuf, 100, 1, psSHP->fpSHP );
psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
+ pabyBuf[25] * 256 * 256
+ pabyBuf[26] * 256
+ pabyBuf[27]) * 2;
/* -------------------------------------------------------------------- */
/* Read SHX file Header info */
/* -------------------------------------------------------------------- */
fread( pabyBuf, 100, 1, psSHP->fpSHX );
if( pabyBuf[0] != 0
|| pabyBuf[1] != 0
|| pabyBuf[2] != 0x27
|| (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
{
fclose( psSHP->fpSHP );
fclose( psSHP->fpSHX );
free( psSHP );
return( NULL );
}
psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
+ pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
psSHP->nShapeType = pabyBuf[32];
if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
{
/* this header appears to be corrupt. Give up. */
fclose( psSHP->fpSHP );
fclose( psSHP->fpSHX );
free( psSHP );
return( NULL );
}
/* -------------------------------------------------------------------- */
/* Read the bounds. */
/* -------------------------------------------------------------------- */
if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
memcpy( &dValue, pabyBuf+36, 8 );
psSHP->adBoundsMin[0] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
memcpy( &dValue, pabyBuf+44, 8 );
psSHP->adBoundsMin[1] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
memcpy( &dValue, pabyBuf+52, 8 );
psSHP->adBoundsMax[0] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
memcpy( &dValue, pabyBuf+60, 8 );
psSHP->adBoundsMax[1] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+68 ); /* z */
memcpy( &dValue, pabyBuf+68, 8 );
psSHP->adBoundsMin[2] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
memcpy( &dValue, pabyBuf+76, 8 );
psSHP->adBoundsMax[2] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+84 ); /* z */
memcpy( &dValue, pabyBuf+84, 8 );
psSHP->adBoundsMin[3] = dValue;
if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
memcpy( &dValue, pabyBuf+92, 8 );
psSHP->adBoundsMax[3] = dValue;
free( pabyBuf );
/* -------------------------------------------------------------------- */
/* Read the .shx file to get the offsets to each record in */
/* the .shp file. */
/* -------------------------------------------------------------------- */
psSHP->nMaxRecords = psSHP->nRecords;
psSHP->panRecOffset =
(int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
psSHP->panRecSize =
(int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );
for( i = 0; i < psSHP->nRecords; i++ )
{
int32 nOffset, nLength;
memcpy( &nOffset, pabyBuf + i * 8, 4 );
if( !bBigEndian ) SwapWord( 4, &nOffset );
memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
if( !bBigEndian ) SwapWord( 4, &nLength );
psSHP->panRecOffset[i] = nOffset*2;
psSHP->panRecSize[i] = nLength*2;
}
free( pabyBuf );
return( psSHP );
}
/************************************************************************/
/* SHPClose() */
/* */
/* Close the .shp and .shx files. */
/************************************************************************/
void SHPAPI_CALL
SHPClose(SHPHandle psSHP )
{
/* -------------------------------------------------------------------- */
/* Update the header if we have modified anything. */
/* -------------------------------------------------------------------- */
if( psSHP->bUpdated )
{
SHPWriteHeader( psSHP );
}
/* -------------------------------------------------------------------- */
/* Free all resources, and close files. */
/* -------------------------------------------------------------------- */
free( psSHP->panRecOffset );
free( psSHP->panRecSize );
fclose( psSHP->fpSHX );
fclose( psSHP->fpSHP );
if( psSHP->pabyRec != NULL )
{
free( psSHP->pabyRec );
}
free( psSHP );
}
/************************************************************************/
/* SHPGetInfo() */
/* */
/* Fetch general information about the shape file. */
/************************************************************************/
void SHPAPI_CALL
SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
double * padfMinBound, double * padfMaxBound )
{
int i;
if( pnEntities != NULL )
*pnEntities = psSHP->nRecords;
if( pnShapeType != NULL )
*pnShapeType = psSHP->nShapeType;
for( i = 0; i < 4; i++ )
{
if( padfMinBound != NULL )
padfMinBound[i] = psSHP->adBoundsMin[i];
if( padfMaxBound != NULL )
padfMaxBound[i] = psSHP->adBoundsMax[i];
}
}
/************************************************************************/
/* SHPCreate() */
/* */
/* Create a new shape file and return a handle to the open */
/* shape file with read/write access. */
/************************************************************************/
SHPHandle SHPAPI_CALL
SHPCreate( const char * pszLayer, int nShapeType )
{
char *pszBasename, *pszFullname;
int i;
FILE *fpSHP, *fpSHX;
uchar abyHeader[100];
int32 i32;
double dValue;
/* -------------------------------------------------------------------- */
/* Establish the byte order on this system. */
/* -------------------------------------------------------------------- */
i = 1;
if( *((uchar *) &i) == 1 )
bBigEndian = FALSE;
else
bBigEndian = TRUE;
/* -------------------------------------------------------------------- */
/* Compute the base (layer) name. If there is any extension */
/* on the passed in filename we will strip it off. */
/* -------------------------------------------------------------------- */
pszBasename = (char *) malloc(strlen(pszLayer)+5);
strcpy( pszBasename, pszLayer );
for( i = strlen(pszBasename)-1;
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
&& pszBasename[i] != '\\';
i-- ) {}
if( pszBasename[i] == '.' )
pszBasename[i] = '\0';
/* -------------------------------------------------------------------- */
/* Open the two files so we can write their headers. */
/* -------------------------------------------------------------------- */
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
sprintf( pszFullname, "%s.shp", pszBasename );
fpSHP = fopen(pszFullname, "wb" );
if( fpSHP == NULL )
return( NULL );
sprintf( pszFullname, "%s.shx", pszBasename );
fpSHX = fopen(pszFullname, "wb" );
if( fpSHX == NULL )
return( NULL );
free( pszFullname );
free( pszBasename );
/* -------------------------------------------------------------------- */
/* Prepare header block for .shp file. */
/* -------------------------------------------------------------------- */
for( i = 0; i < 100; i++ )
abyHeader[i] = 0;
abyHeader[2] = 0x27; /* magic cookie */
abyHeader[3] = 0x0a;
i32 = 50; /* file size */
ByteCopy( &i32, abyHeader+24, 4 );
if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
i32 = 1000; /* version */
ByteCopy( &i32, abyHeader+28, 4 );
if( bBigEndian ) SwapWord( 4, abyHeader+28 );
i32 = nShapeType; /* shape type */
ByteCopy( &i32, abyHeader+32, 4 );
if( bBigEndian ) SwapWord( 4, abyHeader+32 );
dValue = 0.0; /* set bounds */
ByteCopy( &dValue, abyHeader+36, 8 );
ByteCopy( &dValue, abyHeader+44, 8 );
ByteCopy( &dValue, abyHeader+52, 8 );
ByteCopy( &dValue, abyHeader+60, 8 );
/* -------------------------------------------------------------------- */
/* Write .shp file header. */
/* -------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -