?? shpopen.c
字號:
ByteCopy( &i32, abyHeader+24, 4 ); if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); if( fseek( psSHP->fpSHX, 0, 0 ) != 0 || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Failure writing .shx header." );#endif return; }/* -------------------------------------------------------------------- *//* Write out the .shx contents. *//* -------------------------------------------------------------------- */ panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords); for( i = 0; i < psSHP->nRecords; i++ ) { panSHX[i*2 ] = psSHP->panRecOffset[i]/2; panSHX[i*2+1] = psSHP->panRecSize[i]/2; if( !bBigEndian ) SwapWord( 4, panSHX+i*2 ); if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); } if( (int)fwrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) != psSHP->nRecords ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Failure writing .shx contents." );#endif } free( panSHX );/* -------------------------------------------------------------------- *//* Flush to disk. *//* -------------------------------------------------------------------- */ fflush( psSHP->fpSHP ); fflush( psSHP->fpSHX );}/************************************************************************//* shpopen() *//* *//* Open the .shp and .shx files based on the basename of the *//* files or either file name. *//************************************************************************/ SHPHandle SHPAPI_CALLSHPOpen( const char * pszLayer, const char * pszAccess ){ char *pszFullname, *pszBasename; SHPHandle psSHP; uchar *pabyBuf; 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 ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open %s.shp or %s.SHP.", pszBasename, pszBasename );#endif 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 ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open %s.shx or %s.SHX.", pszBasename, pszBasename );#endif 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 *//* -------------------------------------------------------------------- */ if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 || pabyBuf[0] != 0 || pabyBuf[1] != 0 || pabyBuf[2] != 0x27 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_AppDefined, ".shx file is unreadable, or corrupt." );#endif 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 ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_AppDefined, "Record count in .shp header is %d, which seems\n" "unreasonable. Assuming header is corrupt.", psSHP->nRecords );#endif 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) ); if( (int) fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) != psSHP->nRecords ) {#ifdef USE_CPL CPLError( CE_Failure, CPLE_AppDefined, "Failed to read all values for %d records in .shx file.", psSHP->nRecords );#endif /* SHX is short or unreadable for some reason. */ fclose( psSHP->fpSHP ); fclose( psSHP->fpSHX ); free( psSHP->panRecOffset ); free( psSHP->panRecSize ); free( psSHP ); return( NULL ); } 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_CALLSHPClose(SHPHandle psSHP ){ if( psSHP == NULL ) return;/* -------------------------------------------------------------------- *//* 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_CALLSHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound ){ int i; if( psSHP == NULL ) return; 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 )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -