******************************************************************************
*
* $Log$
- * Revision 1.1 2001/07/18 21:42:12 pramsey
- * Initial add of the data loader code.
+ * Revision 1.2 2001/11/01 22:57:11 pramsey
+ * Updated shapelib files from latest CVS version.
+ *
+ * Revision 1.37 2001/07/04 05:18:09 warmerda
+ * do last fix properly
+ *
+ * Revision 1.36 2001/07/04 05:16:09 warmerda
+ * fixed fieldname comparison in DBFGetFieldIndex
+ *
+ * Revision 1.35 2001/06/22 02:10:06 warmerda
+ * fixed NULL shape support with help from Jim Matthews
+ *
+ * Revision 1.33 2001/05/31 19:20:13 warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.32 2001/05/31 18:15:40 warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.31 2001/05/23 13:36:52 warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.30 2000/12/05 14:43:38 warmerda
+ * DBReadAttribute() white space trimming bug fix
+ *
+ * Revision 1.29 2000/10/05 14:36:44 warmerda
+ * fix bug with writing very wide numeric fields
+ *
+ * Revision 1.28 2000/09/25 14:18:07 warmerda
+ * Added some casts of strlen() return result to fix warnings on some
+ * systems, as submitted by Daniel.
+ *
+ * Revision 1.27 2000/09/25 14:15:51 warmerda
+ * added DBFGetNativeFieldType()
+ *
+ * Revision 1.26 2000/07/07 13:39:45 warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.25 2000/05/29 18:19:13 warmerda
+ * avoid use of uchar, and adding casting fix
+ *
+ * Revision 1.24 2000/05/23 13:38:27 warmerda
+ * Added error checks on return results of fread() and fseek().
+ *
+ * Revision 1.23 2000/05/23 13:25:49 warmerda
+ * Avoid crashing if field or record are out of range in dbfread*attribute().
*
* Revision 1.22 1999/12/15 13:47:24 warmerda
* Added stdlib.h to ensure that atof() is prototyped.
#include <math.h>
#include <stdlib.h>
-
-typedef unsigned char uchar;
+#include <ctype.h>
+#include <string.h>
#ifndef FALSE
# define FALSE 0
static void DBFWriteHeader(DBFHandle psDBF)
{
- uchar abyHeader[XBASE_FLDHDR_SZ];
+ unsigned char abyHeader[XBASE_FLDHDR_SZ];
int i;
if( !psDBF->bNoHeader )
/* Open a .dbf file. */
/************************************************************************/
-DBFHandle DBFOpen( const char * pszFilename, const char * pszAccess )
+DBFHandle SHPAPI_CALL
+DBFOpen( const char * pszFilename, const char * pszAccess )
{
DBFHandle psDBF;
- uchar *pabyBuf;
+ unsigned char *pabyBuf;
int nFields, nRecords, nHeadLen, nRecLen, iField, i;
char *pszBasename, *pszFullname;
&& strcmp(pszAccess,"r+b") != 0 )
return( NULL );
+ if( strcmp(pszAccess,"r") == 0 )
+ pszAccess = "rb";
+
+ if( strcmp(pszAccess,"r+") == 0 )
+ pszAccess = "rb+";
+
/* -------------------------------------------------------------------- */
/* Compute the base (layer) name. If there is any extension */
/* on the passed in filename we will strip it off. */
/* -------------------------------------------------------------------- */
/* Read Table Header info */
/* -------------------------------------------------------------------- */
- pabyBuf = (uchar *) malloc(500);
+ pabyBuf = (unsigned char *) malloc(500);
fread( pabyBuf, 32, 1, psDBF->fp );
psDBF->nRecords = nRecords =
/* Read in Field Definitions */
/* -------------------------------------------------------------------- */
- pabyBuf = (uchar *) SfRealloc(pabyBuf,nHeadLen);
+ pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
psDBF->pszHeader = (char *) pabyBuf;
fseek( psDBF->fp, 32, 0 );
for( iField = 0; iField < nFields; iField++ )
{
- uchar *pabyFInfo;
+ unsigned char *pabyFInfo;
pabyFInfo = pabyBuf+iField*32;
/* DBFClose() */
/************************************************************************/
-void DBFClose(DBFHandle psDBF)
+void SHPAPI_CALL
+DBFClose(DBFHandle psDBF)
{
/* -------------------------------------------------------------------- */
/* Write out header if not already written. */
/* -------------------------------------------------------------------- */
if( psDBF->bUpdated )
{
- uchar abyFileHeader[32];
+ unsigned char abyFileHeader[32];
fseek( psDBF->fp, 0, 0 );
fread( abyFileHeader, 32, 1, psDBF->fp );
/* Create a new .dbf file. */
/************************************************************************/
-DBFHandle DBFCreate( const char * pszFilename )
+DBFHandle SHPAPI_CALL
+DBFCreate( const char * pszFilename )
{
DBFHandle psDBF;
/* are written. */
/************************************************************************/
-int DBFAddField(DBFHandle psDBF, const char * pszFieldName,
- DBFFieldType eType, int nWidth, int nDecimals )
+int SHPAPI_CALL
+DBFAddField(DBFHandle psDBF, const char * pszFieldName,
+ DBFFieldType eType, int nWidth, int nDecimals )
{
char *pszFInfo;
for( i = 0; i < 32; i++ )
pszFInfo[i] = '\0';
- if( strlen(pszFieldName) < 10 )
+ if( (int) strlen(pszFieldName) < 10 )
strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
else
strncpy( pszFInfo, pszFieldName, 10);
{
int nRecordOffset;
- uchar *pabyRec;
+ unsigned char *pabyRec;
void *pReturnField = NULL;
static double dDoubleField;
/* -------------------------------------------------------------------- */
-/* Have we read the record? */
+/* Verify selection. */
/* -------------------------------------------------------------------- */
if( hEntity < 0 || hEntity >= psDBF->nRecords )
return( NULL );
+ if( iField < 0 || iField >= psDBF->nFields )
+ return( NULL );
+
+/* -------------------------------------------------------------------- */
+/* Have we read the record? */
+/* -------------------------------------------------------------------- */
if( psDBF->nCurrentRecord != hEntity )
{
DBFFlushRecord( psDBF );
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
- fseek( psDBF->fp, nRecordOffset, 0 );
- fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
+ {
+ fprintf( stderr, "fseek(%d) failed on DBF file.\n",
+ nRecordOffset );
+ return NULL;
+ }
+
+ if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
+ 1, psDBF->fp ) != 1 )
+ {
+ fprintf( stderr, "fread(%d) failed on DBF file.\n",
+ psDBF->nRecordLength );
+ return NULL;
+ }
psDBF->nCurrentRecord = hEntity;
}
- pabyRec = (uchar *) psDBF->pszCurrentRecord;
+ pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
/* -------------------------------------------------------------------- */
/* Ensure our field buffer is large enough to hold this buffer. */
/* -------------------------------------------------------------------- */
/* Extract the requested field. */
/* -------------------------------------------------------------------- */
- strncpy( pszStringField, pabyRec+psDBF->panFieldOffset[iField],
+ strncpy( pszStringField,
+ ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
psDBF->panFieldSize[iField] );
pszStringField[psDBF->panFieldSize[iField]] = '\0';
*(pchDst++) = *(pchSrc++);
*pchDst = '\0';
- while( *(--pchDst) == ' ' && pchDst != pszStringField )
+ while( pchDst != pszStringField && *(--pchDst) == ' ' )
*pchDst = '\0';
-
}
#endif
/* Read an integer attribute. */
/************************************************************************/
-int DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
+int SHPAPI_CALL
+DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
{
double *pdValue;
pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
- return( (int) *pdValue );
+ if( pdValue == NULL )
+ return 0;
+ else
+ return( (int) *pdValue );
}
/************************************************************************/
/* Read a double attribute. */
/************************************************************************/
-double DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
+double SHPAPI_CALL
+DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
{
double *pdValue;
pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
- return( *pdValue );
+ if( pdValue == NULL )
+ return 0.0;
+ else
+ return( *pdValue );
}
/************************************************************************/
/* Read a string attribute. */
/************************************************************************/
-const char *DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
+const char SHPAPI_CALL1(*)
+DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
{
return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
}
+/************************************************************************/
+/* DBFIsAttributeNULL() */
+/* */
+/* Return TRUE if value for field is NULL. */
+/* */
+/* Contributed by Jim Matthews. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
+
+{
+ const char *pszValue;
+
+ pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+
+ switch(psDBF->pachFieldType[iField])
+ {
+ case 'N':
+ case 'F':
+ /* NULL numeric fields have value "****************" */
+ return pszValue[0] == '*';
+
+ case 'D':
+ /* NULL date fields have value "00000000" */
+ return strncmp(pszValue,"00000000",8) == 0;
+
+ case 'L':
+ /* NULL boolean fields have value "?" */
+ return pszValue[0] == '?';
+
+ default:
+ /* empty string fields are considered NULL */
+ return strlen(pszValue) == 0;
+ }
+ return FALSE;
+}
+
/************************************************************************/
/* DBFGetFieldCount() */
/* */
/* Return the number of fields in this table. */
/************************************************************************/
-int DBFGetFieldCount( DBFHandle psDBF )
+int SHPAPI_CALL
+DBFGetFieldCount( DBFHandle psDBF )
{
return( psDBF->nFields );
/* Return the number of records in this table. */
/************************************************************************/
-int DBFGetRecordCount( DBFHandle psDBF )
+int SHPAPI_CALL
+DBFGetRecordCount( DBFHandle psDBF )
{
return( psDBF->nRecords );
/* Return any requested information about the field. */
/************************************************************************/
-DBFFieldType DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
- int * pnWidth, int * pnDecimals )
+DBFFieldType SHPAPI_CALL
+DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
+ int * pnWidth, int * pnDecimals )
{
if( iField < 0 || iField >= psDBF->nFields )
{
int nRecordOffset, i, j;
- uchar *pabyRec;
- char szSField[40], szFormat[12];
+ unsigned char *pabyRec;
+ char szSField[400], szFormat[20];
/* -------------------------------------------------------------------- */
/* Is this a valid record? */
psDBF->pszCurrentRecord[i] = ' ';
psDBF->nCurrentRecord = hEntity;
-
}
/* -------------------------------------------------------------------- */
psDBF->nCurrentRecord = hEntity;
}
- pabyRec = (uchar *) psDBF->pszCurrentRecord;
+ pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+ psDBF->bCurrentRecordModified = TRUE;
+ psDBF->bUpdated = TRUE;
+
+/* -------------------------------------------------------------------- */
+/* Translate NULL value to valid DBF file representation. */
+/* */
+/* Contributed by Jim Matthews. */
+/* -------------------------------------------------------------------- */
+ if( pValue == NULL )
+ {
+ switch(psDBF->pachFieldType[iField])
+ {
+ case 'N':
+ case 'F':
+ /* NULL numeric fields have value "****************" */
+ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*',
+ psDBF->panFieldSize[iField] );
+ break;
+
+ case 'D':
+ /* NULL date fields have value "00000000" */
+ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0',
+ psDBF->panFieldSize[iField] );
+ break;
+
+ case 'L':
+ /* NULL boolean fields have value "?" */
+ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?',
+ psDBF->panFieldSize[iField] );
+ break;
+
+ default:
+ /* empty string fields are considered NULL */
+ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0',
+ psDBF->panFieldSize[iField] );
+ break;
+ }
+ return TRUE;
+ }
/* -------------------------------------------------------------------- */
/* Assign all the record fields. */
/* -------------------------------------------------------------------- */
- switch( psDBF->pachFieldType[iField] )
+ switch( psDBF->pachFieldType[iField] )
{
case 'D':
case 'N':
case 'F':
- if( psDBF->panFieldDecimals[iField] == 0 )
+ if( psDBF->panFieldDecimals[iField] == 0 )
{
- sprintf( szFormat, "%%%dd", psDBF->panFieldSize[iField] );
+ int nWidth = psDBF->panFieldSize[iField];
+
+ if( sizeof(szSField)-2 < nWidth )
+ nWidth = sizeof(szSField)-2;
+
+ sprintf( szFormat, "%%%dd", nWidth );
sprintf(szSField, szFormat, (int) *((double *) pValue) );
- if( strlen(szSField) > psDBF->panFieldSize[iField] )
+ if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
szSField[psDBF->panFieldSize[iField]] = '\0';
+
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
szSField, strlen(szSField) );
}
else
{
+ int nWidth = psDBF->panFieldSize[iField];
+
+ if( sizeof(szSField)-2 < nWidth )
+ nWidth = sizeof(szSField)-2;
+
sprintf( szFormat, "%%%d.%df",
- psDBF->panFieldSize[iField],
- psDBF->panFieldDecimals[iField] );
+ nWidth, psDBF->panFieldDecimals[iField] );
sprintf(szSField, szFormat, *((double *) pValue) );
- if( strlen(szSField) > psDBF->panFieldSize[iField] )
+ if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
szSField[psDBF->panFieldSize[iField]] = '\0';
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
szSField, strlen(szSField) );
}
-
break;
default:
- if( strlen((char *) pValue) > psDBF->panFieldSize[iField] )
+ if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
j = psDBF->panFieldSize[iField];
else
{
break;
}
- psDBF->bCurrentRecordModified = TRUE;
- psDBF->bUpdated = TRUE;
-
return( TRUE );
}
/* Write a double attribute. */
/************************************************************************/
-int DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
- double dValue )
+int SHPAPI_CALL
+DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
+ double dValue )
{
return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
/* Write a integer attribute. */
/************************************************************************/
-int DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
- int nValue )
+int SHPAPI_CALL
+DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
+ int nValue )
{
double dValue = nValue;
/* Write a string attribute. */
/************************************************************************/
-int DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
- const char * pszValue )
+int SHPAPI_CALL
+DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
+ const char * pszValue )
{
return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) );
}
+/************************************************************************/
+/* DBFWriteNULLAttribute() */
+/* */
+/* Write a string attribute. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+ return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) );
+}
+
/************************************************************************/
/* DBFWriteTuple() */
/* */
/* Write an attribute record to the file. */
/************************************************************************/
-int DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
+int SHPAPI_CALL
+DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
{
int nRecordOffset, i;
- uchar *pabyRec;
+ unsigned char *pabyRec;
/* -------------------------------------------------------------------- */
/* Is this a valid record? */
psDBF->nCurrentRecord = hEntity;
}
- pabyRec = (uchar *) psDBF->pszCurrentRecord;
+ pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength );
/* Read one of the attribute fields of a record. */
/************************************************************************/
-const char *DBFReadTuple(DBFHandle psDBF, int hEntity )
+const char SHPAPI_CALL1(*)
+DBFReadTuple(DBFHandle psDBF, int hEntity )
{
int nRecordOffset;
- uchar *pabyRec;
+ unsigned char *pabyRec;
static char *pReturnTuple = NULL;
static int nTupleLen = 0;
psDBF->nCurrentRecord = hEntity;
}
- pabyRec = (uchar *) psDBF->pszCurrentRecord;
+ pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
if ( nTupleLen < psDBF->nRecordLength) {
nTupleLen = psDBF->nRecordLength;
/* Read one of the attribute fields of a record. */
/************************************************************************/
-DBFHandle DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
+DBFHandle SHPAPI_CALL
+DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
{
DBFHandle newDBF;
return ( newDBF );
}
+
+/************************************************************************/
+/* DBFGetNativeFieldType() */
+/* */
+/* Return the DBase field type for the specified field. */
+/* */
+/* Value can be one of: 'C' (String), 'D' (Date), 'F' (Float), */
+/* 'N' (Numeric, with or without decimal), */
+/* 'L' (Logical), */
+/* 'M' (Memo: 10 digits .DBT block ptr) */
+/************************************************************************/
+
+char SHPAPI_CALL
+DBFGetNativeFieldType( DBFHandle psDBF, int iField )
+
+{
+ if( iField >=0 && iField < psDBF->nFields )
+ return psDBF->pachFieldType[iField];
+
+ return ' ';
+}
+
+/************************************************************************/
+/* str_to_upper() */
+/************************************************************************/
+
+static void str_to_upper (char *string)
+{
+ int len;
+ short i = -1;
+
+ len = strlen (string);
+
+ while (++i < len)
+ if (isalpha(string[i]) && islower(string[i]))
+ string[i] = toupper ((int)string[i]);
+}
+
+/************************************************************************/
+/* DBFGetFieldIndex() */
+/* */
+/* Get the index number for a field in a .dbf file. */
+/* */
+/* Contributed by Jim Matthews. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
+
+{
+ char name[12], name1[12], name2[12];
+ int i;
+
+ strncpy(name1, pszFieldName,11);
+ str_to_upper(name1);
+
+ for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
+ {
+ DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
+ strncpy(name2,name,11);
+ str_to_upper(name2);
+
+ if(!strncmp(name1,name2,10))
+ return(i);
+ }
+ return(-1);
+}
******************************************************************************
*
* $Log$
- * Revision 1.1 2001/07/18 21:42:12 pramsey
- * Initial add of the data loader code.
+ * Revision 1.2 2001/11/01 22:57:11 pramsey
+ * Updated shapelib files from latest CVS version.
+ *
+ * Revision 1.21 2001/11/01 16:29:55 warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.20 2001/07/20 13:06:02 warmerda
+ * fixed SHPAPI attribute for SHPTreeFindLikelyShapes
+ *
+ * Revision 1.19 2001/05/31 19:20:13 warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.18 2001/05/31 18:15:40 warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.17 2001/05/23 13:36:52 warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.16 2000/09/25 14:15:59 warmerda
+ * added DBFGetNativeFieldType()
*
* Revision 1.15 2000/02/16 16:03:51 warmerda
* added null shape support
#ifdef __cplusplus
extern "C" {
#endif
+
+#ifndef SHPAPI_CALL
+#define SHPAPI_CALL
+#endif
+
+#define SHPAPI_CALL1(x) * SHPAPI_CALL
/************************************************************************/
/* Configuration options. */
double adBoundsMax[4];
int bUpdated;
+
+ unsigned char *pabyRec;
+ int nBufSize;
} SHPInfo;
typedef SHPInfo * SHPHandle;
/* -------------------------------------------------------------------- */
/* SHP API Prototypes */
/* -------------------------------------------------------------------- */
-SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
-SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
-void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
- double * padfMinBound, double * padfMaxBound );
-
-SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
-int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
-
-void SHPDestroyObject( SHPObject * psObject );
-void SHPComputeExtents( SHPObject * psObject );
-SHPObject *SHPCreateObject( int nSHPType, int nShapeId,
- int nParts, int * panPartStart, int * panPartType,
- int nVertices, double * padfX, double * padfY,
- double * padfZ, double * padfM );
-SHPObject *SHPCreateSimpleObject( int nSHPType, int nVertices,
- double * padfX, double * padfY, double * padfZ );
-
-void SHPClose( SHPHandle hSHP );
-
-const char *SHPTypeName( int nSHPType );
-const char *SHPPartTypeName( int nPartType );
+SHPHandle SHPAPI_CALL
+ SHPOpen( const char * pszShapeFile, const char * pszAccess );
+SHPHandle SHPAPI_CALL
+ SHPCreate( const char * pszShapeFile, int nShapeType );
+void SHPAPI_CALL
+ SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
+ double * padfMinBound, double * padfMaxBound );
+
+SHPObject SHPAPI_CALL1(*)
+ SHPReadObject( SHPHandle hSHP, int iShape );
+int SHPAPI_CALL
+ SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
+
+void SHPAPI_CALL
+ SHPDestroyObject( SHPObject * psObject );
+void SHPAPI_CALL
+ SHPComputeExtents( SHPObject * psObject );
+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 SHPAPI_CALL1(*)
+ SHPCreateSimpleObject( int nSHPType, int nVertices,
+ double * padfX, double * padfY, double * padfZ );
+
+void SHPAPI_CALL
+ SHPClose( SHPHandle hSHP );
+
+const char SHPAPI_CALL1(*)
+ SHPTypeName( int nSHPType );
+const char SHPAPI_CALL1(*)
+ SHPPartTypeName( int nPartType );
/* -------------------------------------------------------------------- */
/* Shape quadtree indexing API. */
SHPTreeNode *psRoot;
} SHPTree;
-SHPTree *SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
- double *padfBoundsMin, double *padfBoundsMax );
-void SHPDestroyTree( SHPTree * hTree );
-
-int SHPWriteTree( SHPTree *hTree, const char * pszFilename );
-SHPTree SHPReadTree( const char * pszFilename );
-
-int SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
-int SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
-int SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
-
-void SHPTreeTrimExtraNodes( SHPTree * hTree );
-
-int *SHPTreeFindLikelyShapes( SHPTree * hTree,
- double * padfBoundsMin,
- double * padfBoundsMax,
- int * );
-int SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
+SHPTree SHPAPI_CALL1(*)
+ SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+ double *padfBoundsMin, double *padfBoundsMax );
+void SHPAPI_CALL
+ SHPDestroyTree( SHPTree * hTree );
+
+int SHPAPI_CALL
+ SHPWriteTree( SHPTree *hTree, const char * pszFilename );
+SHPTree SHPAPI_CALL
+ SHPReadTree( const char * pszFilename );
+
+int SHPAPI_CALL
+ SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
+int SHPAPI_CALL
+ SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
+int SHPAPI_CALL
+ SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
+
+void SHPAPI_CALL
+ SHPTreeTrimExtraNodes( SHPTree * hTree );
+
+int SHPAPI_CALL1(*)
+ SHPTreeFindLikelyShapes( SHPTree * hTree,
+ double * padfBoundsMin,
+ double * padfBoundsMax,
+ int * );
+int SHPAPI_CALL
+ SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
/************************************************************************/
/* DBF Support. */
FTString,
FTInteger,
FTDouble,
- FTInvalid,
+ FTInvalid
} DBFFieldType;
#define XBASE_FLDHDR_SZ 32
-DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );
-DBFHandle DBFCreate( const char * pszDBFFile );
-
-int DBFGetFieldCount( DBFHandle psDBF );
-int DBFGetRecordCount( DBFHandle psDBF );
-int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
- DBFFieldType eType, int nWidth, int nDecimals );
-
-DBFFieldType DBFGetFieldInfo( DBFHandle psDBF, int iField,
- char * pszFieldName,
- int * pnWidth, int * pnDecimals );
-
-int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
-double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
-const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
-
-int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
- int nFieldValue );
-int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
- double dFieldValue );
-int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
- const char * pszFieldValue );
-
-const char *DBFReadTuple(DBFHandle psDBF, int hEntity );
-int DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
-
-DBFHandle DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
+DBFHandle SHPAPI_CALL
+ DBFOpen( const char * pszDBFFile, const char * pszAccess );
+DBFHandle SHPAPI_CALL
+ DBFCreate( const char * pszDBFFile );
+
+int SHPAPI_CALL
+ DBFGetFieldCount( DBFHandle psDBF );
+int SHPAPI_CALL
+ DBFGetRecordCount( DBFHandle psDBF );
+int SHPAPI_CALL
+ DBFAddField( DBFHandle hDBF, const char * pszFieldName,
+ DBFFieldType eType, int nWidth, int nDecimals );
+
+DBFFieldType SHPAPI_CALL
+ DBFGetFieldInfo( DBFHandle psDBF, int iField,
+ char * pszFieldName, int * pnWidth, int * pnDecimals );
+
+int SHPAPI_CALL
+ DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
+
+int SHPAPI_CALL
+ DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
+double SHPAPI_CALL
+ DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
+const char SHPAPI_CALL1(*)
+ DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
+int SHPAPI_CALL
+ DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
+
+int SHPAPI_CALL
+ DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
+ int nFieldValue );
+int SHPAPI_CALL
+ DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
+ double dFieldValue );
+int SHPAPI_CALL
+ DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
+ const char * pszFieldValue );
+int SHPAPI_CALL
+ DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
+
+const char SHPAPI_CALL1(*)
+ DBFReadTuple(DBFHandle psDBF, int hEntity );
+int SHPAPI_CALL
+ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
+
+DBFHandle SHPAPI_CALL
+ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
-void DBFClose( DBFHandle hDBF );
+void SHPAPI_CALL
+ DBFClose( DBFHandle hDBF );
+char SHPAPI_CALL
+ DBFGetNativeFieldType( DBFHandle hDBF, int iField );
#ifdef __cplusplus
}
*
* Project: Shapelib
* Purpose: Implementation of core Shapefile read/write functions.
- * Author: Frank Warmerdam, warmerda@home.com
+ * Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
- * Copyright (c) 1999, Frank Warmerdam
+ * Copyright (c) 1999, 2001, Frank Warmerdam
*
* This software is available under the following "MIT Style" license,
* or at the option of the licensee under the LGPL (see LICENSE.LGPL). This
******************************************************************************
*
* $Log$
- * Revision 1.1 2001/07/18 21:42:12 pramsey
- * Initial add of the data loader code.
+ * Revision 1.2 2001/11/01 22:57:11 pramsey
+ * Updated shapelib files from latest CVS version.
+ *
+ * Revision 1.34 2001/11/01 16:29:55 warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.33 2001/07/03 12:18:15 warmerda
+ * Improved cleanup if SHX not found, provied by Riccardo Cohen.
+ *
+ * Revision 1.32 2001/06/22 01:58:07 warmerda
+ * be more careful about establishing initial bounds in face of NULL shapes
+ *
+ * Revision 1.31 2001/05/31 19:35:29 warmerda
+ * added support for writing null shapes
+ *
+ * Revision 1.30 2001/05/28 12:46:29 warmerda
+ * Add some checking on reasonableness of record count when opening.
+ *
+ * Revision 1.29 2001/05/23 13:36:52 warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.28 2001/02/06 22:25:06 warmerda
+ * fixed memory leaks when SHPOpen() fails
+ *
+ * Revision 1.27 2000/07/18 15:21:33 warmerda
+ * added better enforcement of -1 for append in SHPWriteObject
*
* Revision 1.26 2000/02/16 16:03:51 warmerda
* added null shape support
#include <limits.h>
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
typedef unsigned char uchar;
#endif
static int bBigEndian;
-static uchar *pabyRec = NULL;
-static int nBufSize = 0;
/************************************************************************/
/* files or either file name. */
/************************************************************************/
-SHPHandle SHPOpen( const char * pszLayer, const char * pszAccess )
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
{
char *pszFullname, *pszBasename;
/* -------------------------------------------------------------------- */
/* Initialize the info structure. */
/* -------------------------------------------------------------------- */
- psSHP = (SHPHandle) malloc(sizeof(SHPInfo));
+ psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
psSHP->bUpdated = FALSE;
}
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 )
+ {
+ fclose( psSHP->fpSHX );
+ free( psSHP );
+ free( pszBasename );
+ free( pszFullname );
return( NULL );
+ }
free( pszFullname );
free( pszBasename );
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. */
/* -------------------------------------------------------------------- */
/* Close the .shp and .shx files. */
/************************************************************************/
-void SHPClose(SHPHandle psSHP )
+void SHPAPI_CALL
+SHPClose(SHPHandle psSHP )
{
/* -------------------------------------------------------------------- */
fclose( psSHP->fpSHX );
fclose( psSHP->fpSHP );
- free( psSHP );
-
- if( pabyRec != NULL )
+ if( psSHP->pabyRec != NULL )
{
- free( pabyRec );
- pabyRec = NULL;
- nBufSize = 0;
+ free( psSHP->pabyRec );
}
+
+ free( psSHP );
}
/************************************************************************/
/* Fetch general information about the shape file. */
/************************************************************************/
-void SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
- double * padfMinBound, double * padfMaxBound )
+void SHPAPI_CALL
+SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
+ double * padfMinBound, double * padfMaxBound )
{
int i;
/* shape file with read/write access. */
/************************************************************************/
-SHPHandle SHPCreate( const char * pszLayer, int nShapeType )
+SHPHandle SHPAPI_CALL
+SHPCreate( const char * pszLayer, int nShapeType )
{
char *pszBasename, *pszFullname;
/* SHPCreateObject(). */
/************************************************************************/
-void SHPComputeExtents( SHPObject * psObject )
+void SHPAPI_CALL
+SHPComputeExtents( SHPObject * psObject )
{
int i;
/* SHPDestroyObject(). */
/************************************************************************/
-SHPObject *SHPCreateObject( int nSHPType, int nShapeId, int nParts,
- int * panPartStart, int * panPartType,
- int nVertices, double * padfX, double * padfY,
- double * padfZ, double * padfM )
+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;
/* Capture vertices. Note that Z and M are optional, but X and */
/* Y are not. */
/* -------------------------------------------------------------------- */
- 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);
+ 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 );
+ 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];
+ 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 );
/* SHPDestroyObject(). */
/************************************************************************/
-SHPObject *SHPCreateSimpleObject( int nSHPType, int nVertices,
- double * padfX, double * padfY,
- double * padfZ )
+SHPObject SHPAPI_CALL1(*)
+SHPCreateSimpleObject( int nSHPType, int nVertices,
+ double * padfX, double * padfY,
+ double * padfZ )
{
return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
/* only possible to write vertices at the end of the file. */
/************************************************************************/
-int SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
+int SHPAPI_CALL
+SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
{
int nRecordOffset, i, nRecordSize;
/* Ensure that shape object matches the type of the file it is */
/* being written to. */
/* -------------------------------------------------------------------- */
- assert( psObject->nSHPType == psSHP->nShapeType );
+ 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. */
psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
psSHP->panRecOffset = (int *)
- SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
+ SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
psSHP->panRecSize = (int *)
- SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
+ SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
}
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* Extract vertices for a Polygon or Arc. */
/* -------------------------------------------------------------------- */
- if( psSHP->nShapeType == SHPT_POLYGON
- || psSHP->nShapeType == SHPT_POLYGONZ
- || psSHP->nShapeType == SHPT_POLYGONM
- || psSHP->nShapeType == SHPT_ARC
- || psSHP->nShapeType == SHPT_ARCZ
- || psSHP->nShapeType == SHPT_ARCM
- || psSHP->nShapeType == SHPT_MULTIPATCH )
+ 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;
/*
* Write multipatch part types if needed.
*/
- if( psSHP->nShapeType == SHPT_MULTIPATCH )
+ if( psObject->nSHPType == SHPT_MULTIPATCH )
{
memcpy( pabyRec + nRecordSize, psObject->panPartType,
4*psObject->nParts );
/*
* Write the Z coordinates (if any).
*/
- if( psSHP->nShapeType == SHPT_POLYGONZ
- || psSHP->nShapeType == SHPT_ARCZ
- || psSHP->nShapeType == SHPT_MULTIPATCH )
+ 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 );
/*
* Write the M values, if any.
*/
- if( psSHP->nShapeType == SHPT_POLYGONM
- || psSHP->nShapeType == SHPT_ARCM
+ if( psObject->nSHPType == SHPT_POLYGONM
+ || psObject->nSHPType == SHPT_ARCM
#ifndef DISABLE_MULTIPATCH_MEASURE
- || psSHP->nShapeType == SHPT_MULTIPATCH
+ || psObject->nSHPType == SHPT_MULTIPATCH
#endif
- || psSHP->nShapeType == SHPT_POLYGONZ
- || psSHP->nShapeType == SHPT_ARCZ )
+ || psObject->nSHPType == SHPT_POLYGONZ
+ || psObject->nSHPType == SHPT_ARCZ )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
/* -------------------------------------------------------------------- */
/* Extract vertices for a MultiPoint. */
/* -------------------------------------------------------------------- */
- else if( psSHP->nShapeType == SHPT_MULTIPOINT
- || psSHP->nShapeType == SHPT_MULTIPOINTZ
- || psSHP->nShapeType == SHPT_MULTIPOINTM )
+ else if( psObject->nSHPType == SHPT_MULTIPOINT
+ || psObject->nSHPType == SHPT_MULTIPOINTZ
+ || psObject->nSHPType == SHPT_MULTIPOINTM )
{
int32 nPoints;
int i;
nRecordSize = 48 + 16 * psObject->nVertices;
- if( psSHP->nShapeType == SHPT_MULTIPOINTZ )
+ if( psObject->nSHPType == SHPT_MULTIPOINTZ )
{
ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
}
}
- if( psSHP->nShapeType == SHPT_MULTIPOINTZ
- || psSHP->nShapeType == SHPT_MULTIPOINTM )
+ if( psObject->nSHPType == SHPT_MULTIPOINTZ
+ || psObject->nSHPType == SHPT_MULTIPOINTM )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
}
/* -------------------------------------------------------------------- */
-/* Extract vertices for a point. */
+/* Write point. */
/* -------------------------------------------------------------------- */
- else if( psSHP->nShapeType == SHPT_POINT
- || psSHP->nShapeType == SHPT_POINTZ
- || psSHP->nShapeType == SHPT_POINTM )
+ 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 );
nRecordSize = 28;
- if( psSHP->nShapeType == SHPT_POINTZ )
+ if( psObject->nSHPType == SHPT_POINTZ )
{
ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
nRecordSize += 8;
}
- if( psSHP->nShapeType == SHPT_POINTZ
- || psSHP->nShapeType == SHPT_POINTM )
+ if( psObject->nSHPType == SHPT_POINTZ
+ || psObject->nSHPType == SHPT_POINTM )
{
ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
}
}
+/* -------------------------------------------------------------------- */
+/* Not much to do for null geometries. */
+/* -------------------------------------------------------------------- */
+ else if( psObject->nSHPType == SHPT_NULL )
+ {
+ nRecordSize = 12;
+ }
+
else
{
/* unknown type */
if( !bBigEndian ) SwapWord( 4, &i32 );
ByteCopy( &i32, pabyRec + 4, 4 );
- i32 = psSHP->nShapeType; /* shape type */
+ i32 = psObject->nSHPType; /* shape type */
if( bBigEndian ) SwapWord( 4, &i32 );
ByteCopy( &i32, pabyRec + 8, 4 );
/* -------------------------------------------------------------------- */
/* Expand file wide bounds based on this shape. */
/* -------------------------------------------------------------------- */
- if( psSHP->nRecords == 1 )
+ 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];
+ 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++ )
/* for one shape. */
/************************************************************************/
-SHPObject *SHPReadObject( SHPHandle psSHP, int hEntity )
+SHPObject SHPAPI_CALL1(*)
+SHPReadObject( SHPHandle psSHP, int hEntity )
{
SHPObject *psShape;
/* -------------------------------------------------------------------- */
/* Ensure our record buffer is large enough. */
/* -------------------------------------------------------------------- */
- if( psSHP->panRecSize[hEntity]+8 > nBufSize )
+ if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
{
- nBufSize = psSHP->panRecSize[hEntity]+8;
- pabyRec = (uchar *) SfRealloc(pabyRec,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( pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );
+ 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, pabyRec + 8, 4 );
+ memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
/* ==================================================================== */
/* -------------------------------------------------------------------- */
/* Get the X/Y bounds. */
/* -------------------------------------------------------------------- */
- memcpy( &(psShape->dfXMin), pabyRec + 8 + 4, 8 );
- memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 );
- memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 );
- memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 );
+ 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) );
/* Extract part/point count, and build vertex and part arrays */
/* to proper size. */
/* -------------------------------------------------------------------- */
- memcpy( &nPoints, pabyRec + 40 + 8, 4 );
- memcpy( &nParts, pabyRec + 36 + 8, 4 );
+ memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
+ memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
if( bBigEndian ) SwapWord( 4, &nPoints );
if( bBigEndian ) SwapWord( 4, &nParts );
/* -------------------------------------------------------------------- */
/* Copy out the part array from the record. */
/* -------------------------------------------------------------------- */
- memcpy( psShape->panPartStart, pabyRec + 44 + 8, 4 * nParts );
+ memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
for( i = 0; i < nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
/* -------------------------------------------------------------------- */
if( psShape->nSHPType == SHPT_MULTIPATCH )
{
- memcpy( psShape->panPartType, pabyRec + nOffset, 4*nParts );
+ memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
for( i = 0; i < nParts; i++ )
{
if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
for( i = 0; i < nPoints; i++ )
{
memcpy(psShape->padfX + i,
- pabyRec + nOffset + i * 16,
+ psSHP->pabyRec + nOffset + i * 16,
8 );
memcpy(psShape->padfY + i,
- pabyRec + nOffset + i * 16 + 8,
+ psSHP->pabyRec + nOffset + i * 16 + 8,
8 );
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
|| psShape->nSHPType == SHPT_ARCZ
|| psShape->nSHPType == SHPT_MULTIPATCH )
{
- memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 );
- memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 );
+ memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+ memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
for( i = 0; i < nPoints; i++ )
{
memcpy( psShape->padfZ + i,
- pabyRec + nOffset + 16 + i*8, 8 );
+ psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
}
/* -------------------------------------------------------------------- */
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
{
- memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 );
- memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 );
+ memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+ memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
for( i = 0; i < nPoints; i++ )
{
memcpy( psShape->padfM + i,
- pabyRec + nOffset + 16 + i*8, 8 );
+ psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
}
}
int32 nPoints;
int i, nOffset;
- memcpy( &nPoints, pabyRec + 44, 4 );
+ memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
if( bBigEndian ) SwapWord( 4, &nPoints );
psShape->nVertices = nPoints;
for( i = 0; i < nPoints; i++ )
{
- memcpy(psShape->padfX+i, pabyRec + 48 + 16 * i, 8 );
- memcpy(psShape->padfY+i, pabyRec + 48 + 16 * i + 8, 8 );
+ memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
+ memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
/* -------------------------------------------------------------------- */
/* Get the X/Y bounds. */
/* -------------------------------------------------------------------- */
- memcpy( &(psShape->dfXMin), pabyRec + 8 + 4, 8 );
- memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 );
- memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 );
- memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 );
+ 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( psShape->nSHPType == SHPT_MULTIPOINTZ )
{
- memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 );
- memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 );
+ memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+ memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
for( i = 0; i < nPoints; i++ )
{
memcpy( psShape->padfZ + i,
- pabyRec + nOffset + 16 + i*8, 8 );
+ psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
}
/* -------------------------------------------------------------------- */
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
{
- memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 );
- memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 );
+ memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+ memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
for( i = 0; i < nPoints; i++ )
{
memcpy( psShape->padfM + i,
- pabyRec + nOffset + 16 + i*8, 8 );
+ psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
}
}
psShape->padfZ = (double *) calloc(1,sizeof(double));
psShape->padfM = (double *) calloc(1,sizeof(double));
- memcpy( psShape->padfX, pabyRec + 12, 8 );
- memcpy( psShape->padfY, pabyRec + 20, 8 );
+ memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
+ memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfX );
if( bBigEndian ) SwapWord( 8, psShape->padfY );
/* -------------------------------------------------------------------- */
if( psShape->nSHPType == SHPT_POINTZ )
{
- memcpy( psShape->padfZ, pabyRec + nOffset, 8 );
+ memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfZ );
/* -------------------------------------------------------------------- */
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
{
- memcpy( psShape->padfM, pabyRec + nOffset, 8 );
+ memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM );
}
/* SHPTypeName() */
/************************************************************************/
-const char *SHPTypeName( int nSHPType )
+const char SHPAPI_CALL1(*)
+SHPTypeName( int nSHPType )
{
switch( nSHPType )
{
- case 0:
+ case SHPT_NULL:
return "NullShape";
case SHPT_POINT:
/* SHPPartTypeName() */
/************************************************************************/
-const char *SHPPartTypeName( int nPartType )
+const char SHPAPI_CALL1(*)
+SHPPartTypeName( int nPartType )
{
switch( nPartType )
/* SHPDestroyObject() */
/************************************************************************/
-void SHPDestroyObject( SHPObject * psShape )
+void SHPAPI_CALL
+SHPDestroyObject( SHPObject * psShape )
{
if( psShape == NULL )