]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
move shapelib to sep. lib (cmake errors)
authorisn <isn@opencascade.com>
Fri, 26 Jun 2015 09:17:37 +0000 (12:17 +0300)
committerisn <isn@opencascade.com>
Fri, 26 Jun 2015 09:17:37 +0000 (12:17 +0300)
12 files changed:
CMakeLists.txt
src/HYDROData/CMakeLists.txt
src/HYDROData/shapelib/dbfopen.c [deleted file]
src/HYDROData/shapelib/safileio.c [deleted file]
src/HYDROData/shapelib/shapefil.h [deleted file]
src/HYDROData/shapelib/shpopen.c [deleted file]
src/HYDROData/shapelib/shptree.c [deleted file]
src/HYDROData/shapelib/shputils.c [deleted file]
src/HYDROGUI/CMakeLists.txt
src/HYDROGUI/HYDROGUI_ExportFileOp.h
src/HYDROGUI/HYDROGUI_ImportLandCoverOp.h
src/HYDROGUI/HYDROGUI_ImportPolylineOp.h

index a66ea3848dae70be3a5ff192c96f9419920455b5..7be94504dbe530c532f8f8594fee930e207f6ce0 100644 (file)
@@ -172,6 +172,7 @@ MARK_AS_ADVANCED(
 
 # Sources 
 # ========
+ADD_SUBDIRECTORY (src/shapelib)
 ADD_SUBDIRECTORY (src/HYDROData)
 ADD_SUBDIRECTORY (src/HYDROGUI)
 ADD_SUBDIRECTORY (src/HYDROPy)
index 05da2c6777b6dff5eb2f439443a69334e3d488c7..36dcd976e02e65cc6ff73abd13cbfd7aee82d3a4 100644 (file)
@@ -54,7 +54,6 @@ set(PROJECT_HEADERS
     HYDROData_LinearInterpolator.h
     HYDROData_InterpolatorsFactory.h
     HYDROData_SinusX.h
-    shapelib/shapefil.h
 )
 
 set(PROJECT_SOURCES 
@@ -109,12 +108,7 @@ set(PROJECT_SOURCES
     HYDROData_LinearInterpolator.cxx
     HYDROData_InterpolatorsFactory.cxx
     HYDROData_SinusX.cxx
-    shapelib/dbfopen.c
-    shapelib/safileio.c
-    shapelib/shpopen.c
-    shapelib/shptree.c
-    shapelib/shputils.c
-)
+ )
 
 add_definitions(
   -DHYDRODATA_EXPORTS
@@ -132,6 +126,7 @@ include_directories(
   ${CMAKE_CURRENT_SOURCE_DIR}
 #  ${GUI_ROOT_DIR}/include/salome
   ${GUI_INCLUDE_DIRS}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../shapelib
 )
 
 add_library(HYDROData SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
@@ -140,7 +135,7 @@ target_link_libraries(HYDROData ${GEOM_GEOMUtils} ${CAS_OCAF} ${CAS_OCAFVIS} ${C
                       ${QT_LIBRARIES} ${GUI_ImageComposer} ${CAS_TKHLR} ${GEOM_GEOM} ${GEOM_GEOMBase} ${GEOM_CurveCreator} )
 INSTALL(TARGETS HYDROData EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
 
-set(PROJECT_LIBRARIES HYDROData)
+set(PROJECT_LIBRARIES shapelib HYDROData)
 
 # tests
 if(SALOME_BUILD_TESTS)
diff --git a/src/HYDROData/shapelib/dbfopen.c b/src/HYDROData/shapelib/dbfopen.c
deleted file mode 100644 (file)
index fbe7b06..0000000
+++ /dev/null
@@ -1,2221 +0,0 @@
-/******************************************************************************
- * $Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $
- *
- * Project:  Shapelib
- * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
- * Author:   Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 1999, 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: dbfopen.c,v $
- * Revision 1.89  2011-07-24 05:59:25  fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.88  2011-05-13 17:35:17  fwarmerdam
- * added DBFReorderFields() and DBFAlterFields() functions (from Even)
- *
- * Revision 1.87  2011-05-07 22:41:02  fwarmerdam
- * ensure pending record is flushed when adding a native field (GDAL #4073)
- *
- * Revision 1.86  2011-04-17 15:15:29  fwarmerdam
- * Removed unused variable.
- *
- * Revision 1.85  2010-12-06 16:09:34  fwarmerdam
- * fix buffer read overrun fetching code page (bug 2276)
- *
- * Revision 1.84  2009-10-29 19:59:48  fwarmerdam
- * avoid crash on truncated header (gdal #3093)
- *
- * Revision 1.83  2008/11/12 14:28:15  fwarmerdam
- * DBFCreateField() now works on files with records
- *
- * Revision 1.82  2008/11/11 17:47:09  fwarmerdam
- * added DBFDeleteField() function
- *
- * Revision 1.81  2008/01/03 17:48:13  bram
- * in DBFCreate, use default code page LDID/87 (= 0x57, ANSI)
- * instead of LDID/3.  This seems to be the same as what ESRI
- * would be doing by default.
- *
- * Revision 1.80  2007/12/30 14:36:39  fwarmerdam
- * avoid syntax issue with last comment.
- *
- * Revision 1.79  2007/12/30 14:35:48  fwarmerdam
- * Avoid char* / unsigned char* warnings.
- *
- * Revision 1.78  2007/12/18 18:28:07  bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.77  2007/12/15 20:25:21  bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function.  This is 
- * either the number from the LDID header field ("LDID/<number>") or as the 
- * content of an accompanying .CPG file.  When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.76  2007/12/12 22:21:32  bram
- * DBFClose: check for NULL psDBF handle before trying to close it.
- *
- * Revision 1.75  2007/12/06 13:58:19  fwarmerdam
- * make sure file offset calculations are done in as SAOffset
- *
- * Revision 1.74  2007/12/06 07:00:25  fwarmerdam
- * dbfopen now using SAHooks for fileio
- *
- * Revision 1.73  2007/09/03 19:48:11  fwarmerdam
- * move DBFReadAttribute() static dDoubleField into dbfinfo
- *
- * Revision 1.72  2007/09/03 19:34:06  fwarmerdam
- * Avoid use of static tuple buffer in DBFReadTuple()
- *
- * Revision 1.71  2006/06/22 14:37:18  fwarmerdam
- * avoid memory leak if dbfopen fread fails
- *
- * Revision 1.70  2006/06/17 17:47:05  fwarmerdam
- * use calloc() for dbfinfo in DBFCreate
- *
- * Revision 1.69  2006/06/17 15:34:32  fwarmerdam
- * disallow creating fields wider than 255
- *
- * Revision 1.68  2006/06/17 15:12:40  fwarmerdam
- * Fixed C++ style comments.
- *
- * Revision 1.67  2006/06/17 00:24:53  fwarmerdam
- * Don't treat non-zero decimals values as high order byte for length
- * for strings.  It causes serious corruption for some files.
- * http://bugzilla.remotesensing.org/show_bug.cgi?id=1202
- *
- * Revision 1.66  2006/03/29 18:26:20  fwarmerdam
- * fixed bug with size of pachfieldtype in dbfcloneempty
- *
- * Revision 1.65  2006/02/15 01:14:30  fwarmerdam
- * added DBFAddNativeFieldType
- *
- * Revision 1.64  2006/02/09 00:29:04  fwarmerdam
- * Changed to put spaces into string fields that are NULL as
- * per http://bugzilla.maptools.org/show_bug.cgi?id=316.
- *
- * Revision 1.63  2006/01/25 15:35:43  fwarmerdam
- * check success on DBFFlushRecord
- *
- * Revision 1.62  2006/01/10 16:28:03  fwarmerdam
- * Fixed typo in CPLError.
- *
- * Revision 1.61  2006/01/10 16:26:29  fwarmerdam
- * Push loading record buffer into DBFLoadRecord.
- * Implement CPL error reporting if USE_CPL defined.
- *
- * Revision 1.60  2006/01/05 01:27:27  fwarmerdam
- * added dbf deletion mark/fetch
- *
- * Revision 1.59  2005/03/14 15:20:28  fwarmerdam
- * Fixed last change.
- *
- * Revision 1.58  2005/03/14 15:18:54  fwarmerdam
- * Treat very wide fields with no decimals as double.  This is
- * more than 32bit integer fields.
- *
- * Revision 1.57  2005/02/10 20:16:54  fwarmerdam
- * Make the pszStringField buffer for DBFReadAttribute() static char [256]
- * as per bug 306.
- *
- * Revision 1.56  2005/02/10 20:07:56  fwarmerdam
- * Fixed bug 305 in DBFCloneEmpty() - header length problem.
- *
- * Revision 1.55  2004/09/26 20:23:46  fwarmerdam
- * avoid warnings with rcsid and signed/unsigned stuff
- *
- * Revision 1.54  2004/09/15 16:26:10  fwarmerdam
- * Treat all blank numeric fields as null too.
- */
-
-#include "shapefil.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-SHP_CVSID("$Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $")
-
-#ifndef FALSE
-#  define FALSE                0
-#  define TRUE         1
-#endif
-
-/************************************************************************/
-/*                             SfRealloc()                              */
-/*                                                                      */
-/*      A realloc cover function that will access a NULL pointer as     */
-/*      a valid input.                                                  */
-/************************************************************************/
-
-static void * SfRealloc( void * pMem, int nNewSize )
-
-{
-    if( pMem == NULL )
-        return( (void *) malloc(nNewSize) );
-    else
-        return( (void *) realloc(pMem,nNewSize) );
-}
-
-/************************************************************************/
-/*                           DBFWriteHeader()                           */
-/*                                                                      */
-/*      This is called to write out the file header, and field          */
-/*      descriptions before writing any actual data records.  This      */
-/*      also computes all the DBFDataSet field offset/size/decimals     */
-/*      and so forth values.                                            */
-/************************************************************************/
-
-static void DBFWriteHeader(DBFHandle psDBF)
-
-{
-    unsigned char      abyHeader[XBASE_FLDHDR_SZ];
-    int                i;
-
-    if( !psDBF->bNoHeader )
-        return;
-
-    psDBF->bNoHeader = FALSE;
-
-/* -------------------------------------------------------------------- */
-/*     Initialize the file header information.                         */
-/* -------------------------------------------------------------------- */
-    for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
-        abyHeader[i] = 0;
-
-    abyHeader[0] = 0x03;               /* memo field? - just copying   */
-
-    /* write out a dummy date */
-    abyHeader[1] = 95;                 /* YY */
-    abyHeader[2] = 7;                  /* MM */
-    abyHeader[3] = 26;                 /* DD */
-
-    /* record count preset at zero */
-
-    abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
-    abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
-    
-    abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
-    abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
-
-    abyHeader[29] = (unsigned char) (psDBF->iLanguageDriver);
-
-/* -------------------------------------------------------------------- */
-/*      Write the initial 32 byte file header, and all the field        */
-/*      descriptions.                                                  */
-/* -------------------------------------------------------------------- */
-    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
-    psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
-    psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, 
-                          psDBF->fp );
-
-/* -------------------------------------------------------------------- */
-/*      Write out the newline character if there is room for it.        */
-/* -------------------------------------------------------------------- */
-    if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
-    {
-        char   cNewline;
-
-        cNewline = 0x0d;
-        psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
-    }
-}
-
-/************************************************************************/
-/*                           DBFFlushRecord()                           */
-/*                                                                      */
-/*      Write out the current record if there is one.                   */
-/************************************************************************/
-
-static int DBFFlushRecord( DBFHandle psDBF )
-
-{
-    SAOffset   nRecordOffset;
-
-    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
-    {
-       psDBF->bCurrentRecordModified = FALSE;
-
-       nRecordOffset = 
-            psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord 
-            + psDBF->nHeaderLength;
-
-       if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0 
-            || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord, 
-                                     psDBF->nRecordLength, 
-                                     1, psDBF->fp ) != 1 )
-        {
-            char szMessage[128];
-            sprintf( szMessage, "Failure writing DBF record %d.", 
-                     psDBF->nCurrentRecord );
-            psDBF->sHooks.Error( szMessage );
-            return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                           DBFLoadRecord()                            */
-/************************************************************************/
-
-static int DBFLoadRecord( DBFHandle psDBF, int iRecord )
-
-{
-    if( psDBF->nCurrentRecord != iRecord )
-    {
-        SAOffset nRecordOffset;
-
-       if( !DBFFlushRecord( psDBF ) )
-            return FALSE;
-
-       nRecordOffset = 
-            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-       if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
-        {
-            char szMessage[128];
-            sprintf( szMessage, "fseek(%ld) failed on DBF file.\n",
-                     (long) nRecordOffset );
-            psDBF->sHooks.Error( szMessage );
-            return FALSE;
-        }
-
-       if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord, 
-                                 psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
-        {
-            char szMessage[128];
-            sprintf( szMessage, "fread(%d) failed on DBF file.\n",
-                     psDBF->nRecordLength );
-            psDBF->sHooks.Error( szMessage );
-            return FALSE;
-        }
-
-       psDBF->nCurrentRecord = iRecord;
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                          DBFUpdateHeader()                           */
-/************************************************************************/
-
-void SHPAPI_CALL
-DBFUpdateHeader( DBFHandle psDBF )
-
-{
-    unsigned char              abyFileHeader[32];
-
-    if( psDBF->bNoHeader )
-        DBFWriteHeader( psDBF );
-
-    DBFFlushRecord( psDBF );
-
-    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
-    psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
-    
-    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
-    abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
-    abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
-    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
-    
-    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
-    psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
-
-    psDBF->sHooks.FFlush( psDBF->fp );
-}
-
-/************************************************************************/
-/*                              DBFOpen()                               */
-/*                                                                      */
-/*      Open a .dbf file.                                               */
-/************************************************************************/
-   
-DBFHandle SHPAPI_CALL
-DBFOpen( const char * pszFilename, const char * pszAccess )
-
-{
-    SAHooks sHooks;
-
-    SASetupDefaultHooks( &sHooks );
-
-    return DBFOpenLL( pszFilename, pszAccess, &sHooks );
-}
-
-/************************************************************************/
-/*                              DBFOpen()                               */
-/*                                                                      */
-/*      Open a .dbf file.                                               */
-/************************************************************************/
-   
-DBFHandle SHPAPI_CALL
-DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
-
-{
-    DBFHandle          psDBF;
-    SAFile             pfCPG;
-    unsigned char      *pabyBuf;
-    int                        nFields, nHeadLen, iField, i;
-    char               *pszBasename, *pszFullname;
-    int                 nBufSize = 500;
-
-/* -------------------------------------------------------------------- */
-/*      We only allow the access strings "rb" and "r+".                  */
-/* -------------------------------------------------------------------- */
-    if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 
-        && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
-        && 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.                 */
-/* -------------------------------------------------------------------- */
-    pszBasename = (char *) malloc(strlen(pszFilename)+5);
-    strcpy( pszBasename, pszFilename );
-    for( i = strlen(pszBasename)-1; 
-        i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-              && pszBasename[i] != '\\';
-        i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
-
-    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
-    sprintf( pszFullname, "%s.dbf", pszBasename );
-        
-    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
-    psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
-    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
-
-    if( psDBF->fp == NULL )
-    {
-        sprintf( pszFullname, "%s.DBF", pszBasename );
-        psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
-    }
-
-    sprintf( pszFullname, "%s.cpg", pszBasename );
-    pfCPG = psHooks->FOpen( pszFullname, "r" );
-    if( pfCPG == NULL )
-    {
-        sprintf( pszFullname, "%s.CPG", pszBasename );
-        pfCPG = psHooks->FOpen( pszFullname, "r" );
-    }
-
-    free( pszBasename );
-    free( pszFullname );
-    
-    if( psDBF->fp == NULL )
-    {
-        free( psDBF );
-        if( pfCPG ) psHooks->FClose( pfCPG );
-        return( NULL );
-    }
-
-    psDBF->bNoHeader = FALSE;
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-
-/* -------------------------------------------------------------------- */
-/*  Read Table Header info                                              */
-/* -------------------------------------------------------------------- */
-    pabyBuf = (unsigned char *) malloc(nBufSize);
-    if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
-    {
-        psDBF->sHooks.FClose( psDBF->fp );
-        if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
-        free( pabyBuf );
-        free( psDBF );
-        return NULL;
-    }
-
-    psDBF->nRecords = 
-     pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
-
-    psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
-    psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256;
-    psDBF->iLanguageDriver = pabyBuf[29];
-
-    if (nHeadLen < 32)
-    {
-        psDBF->sHooks.FClose( psDBF->fp );
-        if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
-        free( pabyBuf );
-        free( psDBF );
-        return NULL;
-    }
-
-    psDBF->nFields = nFields = (nHeadLen - 32) / 32;
-
-    psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength);
-
-/* -------------------------------------------------------------------- */
-/*  Figure out the code page from the LDID and CPG                      */
-/* -------------------------------------------------------------------- */
-
-    psDBF->pszCodePage = NULL;
-    if( pfCPG )
-    {
-        size_t n;
-        memset( pabyBuf, 0, nBufSize);
-        psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
-        n = strcspn( (char *) pabyBuf, "\n\r" );
-        if( n > 0 )
-        {
-            pabyBuf[n] = '\0';
-            psDBF->pszCodePage = (char *) malloc(n + 1);
-            memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
-        }
-               psDBF->sHooks.FClose( pfCPG );
-    }
-    if( psDBF->pszCodePage == NULL && pabyBuf[29] != 0 )
-    {
-        sprintf( (char *) pabyBuf, "LDID/%d", psDBF->iLanguageDriver );
-        psDBF->pszCodePage = (char *) malloc(strlen((char*)pabyBuf) + 1);
-        strcpy( psDBF->pszCodePage, (char *) pabyBuf );
-    }
-
-/* -------------------------------------------------------------------- */
-/*  Read in Field Definitions                                           */
-/* -------------------------------------------------------------------- */
-    
-    pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
-    psDBF->pszHeader = (char *) pabyBuf;
-
-    psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
-    if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
-    {
-        psDBF->sHooks.FClose( psDBF->fp );
-        free( pabyBuf );
-        free( psDBF->pszCurrentRecord );
-        free( psDBF );
-        return NULL;
-    }
-
-    psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
-    psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
-    psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields);
-    psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields);
-
-    for( iField = 0; iField < nFields; iField++ )
-    {
-       unsigned char           *pabyFInfo;
-
-       pabyFInfo = pabyBuf+iField*32;
-
-       if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
-       {
-           psDBF->panFieldSize[iField] = pabyFInfo[16];
-           psDBF->panFieldDecimals[iField] = pabyFInfo[17];
-       }
-       else
-       {
-           psDBF->panFieldSize[iField] = pabyFInfo[16];
-           psDBF->panFieldDecimals[iField] = 0;
-
-/*
-** The following seemed to be used sometimes to handle files with long
-** string fields, but in other cases (such as bug 1202) the decimals field
-** just seems to indicate some sort of preferred formatting, not very
-** wide fields.  So I have disabled this code.  FrankW.
-           psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
-           psDBF->panFieldDecimals[iField] = 0;
-*/
-       }
-
-       psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
-       if( iField == 0 )
-           psDBF->panFieldOffset[iField] = 1;
-       else
-           psDBF->panFieldOffset[iField] = 
-             psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
-    }
-
-    return( psDBF );
-}
-
-/************************************************************************/
-/*                              DBFClose()                              */
-/************************************************************************/
-
-void SHPAPI_CALL
-DBFClose(DBFHandle psDBF)
-{
-    if( psDBF == NULL )
-        return;
-
-/* -------------------------------------------------------------------- */
-/*      Write out header if not already written.                        */
-/* -------------------------------------------------------------------- */
-    if( psDBF->bNoHeader )
-        DBFWriteHeader( psDBF );
-
-    DBFFlushRecord( psDBF );
-
-/* -------------------------------------------------------------------- */
-/*      Update last access date, and number of records if we have      */
-/*     write access.                                                   */
-/* -------------------------------------------------------------------- */
-    if( psDBF->bUpdated )
-        DBFUpdateHeader( psDBF );
-
-/* -------------------------------------------------------------------- */
-/*      Close, and free resources.                                      */
-/* -------------------------------------------------------------------- */
-    psDBF->sHooks.FClose( psDBF->fp );
-
-    if( psDBF->panFieldOffset != NULL )
-    {
-        free( psDBF->panFieldOffset );
-        free( psDBF->panFieldSize );
-        free( psDBF->panFieldDecimals );
-        free( psDBF->pachFieldType );
-    }
-
-    if( psDBF->pszWorkField != NULL )
-        free( psDBF->pszWorkField );
-
-    free( psDBF->pszHeader );
-    free( psDBF->pszCurrentRecord );
-    free( psDBF->pszCodePage );
-
-    free( psDBF );
-}
-
-/************************************************************************/
-/*                             DBFCreate()                              */
-/*                                                                      */
-/* Create a new .dbf file with default code page LDID/87 (0x57)         */
-/************************************************************************/
-
-DBFHandle SHPAPI_CALL
-DBFCreate( const char * pszFilename )
-
-{
-    return DBFCreateEx( pszFilename, "LDID/87" ); // 0x57
-}
-
-/************************************************************************/
-/*                            DBFCreateEx()                             */
-/*                                                                      */
-/*      Create a new .dbf file.                                         */
-/************************************************************************/
-
-DBFHandle SHPAPI_CALL
-DBFCreateEx( const char * pszFilename, const char* pszCodePage )
-
-{
-    SAHooks sHooks;
-
-    SASetupDefaultHooks( &sHooks );
-
-    return DBFCreateLL( pszFilename, pszCodePage , &sHooks );
-}
-
-/************************************************************************/
-/*                             DBFCreate()                              */
-/*                                                                      */
-/*      Create a new .dbf file.                                         */
-/************************************************************************/
-
-DBFHandle SHPAPI_CALL
-DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHooks )
-
-{
-    DBFHandle  psDBF;
-    SAFile     fp;
-    char       *pszFullname, *pszBasename;
-    int                i, ldid = -1;
-    char chZero = '\0';
-
-/* -------------------------------------------------------------------- */
-/*     Compute the base (layer) name.  If there is any extension       */
-/*     on the passed in filename we will strip it off.                 */
-/* -------------------------------------------------------------------- */
-    pszBasename = (char *) malloc(strlen(pszFilename)+5);
-    strcpy( pszBasename, pszFilename );
-    for( i = strlen(pszBasename)-1; 
-        i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-              && pszBasename[i] != '\\';
-        i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
-
-    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
-    sprintf( pszFullname, "%s.dbf", pszBasename );
-
-/* -------------------------------------------------------------------- */
-/*      Create the file.                                                */
-/* -------------------------------------------------------------------- */
-    fp = psHooks->FOpen( pszFullname, "wb" );
-    if( fp == NULL )
-        return( NULL );
-    
-    psHooks->FWrite( &chZero, 1, 1, fp );
-    psHooks->FClose( fp );
-
-    fp = psHooks->FOpen( pszFullname, "rb+" );
-    if( fp == NULL )
-        return( NULL );
-
-
-    sprintf( pszFullname, "%s.cpg", pszBasename );
-    if( pszCodePage != NULL )
-    {
-        if( strncmp( pszCodePage, "LDID/", 5 ) == 0 )
-        {
-            ldid = atoi( pszCodePage + 5 );
-            if( ldid > 255 )
-                ldid = -1; // don't use 0 to indicate out of range as LDID/0 is a valid one
-        }
-        if( ldid < 0 )
-        {
-            SAFile fpCPG = psHooks->FOpen( pszFullname, "w" );
-            psHooks->FWrite( (char*) pszCodePage, strlen(pszCodePage), 1, fpCPG );
-            psHooks->FClose( fpCPG );
-        }
-    }
-    if( pszCodePage == NULL || ldid >= 0 )
-    {
-        psHooks->Remove( pszFullname );
-    }
-
-    free( pszBasename );
-    free( pszFullname );
-
-/* -------------------------------------------------------------------- */
-/*     Create the info structure.                                      */
-/* -------------------------------------------------------------------- */
-    psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo));
-
-    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
-    psDBF->fp = fp;
-    psDBF->nRecords = 0;
-    psDBF->nFields = 0;
-    psDBF->nRecordLength = 1;
-    psDBF->nHeaderLength = 33;
-    
-    psDBF->panFieldOffset = NULL;
-    psDBF->panFieldSize = NULL;
-    psDBF->panFieldDecimals = NULL;
-    psDBF->pachFieldType = NULL;
-    psDBF->pszHeader = NULL;
-
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-    psDBF->pszCurrentRecord = NULL;
-
-    psDBF->bNoHeader = TRUE;
-
-    psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
-    psDBF->pszCodePage = NULL;
-    if( pszCodePage )
-    {
-        psDBF->pszCodePage = (char * ) malloc( strlen(pszCodePage) + 1 );
-        strcpy( psDBF->pszCodePage, pszCodePage );
-    }
-
-    return( psDBF );
-}
-
-/************************************************************************/
-/*                            DBFAddField()                             */
-/*                                                                      */
-/*      Add a field to a newly created .dbf or to an existing one       */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFAddField(DBFHandle psDBF, const char * pszFieldName, 
-            DBFFieldType eType, int nWidth, int nDecimals )
-
-{
-    char chNativeType = 'C';
-
-    if( eType == FTLogical )
-        chNativeType = 'L';
-    else if( eType == FTString )
-        chNativeType = 'C';
-    else
-        chNativeType = 'N';
-
-    return DBFAddNativeFieldType( psDBF, pszFieldName, chNativeType, 
-                                  nWidth, nDecimals );
-}
-
-/************************************************************************/
-/*                        DBFGetNullCharacter()                         */
-/************************************************************************/
-
-static char DBFGetNullCharacter(char chType)
-{
-    switch (chType)
-    {
-      case 'N':
-      case 'F':
-        return '*';
-      case 'D':
-        return '0';
-      case 'L':
-       return '?';
-      default:
-       return ' ';
-    }
-}
-
-/************************************************************************/
-/*                            DBFAddField()                             */
-/*                                                                      */
-/*      Add a field to a newly created .dbf file before any records     */
-/*      are written.                                                    */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, 
-                      char chType, int nWidth, int nDecimals )
-
-{
-    char       *pszFInfo;
-    int                i;
-    int         nOldRecordLength, nOldHeaderLength;
-    char        *pszRecord;
-    char        chFieldFill;
-    SAOffset    nRecordOffset;
-
-    /* make sure that everything is written in .dbf */
-    if( !DBFFlushRecord( psDBF ) )
-        return -1;
-
-/* -------------------------------------------------------------------- */
-/*      Do some checking to ensure we can add records to this file.     */
-/* -------------------------------------------------------------------- */
-    if( nWidth < 1 )
-        return -1;
-
-    if( nWidth > 255 )
-        nWidth = 255;
-
-    nOldRecordLength = psDBF->nRecordLength;
-    nOldHeaderLength = psDBF->nHeaderLength;
-
-/* -------------------------------------------------------------------- */
-/*      SfRealloc all the arrays larger to hold the additional field      */
-/*      information.                                                    */
-/* -------------------------------------------------------------------- */
-    psDBF->nFields++;
-
-    psDBF->panFieldOffset = (int *) 
-        SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
-
-    psDBF->panFieldSize = (int *) 
-        SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
-
-    psDBF->panFieldDecimals = (int *) 
-        SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
-
-    psDBF->pachFieldType = (char *) 
-        SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
-
-/* -------------------------------------------------------------------- */
-/*      Assign the new field information fields.                        */
-/* -------------------------------------------------------------------- */
-    psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
-    psDBF->nRecordLength += nWidth;
-    psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
-    psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
-    psDBF->pachFieldType[psDBF->nFields-1] = chType;
-
-/* -------------------------------------------------------------------- */
-/*      Extend the required header information.                         */
-/* -------------------------------------------------------------------- */
-    psDBF->nHeaderLength += 32;
-    psDBF->bUpdated = FALSE;
-
-    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
-
-    pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
-
-    for( i = 0; i < 32; i++ )
-        pszFInfo[i] = '\0';
-
-    if( (int) strlen(pszFieldName) < 10 )
-        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
-    else
-        strncpy( pszFInfo, pszFieldName, 10);
-
-    pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
-
-    if( chType == 'C' )
-    {
-        pszFInfo[16] = (unsigned char) (nWidth % 256);
-        pszFInfo[17] = (unsigned char) (nWidth / 256);
-    }
-    else
-    {
-        pszFInfo[16] = (unsigned char) nWidth;
-        pszFInfo[17] = (unsigned char) nDecimals;
-    }
-    
-/* -------------------------------------------------------------------- */
-/*      Make the current record buffer appropriately larger.            */
-/* -------------------------------------------------------------------- */
-    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
-                                                 psDBF->nRecordLength);
-
-    /* we're done if dealing with new .dbf */
-    if( psDBF->bNoHeader )
-        return( psDBF->nFields - 1 );
-
-/* -------------------------------------------------------------------- */
-/*      For existing .dbf file, shift records                           */
-/* -------------------------------------------------------------------- */
-
-    /* alloc record */
-    pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
-
-    chFieldFill = DBFGetNullCharacter(chType);
-
-    for (i = psDBF->nRecords-1; i >= 0; --i)
-    {
-        nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength;
-
-        /* load record */
-        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-        psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
-
-        /* set new field's value to NULL */
-        memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
-
-        nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength;
-
-        /* move record to the new place*/
-        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-        psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
-    }
-
-    /* free record */
-    free(pszRecord);
-
-    /* force update of header with new header, record length and new field */
-    psDBF->bNoHeader = TRUE;
-    DBFUpdateHeader( psDBF );
-
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-
-    return( psDBF->nFields-1 );
-}
-
-/************************************************************************/
-/*                          DBFReadAttribute()                          */
-/*                                                                      */
-/*      Read one of the attribute fields of a record.                   */
-/************************************************************************/
-
-static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
-                              char chReqType )
-
-{
-    unsigned char      *pabyRec;
-    void       *pReturnField = NULL;
-
-/* -------------------------------------------------------------------- */
-/*      Verify selection.                                               */
-/* -------------------------------------------------------------------- */
-    if( hEntity < 0 || hEntity >= psDBF->nRecords )
-        return( NULL );
-
-    if( iField < 0 || iField >= psDBF->nFields )
-        return( NULL );
-
-/* -------------------------------------------------------------------- */
-/*     Have we read the record?                                        */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, hEntity ) )
-        return NULL;
-
-    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
-
-/* -------------------------------------------------------------------- */
-/*      Ensure we have room to extract the target field.                */
-/* -------------------------------------------------------------------- */
-    if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength )
-    {
-        psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
-        if( psDBF->pszWorkField == NULL )
-            psDBF->pszWorkField = (char *) malloc(psDBF->nWorkFieldLength);
-        else
-            psDBF->pszWorkField = (char *) realloc(psDBF->pszWorkField,
-                                                   psDBF->nWorkFieldLength);
-    }
-
-/* -------------------------------------------------------------------- */
-/*     Extract the requested field.                                    */
-/* -------------------------------------------------------------------- */
-    strncpy( psDBF->pszWorkField,
-            ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
-            psDBF->panFieldSize[iField] );
-    psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0';
-
-    pReturnField = psDBF->pszWorkField;
-
-/* -------------------------------------------------------------------- */
-/*      Decode the field.                                               */
-/* -------------------------------------------------------------------- */
-    if( chReqType == 'N' )
-    {
-        psDBF->dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
-
-       pReturnField = &(psDBF->dfDoubleField);
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Should we trim white space off the string attribute value?      */
-/* -------------------------------------------------------------------- */
-#ifdef TRIM_DBF_WHITESPACE
-    else
-    {
-        char   *pchSrc, *pchDst;
-
-        pchDst = pchSrc = psDBF->pszWorkField;
-        while( *pchSrc == ' ' )
-            pchSrc++;
-
-        while( *pchSrc != '\0' )
-            *(pchDst++) = *(pchSrc++);
-        *pchDst = '\0';
-
-        while( pchDst != psDBF->pszWorkField && *(--pchDst) == ' ' )
-            *pchDst = '\0';
-    }
-#endif
-    
-    return( pReturnField );
-}
-
-/************************************************************************/
-/*                        DBFReadIntAttribute()                         */
-/*                                                                      */
-/*      Read an integer attribute.                                      */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
-
-{
-    double     *pdValue;
-
-    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
-
-    if( pdValue == NULL )
-        return 0;
-    else
-        return( (int) *pdValue );
-}
-
-/************************************************************************/
-/*                        DBFReadDoubleAttribute()                      */
-/*                                                                      */
-/*      Read a double attribute.                                        */
-/************************************************************************/
-
-double SHPAPI_CALL
-DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
-
-{
-    double     *pdValue;
-
-    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
-
-    if( pdValue == NULL )
-        return 0.0;
-    else
-        return( *pdValue );
-}
-
-/************************************************************************/
-/*                        DBFReadStringAttribute()                      */
-/*                                                                      */
-/*      Read a string attribute.                                        */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
-
-{
-    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
-}
-
-/************************************************************************/
-/*                        DBFReadLogicalAttribute()                     */
-/*                                                                      */
-/*      Read a logical attribute.                                       */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
-
-{
-    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
-}
-
-
-/************************************************************************/
-/*                         DBFIsValueNULL()                             */
-/*                                                                      */
-/*      Return TRUE if the passed string is NULL.                       */
-/************************************************************************/
-
-static int DBFIsValueNULL( char chType, const char* pszValue )
-{
-    int i;
-
-    if( pszValue == NULL )
-        return TRUE;
-
-    switch(chType)
-    {
-      case 'N':
-      case 'F':
-        /*
-        ** We accept all asterisks or all blanks as NULL
-        ** though according to the spec I think it should be all
-        ** asterisks.
-        */
-        if( pszValue[0] == '*' )
-            return TRUE;
-
-        for( i = 0; pszValue[i] != '\0'; i++ )
-        {
-            if( pszValue[i] != ' ' )
-                return FALSE;
-        }
-        return TRUE;
-
-      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;
-    }
-}
-
-/************************************************************************/
-/*                         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 );
-
-    if( pszValue == NULL )
-        return TRUE;
-
-    return DBFIsValueNULL( psDBF->pachFieldType[iField], pszValue );
-}
-
-/************************************************************************/
-/*                          DBFGetFieldCount()                          */
-/*                                                                      */
-/*      Return the number of fields in this table.                      */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFGetFieldCount( DBFHandle psDBF )
-
-{
-    return( psDBF->nFields );
-}
-
-/************************************************************************/
-/*                         DBFGetRecordCount()                          */
-/*                                                                      */
-/*      Return the number of records in this table.                     */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFGetRecordCount( DBFHandle psDBF )
-
-{
-    return( psDBF->nRecords );
-}
-
-/************************************************************************/
-/*                          DBFGetFieldInfo()                           */
-/*                                                                      */
-/*      Return any requested information about the field.               */
-/************************************************************************/
-
-DBFFieldType SHPAPI_CALL
-DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
-                 int * pnWidth, int * pnDecimals )
-
-{
-    if( iField < 0 || iField >= psDBF->nFields )
-        return( FTInvalid );
-
-    if( pnWidth != NULL )
-        *pnWidth = psDBF->panFieldSize[iField];
-
-    if( pnDecimals != NULL )
-        *pnDecimals = psDBF->panFieldDecimals[iField];
-
-    if( pszFieldName != NULL )
-    {
-       int     i;
-
-       strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 );
-       pszFieldName[11] = '\0';
-       for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- )
-           pszFieldName[i] = '\0';
-    }
-
-    if ( psDBF->pachFieldType[iField] == 'L' )
-       return( FTLogical);
-
-    else if( psDBF->pachFieldType[iField] == 'N' 
-             || psDBF->pachFieldType[iField] == 'F' )
-    {
-       if( psDBF->panFieldDecimals[iField] > 0 
-            || psDBF->panFieldSize[iField] > 10 )
-           return( FTDouble );
-       else
-           return( FTInteger );
-    }
-    else
-    {
-       return( FTString );
-    }
-}
-
-/************************************************************************/
-/*                         DBFWriteAttribute()                          */
-/*                                                                     */
-/*     Write an attribute record to the file.                          */
-/************************************************************************/
-
-static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
-                            void * pValue )
-
-{
-    int                i, j, nRetResult = TRUE;
-    unsigned char      *pabyRec;
-    char       szSField[400], szFormat[20];
-
-/* -------------------------------------------------------------------- */
-/*     Is this a valid record?                                         */
-/* -------------------------------------------------------------------- */
-    if( hEntity < 0 || hEntity > psDBF->nRecords )
-        return( FALSE );
-
-    if( psDBF->bNoHeader )
-        DBFWriteHeader(psDBF);
-
-/* -------------------------------------------------------------------- */
-/*      Is this a brand new record?                                     */
-/* -------------------------------------------------------------------- */
-    if( hEntity == psDBF->nRecords )
-    {
-       if( !DBFFlushRecord( psDBF ) )
-            return FALSE;
-
-       psDBF->nRecords++;
-       for( i = 0; i < psDBF->nRecordLength; i++ )
-           psDBF->pszCurrentRecord[i] = ' ';
-
-       psDBF->nCurrentRecord = hEntity;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Is this an existing record, but different than the last one     */
-/*      we accessed?                                                    */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, hEntity ) )
-        return FALSE;
-
-    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 )
-    {
-        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]),
-                DBFGetNullCharacter(psDBF->pachFieldType[iField]),
-                psDBF->panFieldSize[iField] );
-        return TRUE;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Assign all the record fields.                                   */
-/* -------------------------------------------------------------------- */
-    switch( psDBF->pachFieldType[iField] )
-    {
-      case 'D':
-      case 'N':
-      case 'F':
-       if( psDBF->panFieldDecimals[iField] == 0 )
-       {
-            int                nWidth = psDBF->panFieldSize[iField];
-
-            if( (int) sizeof(szSField)-2 < nWidth )
-                nWidth = sizeof(szSField)-2;
-
-           sprintf( szFormat, "%%%dd", nWidth );
-           sprintf(szSField, szFormat, (int) *((double *) pValue) );
-           if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
-            {
-               szSField[psDBF->panFieldSize[iField]] = '\0';
-                nRetResult = FALSE;
-            }
-
-           strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
-                   szSField, strlen(szSField) );
-       }
-       else
-       {
-            int                nWidth = psDBF->panFieldSize[iField];
-
-            if( (int) sizeof(szSField)-2 < nWidth )
-                nWidth = sizeof(szSField)-2;
-
-           sprintf( szFormat, "%%%d.%df", 
-                     nWidth, psDBF->panFieldDecimals[iField] );
-           sprintf(szSField, szFormat, *((double *) pValue) );
-           if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
-            {
-               szSField[psDBF->panFieldSize[iField]] = '\0';
-                nRetResult = FALSE;
-            }
-           strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
-                   szSField, strlen(szSField) );
-       }
-       break;
-
-      case 'L':
-        if (psDBF->panFieldSize[iField] >= 1  && 
-            (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
-            *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
-        break;
-
-      default:
-       if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
-        {
-           j = psDBF->panFieldSize[iField];
-            nRetResult = FALSE;
-        }
-       else
-        {
-            memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
-                    psDBF->panFieldSize[iField] );
-           j = strlen((char *) pValue);
-        }
-
-       strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
-               (char *) pValue, j );
-       break;
-    }
-
-    return( nRetResult );
-}
-
-/************************************************************************/
-/*                     DBFWriteAttributeDirectly()                      */
-/*                                                                      */
-/*      Write an attribute record to the file, but without any          */
-/*      reformatting based on type.  The provided buffer is written     */
-/*      as is to the field position in the record.                      */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
-                              void * pValue )
-
-{
-    int                        i, j;
-    unsigned char      *pabyRec;
-
-/* -------------------------------------------------------------------- */
-/*     Is this a valid record?                                         */
-/* -------------------------------------------------------------------- */
-    if( hEntity < 0 || hEntity > psDBF->nRecords )
-        return( FALSE );
-
-    if( psDBF->bNoHeader )
-        DBFWriteHeader(psDBF);
-
-/* -------------------------------------------------------------------- */
-/*      Is this a brand new record?                                     */
-/* -------------------------------------------------------------------- */
-    if( hEntity == psDBF->nRecords )
-    {
-       if( !DBFFlushRecord( psDBF ) )
-            return FALSE;
-
-       psDBF->nRecords++;
-       for( i = 0; i < psDBF->nRecordLength; i++ )
-           psDBF->pszCurrentRecord[i] = ' ';
-
-       psDBF->nCurrentRecord = hEntity;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Is this an existing record, but different than the last one     */
-/*      we accessed?                                                    */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, hEntity ) )
-        return FALSE;
-
-    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
-
-/* -------------------------------------------------------------------- */
-/*      Assign all the record fields.                                   */
-/* -------------------------------------------------------------------- */
-    if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
-        j = psDBF->panFieldSize[iField];
-    else
-    {
-        memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
-                psDBF->panFieldSize[iField] );
-        j = strlen((char *) pValue);
-    }
-
-    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
-            (char *) pValue, j );
-
-    psDBF->bCurrentRecordModified = TRUE;
-    psDBF->bUpdated = TRUE;
-
-    return( TRUE );
-}
-
-/************************************************************************/
-/*                      DBFWriteDoubleAttribute()                       */
-/*                                                                      */
-/*      Write a double attribute.                                       */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
-                         double dValue )
-
-{
-    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
-}
-
-/************************************************************************/
-/*                      DBFWriteIntegerAttribute()                      */
-/*                                                                      */
-/*      Write a integer attribute.                                      */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
-                          int nValue )
-
-{
-    double     dValue = nValue;
-
-    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
-}
-
-/************************************************************************/
-/*                      DBFWriteStringAttribute()                       */
-/*                                                                      */
-/*      Write a string attribute.                                       */
-/************************************************************************/
-
-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 ) );
-}
-
-/************************************************************************/
-/*                      DBFWriteLogicalAttribute()                      */
-/*                                                                      */
-/*      Write a logical attribute.                                      */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
-                      const char lValue)
-
-{
-    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
-}
-
-/************************************************************************/
-/*                         DBFWriteTuple()                              */
-/*                                                                     */
-/*     Write an attribute record to the file.                          */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
-
-{
-    int                        i;
-    unsigned char      *pabyRec;
-
-/* -------------------------------------------------------------------- */
-/*     Is this a valid record?                                         */
-/* -------------------------------------------------------------------- */
-    if( hEntity < 0 || hEntity > psDBF->nRecords )
-        return( FALSE );
-
-    if( psDBF->bNoHeader )
-        DBFWriteHeader(psDBF);
-
-/* -------------------------------------------------------------------- */
-/*      Is this a brand new record?                                     */
-/* -------------------------------------------------------------------- */
-    if( hEntity == psDBF->nRecords )
-    {
-       if( !DBFFlushRecord( psDBF ) )
-            return FALSE;
-
-       psDBF->nRecords++;
-       for( i = 0; i < psDBF->nRecordLength; i++ )
-           psDBF->pszCurrentRecord[i] = ' ';
-
-       psDBF->nCurrentRecord = hEntity;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Is this an existing record, but different than the last one     */
-/*      we accessed?                                                    */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, hEntity ) )
-        return FALSE;
-
-    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
-
-    memcpy ( pabyRec, pRawTuple,  psDBF->nRecordLength );
-
-    psDBF->bCurrentRecordModified = TRUE;
-    psDBF->bUpdated = TRUE;
-
-    return( TRUE );
-}
-
-/************************************************************************/
-/*                            DBFReadTuple()                            */
-/*                                                                      */
-/*      Read a complete record.  Note that the result is only valid     */
-/*      till the next record read for any reason.                       */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-DBFReadTuple(DBFHandle psDBF, int hEntity )
-
-{
-    if( hEntity < 0 || hEntity >= psDBF->nRecords )
-        return( NULL );
-
-    if( !DBFLoadRecord( psDBF, hEntity ) )
-        return NULL;
-
-    return (const char *) psDBF->pszCurrentRecord;
-}
-
-/************************************************************************/
-/*                          DBFCloneEmpty()                              */
-/*                                                                      */
-/*      Read one of the attribute fields of a record.                   */
-/************************************************************************/
-
-DBFHandle SHPAPI_CALL
-DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) 
-{
-    DBFHandle  newDBF;
-
-   newDBF = DBFCreateEx ( pszFilename, psDBF->pszCodePage );
-   if ( newDBF == NULL ) return ( NULL ); 
-   
-   newDBF->nFields = psDBF->nFields;
-   newDBF->nRecordLength = psDBF->nRecordLength;
-   newDBF->nHeaderLength = psDBF->nHeaderLength;
-    
-   newDBF->pszHeader = (char *) malloc ( newDBF->nHeaderLength );
-   memcpy ( newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength );
-   
-   newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); 
-   memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
-   newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
-   memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
-   newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
-   memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
-   newDBF->pachFieldType = (char *) malloc ( sizeof(char) * psDBF->nFields );
-   memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(char)*psDBF->nFields );
-
-   newDBF->bNoHeader = TRUE;
-   newDBF->bUpdated = TRUE;
-   
-   DBFWriteHeader ( newDBF );
-   DBFClose ( newDBF );
-   
-   newDBF = DBFOpen ( pszFilename, "rb+" );
-
-   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] = (char) 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);
-    name1[11] = '\0';
-    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);
-}
-
-/************************************************************************/
-/*                         DBFIsRecordDeleted()                         */
-/*                                                                      */
-/*      Returns TRUE if the indicated record is deleted, otherwise      */
-/*      it returns FALSE.                                               */
-/************************************************************************/
-
-int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape )
-
-{
-/* -------------------------------------------------------------------- */
-/*      Verify selection.                                               */
-/* -------------------------------------------------------------------- */
-    if( iShape < 0 || iShape >= psDBF->nRecords )
-        return TRUE;
-
-/* -------------------------------------------------------------------- */
-/*     Have we read the record?                                        */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, iShape ) )
-        return FALSE;
-
-/* -------------------------------------------------------------------- */
-/*      '*' means deleted.                                              */
-/* -------------------------------------------------------------------- */
-    return psDBF->pszCurrentRecord[0] == '*';
-}
-
-/************************************************************************/
-/*                        DBFMarkRecordDeleted()                        */
-/************************************************************************/
-
-int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape, 
-                                      int bIsDeleted )
-
-{
-    char chNewFlag;
-
-/* -------------------------------------------------------------------- */
-/*      Verify selection.                                               */
-/* -------------------------------------------------------------------- */
-    if( iShape < 0 || iShape >= psDBF->nRecords )
-        return FALSE;
-
-/* -------------------------------------------------------------------- */
-/*      Is this an existing record, but different than the last one     */
-/*      we accessed?                                                    */
-/* -------------------------------------------------------------------- */
-    if( !DBFLoadRecord( psDBF, iShape ) )
-        return FALSE;
-
-/* -------------------------------------------------------------------- */
-/*      Assign value, marking record as dirty if it changes.            */
-/* -------------------------------------------------------------------- */
-    if( bIsDeleted )
-        chNewFlag = '*';
-    else 
-        chNewFlag = ' ';
-
-    if( psDBF->pszCurrentRecord[0] != chNewFlag )
-    {
-        psDBF->bCurrentRecordModified = TRUE;
-        psDBF->bUpdated = TRUE;
-        psDBF->pszCurrentRecord[0] = chNewFlag;
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                            DBFGetCodePage                            */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-DBFGetCodePage(DBFHandle psDBF )
-{
-    if( psDBF == NULL )
-        return NULL;
-    return psDBF->pszCodePage;
-}
-
-/************************************************************************/
-/*                          DBFDeleteField()                            */
-/*                                                                      */
-/*      Remove a field from a .dbf file                                 */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFDeleteField(DBFHandle psDBF, int iField)
-{
-    int nOldRecordLength, nOldHeaderLength;
-    int nDeletedFieldOffset, nDeletedFieldSize;
-    SAOffset nRecordOffset;
-    char* pszRecord;
-    int i, iRecord;
-
-    if (iField < 0 || iField >= psDBF->nFields)
-        return FALSE;
-
-    /* make sure that everything is written in .dbf */
-    if( !DBFFlushRecord( psDBF ) )
-        return FALSE;
-
-    /* get information about field to be deleted */
-    nOldRecordLength = psDBF->nRecordLength;
-    nOldHeaderLength = psDBF->nHeaderLength;
-    nDeletedFieldOffset = psDBF->panFieldOffset[iField];
-    nDeletedFieldSize = psDBF->panFieldSize[iField];
-
-    /* update fields info */
-    for (i = iField + 1; i < psDBF->nFields; i++)
-    {
-        psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
-        psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
-        psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
-        psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
-    }
-
-    /* resize fields arrays */
-    psDBF->nFields--;
-
-    psDBF->panFieldOffset = (int *) 
-        SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
-
-    psDBF->panFieldSize = (int *) 
-        SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
-
-    psDBF->panFieldDecimals = (int *) 
-        SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
-
-    psDBF->pachFieldType = (char *) 
-        SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
-
-    /* update header information */
-    psDBF->nHeaderLength -= 32;
-    psDBF->nRecordLength -= nDeletedFieldSize;
-
-    /* overwrite field information in header */
-    memmove(psDBF->pszHeader + iField*32,
-           psDBF->pszHeader + (iField+1)*32,
-           sizeof(char) * (psDBF->nFields - iField)*32);
-
-    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
-
-    /* update size of current record appropriately */
-    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
-                                                 psDBF->nRecordLength);
-
-    /* we're done if we're dealing with not yet created .dbf */
-    if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
-        return TRUE;
-
-    /* force update of header with new header and record length */
-    psDBF->bNoHeader = TRUE;
-    DBFUpdateHeader( psDBF );
-
-    /* alloc record */
-    pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
-
-    /* shift records to their new positions */
-    for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
-    {
-        nRecordOffset = 
-            nOldRecordLength * (SAOffset) iRecord + nOldHeaderLength;
-
-        /* load record */
-        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-        psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
-
-        nRecordOffset = 
-            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-        /* move record in two steps */
-        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-        psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
-        psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
-                              nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
-                              1, psDBF->fp );
-
-    }
-
-    /* TODO: truncate file */
-
-    /* free record */
-    free(pszRecord);
-
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                          DBFReorderFields()                          */
-/*                                                                      */
-/*      Reorder the fields of a .dbf file                               */
-/*                                                                      */
-/* panMap must be exactly psDBF->nFields long and be a permutation      */
-/* of [0, psDBF->nFields-1]. This assumption will not be asserted in the*/
-/* code of DBFReorderFields.                                            */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFReorderFields( DBFHandle psDBF, int* panMap )
-{
-    SAOffset nRecordOffset;
-    int      i, iRecord;
-    int     *panFieldOffsetNew;
-    int     *panFieldSizeNew;
-    int     *panFieldDecimalsNew;
-    char    *pachFieldTypeNew;
-    char    *pszHeaderNew;
-    char    *pszRecord;
-    char    *pszRecordNew;
-
-    if ( psDBF->nFields == 0 )
-        return TRUE;
-
-    /* make sure that everything is written in .dbf */
-    if( !DBFFlushRecord( psDBF ) )
-        return FALSE;
-
-    panFieldOffsetNew = (int *) malloc(sizeof(int) * psDBF->nFields);
-    panFieldSizeNew = (int *) malloc(sizeof(int) *  psDBF->nFields);
-    panFieldDecimalsNew = (int *) malloc(sizeof(int) *  psDBF->nFields);
-    pachFieldTypeNew = (char *) malloc(sizeof(char) *  psDBF->nFields);
-    pszHeaderNew = (char*) malloc(sizeof(char) * 32 *  psDBF->nFields);
-
-    /* shuffle fields definitions */
-    for(i=0; i < psDBF->nFields; i++)
-    {
-        panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
-        panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
-        pachFieldTypeNew[i] = psDBF->pachFieldType[panMap[i]];
-        memcpy(pszHeaderNew + i * 32,
-               psDBF->pszHeader + panMap[i] * 32, 32);
-    }
-    panFieldOffsetNew[0] = 1;
-    for(i=1; i < psDBF->nFields; i++)
-    {
-        panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
-    }
-
-    free(psDBF->pszHeader);
-    psDBF->pszHeader = pszHeaderNew;
-
-    /* we're done if we're dealing with not yet created .dbf */
-    if ( !(psDBF->bNoHeader && psDBF->nRecords == 0) )
-    {
-        /* force update of header with new header and record length */
-        psDBF->bNoHeader = TRUE;
-        DBFUpdateHeader( psDBF );
-
-        /* alloc record */
-        pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
-        pszRecordNew = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
-
-        /* shuffle fields in records */
-        for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
-        {
-            nRecordOffset =
-                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-            /* load record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FRead( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
-            pszRecordNew[0] = pszRecord[0];
-
-            for(i=0; i < psDBF->nFields; i++)
-            {
-                memcpy(pszRecordNew + panFieldOffsetNew[i],
-                       pszRecord + psDBF->panFieldOffset[panMap[i]],
-                       psDBF->panFieldSize[panMap[i]]);
-            }
-
-            /* write record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FWrite( pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp );
-        }
-
-        /* free record */
-        free(pszRecord);
-        free(pszRecordNew);
-    }
-
-    free(psDBF->panFieldOffset);
-    free(psDBF->panFieldSize);
-    free(psDBF->panFieldDecimals);
-    free(psDBF->pachFieldType);
-
-    psDBF->panFieldOffset = panFieldOffsetNew;
-    psDBF->panFieldSize = panFieldSizeNew;
-    psDBF->panFieldDecimals =panFieldDecimalsNew;
-    psDBF->pachFieldType = pachFieldTypeNew;
-
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-
-    return TRUE;
-}
-
-
-/************************************************************************/
-/*                          DBFAlterFieldDefn()                         */
-/*                                                                      */
-/*      Alter a field definition in a .dbf file                         */
-/************************************************************************/
-
-int SHPAPI_CALL
-DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
-                    char chType, int nWidth, int nDecimals )
-{
-    int   i;
-    int   iRecord;
-    int   nOffset;
-    int   nOldWidth;
-    int   nOldRecordLength;
-    int   nRecordOffset;
-    char* pszFInfo;
-    char  chOldType;
-    int   bIsNULL;
-    char chFieldFill;
-
-    if (iField < 0 || iField >= psDBF->nFields)
-        return FALSE;
-
-    /* make sure that everything is written in .dbf */
-    if( !DBFFlushRecord( psDBF ) )
-        return FALSE;
-
-    chFieldFill = DBFGetNullCharacter(chType);
-
-    chOldType = psDBF->pachFieldType[iField];
-    nOffset = psDBF->panFieldOffset[iField];
-    nOldWidth = psDBF->panFieldSize[iField];
-    nOldRecordLength = psDBF->nRecordLength;
-
-/* -------------------------------------------------------------------- */
-/*      Do some checking to ensure we can add records to this file.     */
-/* -------------------------------------------------------------------- */
-    if( nWidth < 1 )
-        return -1;
-
-    if( nWidth > 255 )
-        nWidth = 255;
-
-/* -------------------------------------------------------------------- */
-/*      Assign the new field information fields.                        */
-/* -------------------------------------------------------------------- */
-    psDBF->panFieldSize[iField] = nWidth;
-    psDBF->panFieldDecimals[iField] = nDecimals;
-    psDBF->pachFieldType[iField] = chType;
-
-/* -------------------------------------------------------------------- */
-/*      Update the header information.                                  */
-/* -------------------------------------------------------------------- */
-    pszFInfo = psDBF->pszHeader + 32 * iField;
-
-    for( i = 0; i < 32; i++ )
-        pszFInfo[i] = '\0';
-
-    if( (int) strlen(pszFieldName) < 10 )
-        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
-    else
-        strncpy( pszFInfo, pszFieldName, 10);
-
-    pszFInfo[11] = psDBF->pachFieldType[iField];
-
-    if( chType == 'C' )
-    {
-        pszFInfo[16] = (unsigned char) (nWidth % 256);
-        pszFInfo[17] = (unsigned char) (nWidth / 256);
-    }
-    else
-    {
-        pszFInfo[16] = (unsigned char) nWidth;
-        pszFInfo[17] = (unsigned char) nDecimals;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Update offsets                                                  */
-/* -------------------------------------------------------------------- */
-    if (nWidth != nOldWidth)
-    {
-        for (i = iField + 1; i < psDBF->nFields; i++)
-             psDBF->panFieldOffset[i] += nWidth - nOldWidth;
-        psDBF->nRecordLength += nWidth - nOldWidth;
-
-        psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
-                                                     psDBF->nRecordLength);
-    }
-
-    /* we're done if we're dealing with not yet created .dbf */
-    if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
-        return TRUE;
-
-    /* force update of header with new header and record length */
-    psDBF->bNoHeader = TRUE;
-    DBFUpdateHeader( psDBF );
-
-    if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
-    {
-        char* pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
-        char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
-
-        pszOldField[nOldWidth] = 0;
-
-        /* move records to their new positions */
-        for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
-        {
-            nRecordOffset =
-                nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-            /* load record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
-
-            memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
-            bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
-
-            if (nWidth != nOldWidth)
-            {
-                if ((chOldType == 'N' || chOldType == 'F') && pszOldField[0] == ' ')
-                {
-                    /* Strip leading spaces when truncating a numeric field */
-                    memmove( pszRecord + nOffset,
-                            pszRecord + nOffset + nOldWidth - nWidth,
-                            nWidth );
-                }
-                if (nOffset + nOldWidth < nOldRecordLength)
-                {
-                    memmove( pszRecord + nOffset + nWidth,
-                            pszRecord + nOffset + nOldWidth,
-                            nOldRecordLength - (nOffset + nOldWidth));
-                }
-            }
-
-            /* Convert null value to the appropriate value of the new type */
-            if (bIsNULL)
-            {
-                memset( pszRecord + nOffset, chFieldFill, nWidth);
-            }
-
-            nRecordOffset =
-                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-            /* write record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
-        }
-
-        free(pszRecord);
-        free(pszOldField);
-    }
-    else if (nWidth > nOldWidth)
-    {
-        char* pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
-        char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
-
-        pszOldField[nOldWidth] = 0;
-
-        /* move records to their new positions */
-        for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
-        {
-            nRecordOffset =
-                nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-            /* load record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
-
-            memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
-            bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
-
-            if (nOffset + nOldWidth < nOldRecordLength)
-            {
-                memmove( pszRecord + nOffset + nWidth,
-                         pszRecord + nOffset + nOldWidth,
-                         nOldRecordLength - (nOffset + nOldWidth));
-            }
-
-            /* Convert null value to the appropriate value of the new type */
-            if (bIsNULL)
-            {
-                memset( pszRecord + nOffset, chFieldFill, nWidth);
-            }
-            else
-            {
-                if ((chOldType == 'N' || chOldType == 'F'))
-                {
-                    /* Add leading spaces when expanding a numeric field */
-                    memmove( pszRecord + nOffset + nWidth - nOldWidth,
-                             pszRecord + nOffset, nOldWidth );
-                    memset( pszRecord + nOffset, ' ', nWidth - nOldWidth );
-                }
-                else
-                {
-                    /* Add trailing spaces */
-                    memset(pszRecord + nOffset + nOldWidth, ' ', nWidth - nOldWidth);
-                }
-            }
-
-            nRecordOffset =
-                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
-
-            /* write record */
-            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
-            psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
-        }
-
-        free(pszRecord);
-        free(pszOldField);
-    }
-
-    psDBF->nCurrentRecord = -1;
-    psDBF->bCurrentRecordModified = FALSE;
-
-    return TRUE;
-}
diff --git a/src/HYDROData/shapelib/safileio.c b/src/HYDROData/shapelib/safileio.c
deleted file mode 100644 (file)
index f3affe2..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/******************************************************************************
- * $Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $
- *
- * Project:  Shapelib
- * Purpose:  Default implementation of file io based on stdio.
- * Author:   Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2007, 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: safileio.c,v $
- * Revision 1.4  2008-01-16 20:05:14  bram
- * Add file hooks that accept UTF-8 encoded filenames on some platforms.  Use SASetupUtf8Hooks
- *  tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability.  Currently, this
- *  is only available on the Windows platform that decodes the UTF-8 filenames to wide
- *  character strings and feeds them to _wfopen and _wremove.
- *
- * Revision 1.3  2007/12/18 18:28:11  bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.2  2007/12/15 20:25:30  bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function.  This is 
- * either the number from the LDID header field ("LDID/<number>") or as the 
- * content of an accompanying .CPG file.  When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.1  2007/12/06 06:56:41  fwarmerdam
- * new
- *
- */
-
-#include "shapefil.h"
-
-#include <math.h>
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-SHP_CVSID("$Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $");
-
-#ifdef SHPAPI_UTF8_HOOKS
-#   ifdef SHPAPI_WINDOWS
-#       define WIN32_LEAN_AND_MEAN
-#       define NOMINMAX
-#       include <windows.h>
-#       pragma comment(lib, "kernel32.lib")
-#   endif
-#endif
-
-/************************************************************************/
-/*                              SADFOpen()                              */
-/************************************************************************/
-
-SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
-
-{
-    return (SAFile) fopen( pszFilename, pszAccess );
-}
-
-/************************************************************************/
-/*                              SADFRead()                              */
-/************************************************************************/
-
-SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
-{
-    return (SAOffset) fread( p, (size_t) size, (size_t) nmemb, 
-                             (FILE *) file );
-}
-
-/************************************************************************/
-/*                             SADFWrite()                              */
-/************************************************************************/
-
-SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
-{
-    return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb, 
-                              (FILE *) file );
-}
-
-/************************************************************************/
-/*                              SADFSeek()                              */
-/************************************************************************/
-
-SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
-
-{
-    return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
-}
-
-/************************************************************************/
-/*                              SADFTell()                              */
-/************************************************************************/
-
-SAOffset SADFTell( SAFile file )
-
-{
-    return (SAOffset) ftell( (FILE *) file );
-}
-
-/************************************************************************/
-/*                             SADFFlush()                              */
-/************************************************************************/
-
-int SADFFlush( SAFile file )
-
-{
-    return fflush( (FILE *) file );
-}
-
-/************************************************************************/
-/*                             SADFClose()                              */
-/************************************************************************/
-
-int SADFClose( SAFile file )
-
-{
-    return fclose( (FILE *) file );
-}
-
-/************************************************************************/
-/*                             SADFClose()                              */
-/************************************************************************/
-
-int SADRemove( const char *filename )
-
-{
-    return remove( filename );
-}
-
-/************************************************************************/
-/*                              SADError()                              */
-/************************************************************************/
-
-void SADError( const char *message )
-
-{
-    fprintf( stderr, "%s\n", message );
-}
-
-/************************************************************************/
-/*                        SASetupDefaultHooks()                         */
-/************************************************************************/
-
-void SASetupDefaultHooks( SAHooks *psHooks )
-
-{
-    psHooks->FOpen   = SADFOpen;
-    psHooks->FRead   = SADFRead;
-    psHooks->FWrite  = SADFWrite;
-    psHooks->FSeek   = SADFSeek;
-    psHooks->FTell   = SADFTell;
-    psHooks->FFlush  = SADFFlush;
-    psHooks->FClose  = SADFClose;
-    psHooks->Remove  = SADRemove;
-
-    psHooks->Error   = SADError;
-    psHooks->Atof    = atof;
-}
-
-
-
-
-#ifdef SHPAPI_WINDOWS
-
-/************************************************************************/
-/*                          Utf8ToWideChar                              */
-/************************************************************************/
-
-const wchar_t* Utf8ToWideChar( const char *pszFilename )
-{
-    int nMulti, nWide;
-    wchar_t *pwszFileName;
-    
-    nMulti = strlen(pszFilename) + 1;
-    nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
-    if( nWide == 0 )
-    {
-        return NULL;
-    }
-    pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
-    if ( pwszFileName == NULL )
-    {
-        return NULL;
-    }
-    if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
-    {
-        free( pwszFileName );
-        return NULL;
-    }
-    return pwszFileName;
-}
-
-/************************************************************************/
-/*                           SAUtf8WFOpen                               */
-/************************************************************************/
-
-SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
-{
-    SAFile file = NULL;
-    const wchar_t *pwszFileName, *pwszAccess;
-    pwszFileName = Utf8ToWideChar( pszFilename );
-    pwszAccess = Utf8ToWideChar( pszAccess );
-    if( pwszFileName != NULL && pwszFileName != NULL)
-    {
-        file = (SAFile) _wfopen( pwszFileName, pwszAccess );
-    }
-    free ((wchar_t*) pwszFileName);
-    free ((wchar_t*) pwszAccess);
-    return file;
-}
-
-/************************************************************************/
-/*                             SAUtf8WRemove()                          */
-/************************************************************************/
-
-int SAUtf8WRemove( const char *pszFilename )
-{
-    const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
-    int rc = -1; 
-    if( pwszFileName != NULL )
-    {
-        rc = _wremove( pwszFileName );
-    }
-    free ((wchar_t*) pwszFileName);
-    return rc;
-}
-
-#endif
-
-#ifdef SHPAPI_UTF8_HOOKS
-
-/************************************************************************/
-/*                          SASetupUtf8Hooks()                          */
-/************************************************************************/
-
-void SASetupUtf8Hooks( SAHooks *psHooks )
-{
-#ifdef SHPAPI_WINDOWS    
-    psHooks->FOpen   = SAUtf8WFOpen;
-    psHooks->Remove  = SAUtf8WRemove;
-#else
-#   error "no implementations of UTF-8 hooks available for this platform"
-#endif
-    psHooks->FRead   = SADFRead;
-    psHooks->FWrite  = SADFWrite;
-    psHooks->FSeek   = SADFSeek;
-    psHooks->FTell   = SADFTell;
-    psHooks->FFlush  = SADFFlush;
-    psHooks->FClose  = SADFClose;
-
-    psHooks->Error   = SADError;
-    psHooks->Atof    = atof;
-}
-
-#endif
diff --git a/src/HYDROData/shapelib/shapefil.h b/src/HYDROData/shapelib/shapefil.h
deleted file mode 100644 (file)
index 1df356c..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-#ifndef SHAPEFILE_H_INCLUDED
-#define SHAPEFILE_H_INCLUDED
-
-/******************************************************************************
- * $Id: shapefil.h,v 1.52 2011-12-11 22:26:46 fwarmerdam Exp $
- *
- * Project:  Shapelib
- * Purpose:  Primary include file for Shapelib.
- * Author:   Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 1999, 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: shapefil.h,v $
- * Revision 1.52  2011-12-11 22:26:46  fwarmerdam
- * upgrade .qix access code to use SAHooks (gdal #3365)
- *
- * Revision 1.51  2011-07-24 05:59:25  fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.50  2011-05-13 17:35:17  fwarmerdam
- * added DBFReorderFields() and DBFAlterFields() functions (from Even)
- *
- * Revision 1.49  2011-04-16 14:38:21  fwarmerdam
- * avoid warnings with gcc on SHP_CVSID
- *
- * Revision 1.48  2010-08-27 23:42:52  fwarmerdam
- * add SHPAPI_CALL attribute in code
- *
- * Revision 1.47  2010-01-28 11:34:34  fwarmerdam
- * handle the shape file length limits more gracefully (#3236)
- *
- * Revision 1.46  2008-11-12 14:28:15  fwarmerdam
- * DBFCreateField() now works on files with records
- *
- * Revision 1.45  2008/11/11 17:47:10  fwarmerdam
- * added DBFDeleteField() function
- *
- * Revision 1.44  2008/01/16 20:05:19  bram
- * Add file hooks that accept UTF-8 encoded filenames on some platforms.  Use SASetupUtf8Hooks
- *  tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability.  Currently, this
- *  is only available on the Windows platform that decodes the UTF-8 filenames to wide
- *  character strings and feeds them to _wfopen and _wremove.
- *
- * Revision 1.43  2008/01/10 16:35:30  fwarmerdam
- * avoid _ prefix on #defined symbols (bug 1840)
- *
- * Revision 1.42  2007/12/18 18:28:14  bram
- * - create hook for client specific atof (bugzilla ticket 1615)
- * - check for NULL handle before closing cpCPG file, and close after reading.
- *
- * Revision 1.41  2007/12/15 20:25:32  bram
- * dbfopen.c now reads the Code Page information from the DBF file, and exports
- * this information as a string through the DBFGetCodePage function.  This is 
- * either the number from the LDID header field ("LDID/<number>") or as the 
- * content of an accompanying .CPG file.  When creating a DBF file, the code can
- * be set using DBFCreateEx.
- *
- * Revision 1.40  2007/12/06 07:00:25  fwarmerdam
- * dbfopen now using SAHooks for fileio
- *
- * Revision 1.39  2007/12/04 20:37:56  fwarmerdam
- * preliminary implementation of hooks api for io and errors
- *
- * Revision 1.38  2007/11/21 22:39:56  fwarmerdam
- * close shx file in readonly mode (GDAL #1956)
- *
- * Revision 1.37  2007/10/27 03:31:14  fwarmerdam
- * limit default depth of tree to 12 levels (gdal ticket #1594)
- *
- * Revision 1.36  2007/09/10 23:33:15  fwarmerdam
- * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
- * of GDAL (gdal ticket #1810).
- *
- * Revision 1.35  2007/09/03 19:48:10  fwarmerdam
- * move DBFReadAttribute() static dDoubleField into dbfinfo
- *
- * Revision 1.34  2006/06/17 15:33:32  fwarmerdam
- * added pszWorkField - bug 1202 (rso)
- *
- * Revision 1.33  2006/02/15 01:14:30  fwarmerdam
- * added DBFAddNativeFieldType
- *
- * Revision 1.32  2006/01/26 15:07:32  fwarmerdam
- * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
- *
- * Revision 1.31  2006/01/05 01:27:27  fwarmerdam
- * added dbf deletion mark/fetch
- *
- * Revision 1.30  2005/01/03 22:30:13  fwarmerdam
- * added support for saved quadtrees
- *
- * Revision 1.29  2004/09/26 20:09:35  fwarmerdam
- * avoid rcsid warnings
- *
- * Revision 1.28  2003/12/29 06:02:18  fwarmerdam
- * added cpl_error.h option
- *
- * Revision 1.27  2003/04/21 18:30:37  warmerda
- * added header write/update public methods
- *
- * Revision 1.26  2002/09/29 00:00:08  warmerda
- * added FTLogical and logical attribute read/write calls
- *
- * Revision 1.25  2002/05/07 13:46:30  warmerda
- * added DBFWriteAttributeDirectly().
- *
- * Revision 1.24  2002/04/10 16:59:54  warmerda
- * added SHPRewindObject
- *
- * Revision 1.23  2002/01/15 14:36:07  warmerda
- * updated email address
- *
- * Revision 1.22  2002/01/15 14:32:00  warmerda
- * try to improve SHPAPI_CALL docs
- */
-
-#include <stdio.h>
-
-#ifdef USE_DBMALLOC
-#include <dbmalloc.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************/
-/*                        Configuration options.                        */
-/************************************************************************/
-
-/* -------------------------------------------------------------------- */
-/*      Should the DBFReadStringAttribute() strip leading and           */
-/*      trailing white space?                                           */
-/* -------------------------------------------------------------------- */
-#define TRIM_DBF_WHITESPACE
-
-/* -------------------------------------------------------------------- */
-/*      Should we write measure values to the Multipatch object?        */
-/*      Reportedly ArcView crashes if we do write it, so for now it     */
-/*      is disabled.                                                    */
-/* -------------------------------------------------------------------- */
-#define DISABLE_MULTIPATCH_MEASURE
-    
-/* -------------------------------------------------------------------- */
-/*      SHPAPI_CALL                                                     */
-/*                                                                      */
-/*      The following two macros are present to allow forcing           */
-/*      various calling conventions on the Shapelib API.                */
-/*                                                                      */
-/*      To force __stdcall conventions (needed to call Shapelib         */
-/*      from Visual Basic and/or Dephi I believe) the makefile could    */
-/*      be modified to define:                                          */
-/*                                                                      */
-/*        /DSHPAPI_CALL=__stdcall                                       */
-/*                                                                      */
-/*      If it is desired to force export of the Shapelib API without    */
-/*      using the shapelib.def file, use the following definition.      */
-/*                                                                      */
-/*        /DSHAPELIB_DLLEXPORT                                          */
-/*                                                                      */
-/*      To get both at once it will be necessary to hack this           */
-/*      include file to define:                                         */
-/*                                                                      */
-/*        #define SHPAPI_CALL __declspec(dllexport) __stdcall           */
-/*        #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall        */
-/*                                                                      */
-/*      The complexity of the situtation is partly caused by the        */
-/*      peculiar requirement of Visual C++ that __stdcall appear        */
-/*      after any "*"'s in the return value of a function while the     */
-/*      __declspec(dllexport) must appear before them.                  */
-/* -------------------------------------------------------------------- */
-
-#ifdef WIN32
-  #define SHAPELIB_DLLEXPORT 1
-#endif
-
-#ifdef SHAPELIB_DLLEXPORT
-#  define SHPAPI_CALL __declspec(dllexport)
-#  define SHPAPI_CALL1(x)  __declspec(dllexport) x
-#endif
-
-#ifndef SHPAPI_CALL
-#  if defined(USE_GCC_VISIBILITY_FLAG)
-#    define SHPAPI_CALL     __attribute__ ((visibility("default")))
-#    define SHPAPI_CALL1(x) __attribute__ ((visibility("default")))     x
-#  else
-#    define SHPAPI_CALL
-#  endif
-#endif
-
-#ifndef SHPAPI_CALL1
-#  define SHPAPI_CALL1(x)      x SHPAPI_CALL
-#endif
-    
-/* -------------------------------------------------------------------- */
-/*      Macros for controlling CVSID and ensuring they don't appear     */
-/*      as unreferenced variables resulting in lots of warnings.        */
-/* -------------------------------------------------------------------- */
-#ifndef DISABLE_CVSID
-#  if defined(__GNUC__) && __GNUC__ >= 4
-#    define SHP_CVSID(string)     static char cpl_cvsid[] __attribute__((used)) = string;
-#  else
-#    define SHP_CVSID(string)     static char cpl_cvsid[] = string; \
-static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : cpl_cvsid ); }
-#  endif
-#else
-#  define SHP_CVSID(string)
-#endif
-
-/* -------------------------------------------------------------------- */
-/*      On some platforms, additional file IO hooks are defined that    */
-/*      UTF-8 encoded filenames Unicode filenames                       */
-/* -------------------------------------------------------------------- */
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-#      define SHPAPI_WINDOWS
-#      define SHPAPI_UTF8_HOOKS
-#endif
-
-/* -------------------------------------------------------------------- */
-/*      IO/Error hook functions.                                        */
-/* -------------------------------------------------------------------- */
-typedef int *SAFile;
-
-#ifndef SAOffset
-typedef unsigned long SAOffset;
-#endif
-
-typedef struct {
-    SAFile     (*FOpen) ( const char *filename, const char *access);
-    SAOffset   (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
-    SAOffset   (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
-    SAOffset   (*FSeek) ( SAFile file, SAOffset offset, int whence );
-    SAOffset   (*FTell) ( SAFile file );
-    int        (*FFlush)( SAFile file );
-    int        (*FClose)( SAFile file );
-    int        (*Remove) ( const char *filename );
-
-    void       (*Error) ( const char *message );
-    double     (*Atof)  ( const char *str );
-} SAHooks;
-
-void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
-#ifdef SHPAPI_UTF8_HOOKS
-void SHPAPI_CALL SASetupUtf8Hooks( SAHooks *psHooks );
-#endif
-
-/************************************************************************/
-/*                             SHP Support.                             */
-/************************************************************************/
-typedef        struct
-{
-    SAHooks sHooks;
-
-    SAFile      fpSHP;
-    SAFile     fpSHX;
-
-    int                nShapeType;                             /* SHPT_* */
-    
-    unsigned int       nFileSize;                              /* SHP file */
-
-    int         nRecords;
-    int                nMaxRecords;
-    unsigned int               *panRecOffset;
-    unsigned int               *panRecSize;
-
-    double     adBoundsMin[4];
-    double     adBoundsMax[4];
-
-    int                bUpdated;
-
-    unsigned char *pabyRec;
-    int         nBufSize;
-} SHPInfo;
-
-typedef SHPInfo * SHPHandle;
-
-/* -------------------------------------------------------------------- */
-/*      Shape types (nSHPType)                                          */
-/* -------------------------------------------------------------------- */
-#define SHPT_NULL      0
-#define SHPT_POINT     1
-#define SHPT_ARC       3
-#define SHPT_POLYGON   5
-#define SHPT_MULTIPOINT        8
-#define SHPT_POINTZ    11
-#define SHPT_ARCZ      13
-#define SHPT_POLYGONZ  15
-#define SHPT_MULTIPOINTZ 18
-#define SHPT_POINTM    21
-#define SHPT_ARCM      23
-#define SHPT_POLYGONM  25
-#define SHPT_MULTIPOINTM 28
-#define SHPT_MULTIPATCH 31
-
-
-/* -------------------------------------------------------------------- */
-/*      Part types - everything but SHPT_MULTIPATCH just uses           */
-/*      SHPP_RING.                                                      */
-/* -------------------------------------------------------------------- */
-
-#define SHPP_TRISTRIP  0
-#define SHPP_TRIFAN    1
-#define SHPP_OUTERRING 2
-#define SHPP_INNERRING 3
-#define SHPP_FIRSTRING 4
-#define SHPP_RING      5
-
-/* -------------------------------------------------------------------- */
-/*      SHPObject - represents on shape (without attributes) read       */
-/*      from the .shp file.                                             */
-/* -------------------------------------------------------------------- */
-typedef struct
-{
-    int                nSHPType;
-
-    int                nShapeId; /* -1 is unknown/unassigned */
-
-    int                nParts;
-    int                *panPartStart;
-    int                *panPartType;
-    
-    int                nVertices;
-    double     *padfX;
-    double     *padfY;
-    double     *padfZ;
-    double     *padfM;
-
-    double     dfXMin;
-    double     dfYMin;
-    double     dfZMin;
-    double     dfMMin;
-
-    double     dfXMax;
-    double     dfYMax;
-    double     dfZMax;
-    double     dfMMax;
-
-    int                bMeasureIsUsed;
-} SHPObject;
-
-/* -------------------------------------------------------------------- */
-/*      SHP API Prototypes                                              */
-/* -------------------------------------------------------------------- */
-
-/* If pszAccess is read-only, the fpSHX field of the returned structure */
-/* will be NULL as it is not necessary to keep the SHX file open */
-SHPHandle SHPAPI_CALL
-      SHPOpen( const char * pszShapeFile, const char * pszAccess );
-SHPHandle SHPAPI_CALL
-      SHPOpenLL( const char *pszShapeFile, const char *pszAccess, 
-                 SAHooks *psHooks );
-SHPHandle SHPAPI_CALL
-      SHPCreate( const char * pszShapeFile, int nShapeType );
-SHPHandle SHPAPI_CALL
-      SHPCreateLL( const char * pszShapeFile, int nShapeType,
-                   SAHooks *psHooks );
-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, 
-                       const int * panPartStart, const int * panPartType,
-                       int nVertices, 
-                       const double * padfX, const double * padfY,
-                       const double * padfZ, const double * padfM );
-SHPObject SHPAPI_CALL1(*)
-      SHPCreateSimpleObject( int nSHPType, int nVertices,
-                             const double * padfX, 
-                             const double * padfY, 
-                             const double * padfZ );
-
-int SHPAPI_CALL
-      SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
-
-void SHPAPI_CALL SHPClose( SHPHandle hSHP );
-void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP );
-
-const char SHPAPI_CALL1(*)
-      SHPTypeName( int nSHPType );
-const char SHPAPI_CALL1(*)
-      SHPPartTypeName( int nPartType );
-
-/* -------------------------------------------------------------------- */
-/*      Shape quadtree indexing API.                                    */
-/* -------------------------------------------------------------------- */
-
-/* this can be two or four for binary or quad tree */
-#define MAX_SUBNODE    4
-
-/* upper limit of tree levels for automatic estimation */
-#define MAX_DEFAULT_TREE_DEPTH 12
-
-typedef struct shape_tree_node
-{
-    /* region covered by this node */
-    double     adfBoundsMin[4];
-    double     adfBoundsMax[4];
-
-    /* list of shapes stored at this node.  The papsShapeObj pointers
-       or the whole list can be NULL */
-    int                nShapeCount;
-    int                *panShapeIds;
-    SHPObject   **papsShapeObj;
-
-    int                nSubNodes;
-    struct shape_tree_node *apsSubNode[MAX_SUBNODE];
-    
-} SHPTreeNode;
-
-typedef struct
-{
-    SHPHandle   hSHP;
-    
-    int                nMaxDepth;
-    int                nDimension;
-    int         nTotalCount;
-    
-    SHPTreeNode        *psRoot;
-} SHPTree;
-
-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 );
-
-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 );
-
-int SHPAPI_CALL1(*) 
-SHPSearchDiskTree( FILE *fp, 
-                   double *padfBoundsMin, double *padfBoundsMax,
-                   int *pnShapeCount );
-
-
-typedef struct SHPDiskTreeInfo* SHPTreeDiskHandle;
-
-SHPTreeDiskHandle SHPAPI_CALL
-    SHPOpenDiskTree( const char* pszQIXFilename,
-                     SAHooks *psHooks );
-
-void SHPAPI_CALL
-    SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree );
-
-int SHPAPI_CALL1(*) 
-SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, 
-                   double *padfBoundsMin, double *padfBoundsMax,
-                   int *pnShapeCount );
-
-int SHPAPI_CALL
-    SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename, SAHooks *psHooks );
-
-/************************************************************************/
-/*                             DBF Support.                             */
-/************************************************************************/
-typedef        struct
-{
-    SAHooks sHooks;
-
-    SAFile     fp;
-
-    int         nRecords;
-
-    int                nRecordLength;
-    int                nHeaderLength;
-    int                nFields;
-    int                *panFieldOffset;
-    int                *panFieldSize;
-    int                *panFieldDecimals;
-    char       *pachFieldType;
-
-    char       *pszHeader;
-
-    int                nCurrentRecord;
-    int                bCurrentRecordModified;
-    char       *pszCurrentRecord;
-
-    int         nWorkFieldLength;
-    char        *pszWorkField;
-    
-    int                bNoHeader;
-    int                bUpdated;
-
-    double      dfDoubleField;
-
-    int         iLanguageDriver;
-    char        *pszCodePage;
-} DBFInfo;
-
-typedef DBFInfo * DBFHandle;
-
-typedef enum {
-  FTString,
-  FTInteger,
-  FTDouble,
-  FTLogical,
-  FTInvalid
-} DBFFieldType;
-
-#define XBASE_FLDHDR_SZ       32
-
-
-DBFHandle SHPAPI_CALL
-      DBFOpen( const char * pszDBFFile, const char * pszAccess );
-DBFHandle SHPAPI_CALL
-      DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
-                 SAHooks *psHooks );
-DBFHandle SHPAPI_CALL
-      DBFCreate( const char * pszDBFFile );
-DBFHandle SHPAPI_CALL
-      DBFCreateEx( const char * pszDBFFile, const char * pszCodePage );
-DBFHandle SHPAPI_CALL
-      DBFCreateLL( const char * pszDBFFile, const char * pszCodePage, SAHooks *psHooks );
-
-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 );
-
-int    SHPAPI_CALL
-      DBFAddNativeFieldType( DBFHandle hDBF, const char * pszFieldName,
-                             char chType, int nWidth, int nDecimals );
-
-int    SHPAPI_CALL
-      DBFDeleteField( DBFHandle hDBF, int iField );
-
-int SHPAPI_CALL
-      DBFReorderFields( DBFHandle psDBF, int* panMap );
-
-int SHPAPI_CALL
-      DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
-                         char chType, 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 );
-const char SHPAPI_CALL1(*)
-      DBFReadLogicalAttribute( 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 );
-
-int SHPAPI_CALL
-     DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
-                              const char lFieldValue);
-int SHPAPI_CALL
-     DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
-                               void * pValue );
-const char SHPAPI_CALL1(*)
-      DBFReadTuple(DBFHandle psDBF, int hEntity );
-int SHPAPI_CALL
-      DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
-
-int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape );
-int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape, 
-                                      int bIsDeleted );
-
-DBFHandle SHPAPI_CALL
-      DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
-void   SHPAPI_CALL
-      DBFClose( DBFHandle hDBF );
-void    SHPAPI_CALL
-      DBFUpdateHeader( DBFHandle hDBF );
-char    SHPAPI_CALL
-      DBFGetNativeFieldType( DBFHandle hDBF, int iField );
-
-const char SHPAPI_CALL1(*)
-      DBFGetCodePage(DBFHandle psDBF );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ndef SHAPEFILE_H_INCLUDED */
diff --git a/src/HYDROData/shapelib/shpopen.c b/src/HYDROData/shapelib/shpopen.c
deleted file mode 100644 (file)
index ee9fce5..0000000
+++ /dev/null
@@ -1,2388 +0,0 @@
-/******************************************************************************
- * $Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $
- *
- * Project:  Shapelib
- * Purpose:  Implementation of core Shapefile read/write functions.
- * Author:   Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: shpopen.c,v $
- * Revision 1.73  2012-01-24 22:33:01  fwarmerdam
- * fix memory leak on failure to open .shp (gdal #4410)
- *
- * Revision 1.72  2011-12-11 22:45:28  fwarmerdam
- * fix failure return from SHPOpenLL.
- *
- * Revision 1.71  2011-09-15 03:33:58  fwarmerdam
- * fix missing cast (#2344)
- *
- * Revision 1.70  2011-07-24 05:59:25  fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.69  2011-07-24 03:24:22  fwarmerdam
- * fix memory leaks in error cases creating shapefiles (#2061)
- *
- * Revision 1.68  2010-08-27 23:42:52  fwarmerdam
- * add SHPAPI_CALL attribute in code
- *
- * Revision 1.67  2010-07-01 08:15:48  fwarmerdam
- * do not error out on an object with zero vertices
- *
- * Revision 1.66  2010-07-01 07:58:57  fwarmerdam
- * minor cleanup of error handling
- *
- * Revision 1.65  2010-07-01 07:27:13  fwarmerdam
- * white space formatting adjustments
- *
- * Revision 1.64  2010-01-28 11:34:34  fwarmerdam
- * handle the shape file length limits more gracefully (#3236)
- *
- * Revision 1.63  2010-01-28 04:04:40  fwarmerdam
- * improve numerical accuracy of SHPRewind() algs (gdal #3363)
- *
- * Revision 1.62  2010-01-17 05:34:13  fwarmerdam
- * Remove asserts on x/y being null (#2148).
- *
- * Revision 1.61  2010-01-16 05:07:42  fwarmerdam
- * allow 0/nulls in shpcreateobject (#2148)
- *
- * Revision 1.60  2009-09-17 20:50:02  bram
- * on Win32, define snprintf as alias to _snprintf
- *
- * Revision 1.59  2008-03-14 05:25:31  fwarmerdam
- * Correct crash on buggy geometries (gdal #2218)
- *
- * Revision 1.58  2008/01/08 23:28:26  bram
- * on line 2095, use a float instead of a double to avoid a compiler warning
- *
- * Revision 1.57  2007/12/06 07:00:25  fwarmerdam
- * dbfopen now using SAHooks for fileio
- *
- * Revision 1.56  2007/12/04 20:37:56  fwarmerdam
- * preliminary implementation of hooks api for io and errors
- *
- * Revision 1.55  2007/11/21 22:39:56  fwarmerdam
- * close shx file in readonly mode (GDAL #1956)
- *
- * Revision 1.54  2007/11/15 00:12:47  mloskot
- * Backported recent changes from GDAL (Ticket #1415) to Shapelib.
- *
- * Revision 1.53  2007/11/14 22:31:08  fwarmerdam
- * checks after mallocs to detect for corrupted/voluntary broken shapefiles.
- * http://trac.osgeo.org/gdal/ticket/1991
- *
- * Revision 1.52  2007/06/21 15:58:33  fwarmerdam
- * fix for SHPRewindObject when rings touch at one vertex (gdal #976)
- *
- * Revision 1.51  2006/09/04 15:24:01  fwarmerdam
- * Fixed up log message for 1.49.
- *
- * Revision 1.50  2006/09/04 15:21:39  fwarmerdam
- * fix of last fix
- *
- * Revision 1.49  2006/09/04 15:21:00  fwarmerdam
- * MLoskot: Added stronger test of Shapefile reading failures, e.g. truncated
- * files.  The problem was discovered by Tim Sutton and reported here
- *   https://svn.qgis.org/trac/ticket/200
- *
- * Revision 1.48  2006/01/26 15:07:32  fwarmerdam
- * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
- *
- * Revision 1.47  2006/01/04 20:07:23  fwarmerdam
- * In SHPWriteObject() make sure that the record length is updated
- * when rewriting an existing record.
- *
- * Revision 1.46  2005/02/11 17:17:46  fwarmerdam
- * added panPartStart[0] validation
- *
- * Revision 1.45  2004/09/26 20:09:48  fwarmerdam
- * const correctness changes
- *
- * Revision 1.44  2003/12/29 00:18:39  fwarmerdam
- * added error checking for failed IO and optional CPL error reporting
- *
- * Revision 1.43  2003/12/01 16:20:08  warmerda
- * be careful of zero vertex shapes
- *
- * Revision 1.42  2003/12/01 14:58:27  warmerda
- * added degenerate object check in SHPRewindObject()
- *
- * Revision 1.41  2003/07/08 15:22:43  warmerda
- * avoid warning
- *
- * Revision 1.40  2003/04/21 18:30:37  warmerda
- * added header write/update public methods
- *
- * Revision 1.39  2002/08/26 06:46:56  warmerda
- * avoid c++ comments
- *
- * Revision 1.38  2002/05/07 16:43:39  warmerda
- * Removed debugging printf.
- *
- * Revision 1.37  2002/04/10 17:35:22  warmerda
- * fixed bug in ring reversal code
- *
- * Revision 1.36  2002/04/10 16:59:54  warmerda
- * added SHPRewindObject
- *
- * Revision 1.35  2001/12/07 15:10:44  warmerda
- * fix if .shx fails to open
- *
- * 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
- *
- * Revision 1.25  1999/12/15 13:47:07  warmerda
- * Fixed record size settings in .shp file (was 4 words too long)
- * Added stdlib.h.
- *
- * Revision 1.24  1999/11/05 14:12:04  warmerda
- * updated license terms
- *
- * Revision 1.23  1999/07/27 00:53:46  warmerda
- * added support for rewriting shapes
- *
- * Revision 1.22  1999/06/11 19:19:11  warmerda
- * Cleanup pabyRec static buffer on SHPClose().
- *
- * Revision 1.21  1999/06/02 14:57:56  kshih
- * Remove unused variables
- *
- * Revision 1.20  1999/04/19 21:04:17  warmerda
- * Fixed syntax error.
- *
- * Revision 1.19  1999/04/19 21:01:57  warmerda
- * Force access string to binary in SHPOpen().
- *
- * Revision 1.18  1999/04/01 18:48:07  warmerda
- * Try upper case extensions if lower case doesn't work.
- *
- * Revision 1.17  1998/12/31 15:29:39  warmerda
- * Disable writing measure values to multipatch objects if
- * DISABLE_MULTIPATCH_MEASURE is defined.
- *
- * Revision 1.16  1998/12/16 05:14:33  warmerda
- * Added support to write MULTIPATCH.  Fixed reading Z coordinate of
- * MULTIPATCH. Fixed record size written for all feature types.
- *
- * Revision 1.15  1998/12/03 16:35:29  warmerda
- * r+b is proper binary access string, not rb+.
- *
- * Revision 1.14  1998/12/03 15:47:56  warmerda
- * Fixed setting of nVertices in SHPCreateObject().
- *
- * Revision 1.13  1998/12/03 15:33:54  warmerda
- * Made SHPCalculateExtents() separately callable.
- *
- * Revision 1.12  1998/11/11 20:01:50  warmerda
- * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines.
- *
- * Revision 1.11  1998/11/09 20:56:44  warmerda
- * Fixed up handling of file wide bounds.
- *
- * Revision 1.10  1998/11/09 20:18:51  warmerda
- * Converted to support 3D shapefiles, and use of SHPObject.
- *
- * Revision 1.9  1998/02/24 15:09:05  warmerda
- * Fixed memory leak.
- *
- * Revision 1.8  1997/12/04 15:40:29  warmerda
- * Fixed byte swapping of record number, and record length fields in the
- * .shp file.
- *
- * Revision 1.7  1995/10/21 03:15:58  warmerda
- * Added support for binary file access, the magic cookie 9997
- * and tried to improve the int32 selection logic for 16bit systems.
- *
- * Revision 1.6  1995/09/04  04:19:41  warmerda
- * Added fix for file bounds.
- *
- * Revision 1.5  1995/08/25  15:16:44  warmerda
- * Fixed a couple of problems with big endian systems ... one with bounds
- * and the other with multipart polygons.
- *
- * Revision 1.4  1995/08/24  18:10:17  warmerda
- * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc()
- * functions (such as on the Sun).
- *
- * Revision 1.3  1995/08/23  02:23:15  warmerda
- * Added support for reading bounds, and fixed up problems in setting the
- * file wide bounds.
- *
- * Revision 1.2  1995/08/04  03:16:57  warmerda
- * Added header.
- *
- */
-
-#include "shapefil.h"
-
-#include <math.h>
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-SHP_CVSID("$Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $")
-
-typedef unsigned char uchar;
-
-#if UINT_MAX == 65535
-typedef unsigned long        int32;
-#else
-typedef unsigned int         int32;
-#endif
-
-#ifndef FALSE
-#  define FALSE                0
-#  define TRUE         1
-#endif
-
-#define ByteCopy( a, b, c )    memcpy( b, a, c )
-#ifndef MAX
-#  define MIN(a,b)      ((a<b) ? a : b)
-#  define MAX(a,b)      ((a>b) ? a : b)
-#endif
-
-#if defined(WIN32) || defined(_WIN32)
-#  ifndef snprintf
-#     define snprintf _snprintf
-#  endif
-#endif
-
-static int     bBigEndian;
-
-
-/************************************************************************/
-/*                              SwapWord()                              */
-/*                                                                      */
-/*      Swap a 2, 4 or 8 byte word.                                     */
-/************************************************************************/
-
-static void    SwapWord( int length, void * wordP )
-
-{
-    int                i;
-    uchar      temp;
-
-    for( i=0; i < length/2; i++ )
-    {
-       temp = ((uchar *) wordP)[i];
-       ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1];
-       ((uchar *) wordP)[length-i-1] = temp;
-    }
-}
-
-/************************************************************************/
-/*                             SfRealloc()                              */
-/*                                                                      */
-/*      A realloc cover function that will access a NULL pointer as     */
-/*      a valid input.                                                  */
-/************************************************************************/
-
-static void * SfRealloc( void * pMem, int nNewSize )
-
-{
-    if( pMem == NULL )
-        return( (void *) malloc(nNewSize) );
-    else
-        return( (void *) realloc(pMem,nNewSize) );
-}
-
-/************************************************************************/
-/*                          SHPWriteHeader()                            */
-/*                                                                      */
-/*      Write out a header for the .shp and .shx files as well as the  */
-/*     contents of the index (.shx) file.                              */
-/************************************************************************/
-
-void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP )
-
-{
-    uchar      abyHeader[100];
-    int                i;
-    int32      i32;
-    double     dValue;
-    int32      *panSHX;
-    
-    if (psSHP->fpSHX == NULL)
-    {
-        psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed");
-        return;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Prepare header block for .shp file.                             */
-/* -------------------------------------------------------------------- */
-    for( i = 0; i < 100; i++ )
-        abyHeader[i] = 0;
-
-    abyHeader[2] = 0x27;                               /* magic cookie */
-    abyHeader[3] = 0x0a;
-
-    i32 = psSHP->nFileSize/2;                          /* 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 = psSHP->nShapeType;                           /* shape type */
-    ByteCopy( &i32, abyHeader+32, 4 );
-    if( bBigEndian ) SwapWord( 4, abyHeader+32 );
-
-    dValue = psSHP->adBoundsMin[0];                    /* set bounds */
-    ByteCopy( &dValue, abyHeader+36, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+36 );
-
-    dValue = psSHP->adBoundsMin[1];
-    ByteCopy( &dValue, abyHeader+44, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+44 );
-
-    dValue = psSHP->adBoundsMax[0];
-    ByteCopy( &dValue, abyHeader+52, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+52 );
-
-    dValue = psSHP->adBoundsMax[1];
-    ByteCopy( &dValue, abyHeader+60, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+60 );
-
-    dValue = psSHP->adBoundsMin[2];                    /* z */
-    ByteCopy( &dValue, abyHeader+68, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+68 );
-
-    dValue = psSHP->adBoundsMax[2];
-    ByteCopy( &dValue, abyHeader+76, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+76 );
-
-    dValue = psSHP->adBoundsMin[3];                    /* m */
-    ByteCopy( &dValue, abyHeader+84, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+84 );
-
-    dValue = psSHP->adBoundsMax[3];
-    ByteCopy( &dValue, abyHeader+92, 8 );
-    if( bBigEndian ) SwapWord( 8, abyHeader+92 );
-
-/* -------------------------------------------------------------------- */
-/*      Write .shp file header.                                         */
-/* -------------------------------------------------------------------- */
-    if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0 
-        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
-    {
-        psSHP->sHooks.Error( "Failure writing .shp header" );
-        return;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Prepare, and write .shx file header.                            */
-/* -------------------------------------------------------------------- */
-    i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2;   /* file size */
-    ByteCopy( &i32, abyHeader+24, 4 );
-    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
-    
-    if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0 
-        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
-    {
-        psSHP->sHooks.Error( "Failure writing .shx header" );
-        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)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) 
-        != psSHP->nRecords )
-    {
-        psSHP->sHooks.Error( "Failure writing .shx contents" );
-    }
-
-    free( panSHX );
-
-/* -------------------------------------------------------------------- */
-/*      Flush to disk.                                                  */
-/* -------------------------------------------------------------------- */
-    psSHP->sHooks.FFlush( psSHP->fpSHP );
-    psSHP->sHooks.FFlush( psSHP->fpSHX );
-}
-
-/************************************************************************/
-/*                              SHPOpen()                               */
-/************************************************************************/
-
-SHPHandle SHPAPI_CALL
-SHPOpen( const char * pszLayer, const char * pszAccess )
-
-{
-    SAHooks sHooks;
-
-    SASetupDefaultHooks( &sHooks );
-
-    return SHPOpenLL( pszLayer, pszAccess, &sHooks );
-}
-
-/************************************************************************/
-/*                              SHPOpen()                               */
-/*                                                                      */
-/*      Open the .shp and .shx files based on the basename of the       */
-/*      files or either file name.                                      */
-/************************************************************************/
-   
-SHPHandle SHPAPI_CALL
-SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
-
-{
-    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;
-    memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
-
-/* -------------------------------------------------------------------- */
-/*     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 = psSHP->sHooks.FOpen(pszFullname, pszAccess );
-    if( psSHP->fpSHP == NULL )
-    {
-        sprintf( pszFullname, "%s.SHP", pszBasename );
-        psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
-    }
-    
-    if( psSHP->fpSHP == NULL )
-    {
-        char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
-        sprintf( pszMessage, "Unable to open %s.shp or %s.SHP.", 
-                  pszBasename, pszBasename );
-        psHooks->Error( pszMessage );
-        free( pszMessage );
-
-        free( psSHP );
-        free( pszBasename );
-        free( pszFullname );
-
-        return NULL;
-    }
-
-    sprintf( pszFullname, "%s.shx", pszBasename );
-    psSHP->fpSHX =  psSHP->sHooks.FOpen(pszFullname, pszAccess );
-    if( psSHP->fpSHX == NULL )
-    {
-        sprintf( pszFullname, "%s.SHX", pszBasename );
-        psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
-    }
-    
-    if( psSHP->fpSHX == NULL )
-    {
-        char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
-        sprintf( pszMessage, "Unable to open %s.shx or %s.SHX.", 
-                  pszBasename, pszBasename );
-        psHooks->Error( pszMessage );
-        free( pszMessage );
-
-        psSHP->sHooks.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);
-    psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
-
-    psSHP->nFileSize = ((unsigned int)pabyBuf[24] * 256 * 256 * 256
-                        + (unsigned int)pabyBuf[25] * 256 * 256
-                        + (unsigned int)pabyBuf[26] * 256
-                        + (unsigned int)pabyBuf[27]) * 2;
-
-/* -------------------------------------------------------------------- */
-/*  Read SHX file Header info                                           */
-/* -------------------------------------------------------------------- */
-    if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 
-        || pabyBuf[0] != 0 
-        || pabyBuf[1] != 0 
-        || pabyBuf[2] != 0x27 
-        || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
-    {
-        psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
-        psSHP->sHooks.FClose( psSHP->fpSHP );
-        psSHP->sHooks.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 )
-    {
-        char szError[200];
-        
-        sprintf( szError, 
-                 "Record count in .shp header is %d, which seems\n"
-                 "unreasonable.  Assuming header is corrupt.",
-                 psSHP->nRecords );
-        psSHP->sHooks.Error( szError );                                       
-        psSHP->sHooks.FClose( psSHP->fpSHP );
-        psSHP->sHooks.FClose( psSHP->fpSHX );
-        free( psSHP );
-        free(pabyBuf);
-
-        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 = (unsigned int *)
-        malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
-    psSHP->panRecSize = (unsigned int *)
-        malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
-    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
-
-    if (psSHP->panRecOffset == NULL ||
-        psSHP->panRecSize == NULL ||
-        pabyBuf == NULL)
-    {
-        char szError[200];
-
-        sprintf(szError, 
-                "Not enough memory to allocate requested memory (nRecords=%d).\n"
-                "Probably broken SHP file", 
-                psSHP->nRecords );
-        psSHP->sHooks.Error( szError );
-        psSHP->sHooks.FClose( psSHP->fpSHP );
-        psSHP->sHooks.FClose( psSHP->fpSHX );
-        if (psSHP->panRecOffset) free( psSHP->panRecOffset );
-        if (psSHP->panRecSize) free( psSHP->panRecSize );
-        if (pabyBuf) free( pabyBuf );
-        free( psSHP );
-        return( NULL );
-    }
-
-    if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) 
-        != psSHP->nRecords )
-    {
-        char szError[200];
-
-        sprintf( szError, 
-                 "Failed to read all values for %d records in .shx file.",
-                 psSHP->nRecords );
-        psSHP->sHooks.Error( szError );
-
-        /* SHX is short or unreadable for some reason. */
-        psSHP->sHooks.FClose( psSHP->fpSHP );
-        psSHP->sHooks.FClose( psSHP->fpSHX );
-        free( psSHP->panRecOffset );
-        free( psSHP->panRecSize );
-        free( pabyBuf );
-        free( psSHP );
-
-        return( NULL );
-    }
-    
-    /* In read-only mode, we can close the SHX now */
-    if (strcmp(pszAccess, "rb") == 0)
-    {
-        psSHP->sHooks.FClose( psSHP->fpSHX );
-        psSHP->fpSHX = 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_CALL
-SHPClose(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 );
-
-    if ( psSHP->fpSHX != NULL)
-        psSHP->sHooks.FClose( psSHP->fpSHX );
-    psSHP->sHooks.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( 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 )
-            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 )
-
-{
-    SAHooks sHooks;
-
-    SASetupDefaultHooks( &sHooks );
-
-    return SHPCreateLL( pszLayer, nShapeType, &sHooks );
-}
-
-/************************************************************************/
-/*                             SHPCreate()                              */
-/*                                                                      */
-/*      Create a new shape file and return a handle to the open         */
-/*      shape file with read/write access.                              */
-/************************************************************************/
-
-SHPHandle SHPAPI_CALL
-SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks )
-
-{
-    char       *pszBasename = NULL, *pszFullname = NULL;
-    int                i;
-    SAFile     fpSHP = NULL, fpSHX = NULL;
-    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 = psHooks->FOpen(pszFullname, "wb" );
-    if( fpSHP == NULL )
-    {
-        psHooks->Error( "Failed to create file .shp file." );
-        goto error;
-    }
-
-    sprintf( pszFullname, "%s.shx", pszBasename );
-    fpSHX = psHooks->FOpen(pszFullname, "wb" );
-    if( fpSHX == NULL )
-    {
-        psHooks->Error( "Failed to create file .shx file." );
-        goto error;
-    }
-
-    free( pszFullname ); pszFullname = NULL;
-    free( pszBasename ); pszBasename = NULL;
-
-/* -------------------------------------------------------------------- */
-/*      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.                                         */
-/* -------------------------------------------------------------------- */
-    if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
-    {
-        psHooks->Error( "Failed to write .shp header." );
-        goto error;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Prepare, and write .shx file header.                            */
-/* -------------------------------------------------------------------- */
-    i32 = 50;                                          /* file size */
-    ByteCopy( &i32, abyHeader+24, 4 );
-    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
-    
-    if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
-    {
-        psHooks->Error( "Failed to write .shx header." );
-        goto error;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Close the files, and then open them as regular existing files.  */
-/* -------------------------------------------------------------------- */
-    psHooks->FClose( fpSHP );
-    psHooks->FClose( fpSHX );
-
-    return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
-
-error:
-    if (pszFullname) free(pszFullname);
-    if (pszBasename) free(pszBasename);
-    if (fpSHP) psHooks->FClose( fpSHP );
-    if (fpSHX) psHooks->FClose( fpSHX );
-    return NULL;
-}
-
-/************************************************************************/
-/*                           _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,
-                 const int * panPartStart, const int * panPartType,
-                 int nVertices, const double *padfX, const double *padfY,
-                 const double * padfZ, const double * padfM )
-
-{
-    SHPObject  *psObject;
-    int                i, bHasM, bHasZ;
-
-    psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
-    psObject->nSHPType = nSHPType;
-    psObject->nShapeId = nShapeId;
-    psObject->bMeasureIsUsed = FALSE;
-
-/* -------------------------------------------------------------------- */
-/*     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 *)
-            calloc(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++ )
-        {
-            if( psObject->panPartStart != NULL )
-                psObject->panPartStart[i] = panPartStart[i];
-
-            if( panPartType != NULL )
-                psObject->panPartType[i] = panPartType[i];
-            else
-                psObject->panPartType[i] = SHPP_RING;
-        }
-
-        if( psObject->panPartStart[0] != 0 )
-            psObject->panPartStart[0] = 0;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Capture vertices.  Note that X, Y, Z and M are optional.        */
-/* -------------------------------------------------------------------- */
-    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);
-
-        for( i = 0; i < nVertices; i++ )
-        {
-            if( padfX != NULL )
-                psObject->padfX[i] = padfX[i];
-            if( padfY != NULL )
-                psObject->padfY[i] = padfY[i];
-            if( padfZ != NULL && bHasZ )
-                psObject->padfZ[i] = padfZ[i];
-            if( padfM != NULL && bHasM )
-                psObject->padfM[i] = padfM[i];
-        }
-        if( padfM != NULL && bHasM )
-            psObject->bMeasureIsUsed = TRUE;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      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,
-                       const double * padfX, const double * padfY,
-                       const 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 )
-                     
-{
-    unsigned int               nRecordOffset, nRecordSize=0;
-    int i;
-    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 = (unsigned int *) 
-            SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * psSHP->nMaxRecords );
-        psSHP->panRecSize = (unsigned int *) 
-            SfRealloc(psSHP->panRecSize,sizeof(unsigned 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++ )
-            {
-                ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
-                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
-                nRecordSize += 8;
-            }
-        }
-
-        /*
-         * Write the M values, if any.
-         */
-        if( psObject->bMeasureIsUsed
-            && (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->bMeasureIsUsed
-            && (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->bMeasureIsUsed
-            && (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 )
-    {
-        unsigned int nExpectedSize = psSHP->nFileSize + nRecordSize;
-        if( nExpectedSize < psSHP->nFileSize ) // due to unsigned int overflow
-        {
-            char str[128];
-            sprintf( str, "Failed to write shape object. "
-                     "File size cannot reach %u + %u.",
-                     psSHP->nFileSize, nRecordSize );
-            psSHP->sHooks.Error( str );
-            free( pabyRec );
-            return -1;
-        }
-
-        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];
-        psSHP->panRecSize[nShapeId] = nRecordSize-8;
-    }
-    
-/* -------------------------------------------------------------------- */
-/*      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( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 )
-    {
-        psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() while writing object to .shp file." );
-        free( pabyRec );
-        return -1;
-    }
-    if( psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
-    {
-        psSHP->sHooks.Error( "Error in psSHP->sHooks.Fwrite() while writing object to .shp file." );
-        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 )
-    {
-        if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
-        {
-            psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
-            psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
-            psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
-            psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
-        }
-        else
-        {
-            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 )
-
-{
-    int                  nEntitySize, nRequiredSize;
-    SHPObject           *psShape;
-    char                 szErrorMsg[128];
-
-/* -------------------------------------------------------------------- */
-/*      Validate the record/entity number.                              */
-/* -------------------------------------------------------------------- */
-    if( hEntity < 0 || hEntity >= psSHP->nRecords )
-        return( NULL );
-
-/* -------------------------------------------------------------------- */
-/*      Ensure our record buffer is large enough.                       */
-/* -------------------------------------------------------------------- */
-    nEntitySize = psSHP->panRecSize[hEntity]+8;
-    if( nEntitySize > psSHP->nBufSize )
-    {
-        psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
-        if (psSHP->pabyRec == NULL)
-        {
-            char szError[200];
-
-            /* Reallocate previous successfull size for following features */
-            psSHP->pabyRec = (uchar *) malloc(psSHP->nBufSize);
-
-            sprintf( szError, 
-                     "Not enough memory to allocate requested memory (nBufSize=%d). "
-                     "Probably broken SHP file", psSHP->nBufSize );
-            psSHP->sHooks.Error( szError );
-            return NULL;
-        }
-
-        /* Only set new buffer size after successfull alloc */
-        psSHP->nBufSize = nEntitySize;
-    }
-
-    /* In case we were not able to reallocate the buffer on a previous step */
-    if (psSHP->pabyRec == NULL)
-    {
-        return NULL;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Read the record.                                                */
-/* -------------------------------------------------------------------- */
-    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 )
-    {
-        /*
-         * TODO - mloskot: Consider detailed diagnostics of shape file,
-         * for example to detect if file is truncated.
-         */
-        char str[128];
-        sprintf( str,
-                 "Error in fseek() reading object from .shp file at offset %u",
-                 psSHP->panRecOffset[hEntity]);
-
-        psSHP->sHooks.Error( str );
-        return NULL;
-    }
-
-    if( psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1, psSHP->fpSHP ) != 1 )
-    {
-        /*
-         * TODO - mloskot: Consider detailed diagnostics of shape file,
-         * for example to detect if file is truncated.
-         */
-        char str[128];
-        sprintf( str,
-                 "Error in fread() reading object of size %u at offset %u from .shp file",
-                 nEntitySize, psSHP->panRecOffset[hEntity] );
-
-        psSHP->sHooks.Error( str );
-        return NULL;
-    }
-
-/* -------------------------------------------------------------------- */
-/*     Allocate and minimally initialize the object.                   */
-/* -------------------------------------------------------------------- */
-    psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
-    psShape->nShapeId = hEntity;
-    psShape->bMeasureIsUsed = FALSE;
-
-    if ( 8 + 4 > nEntitySize )
-    {
-        snprintf(szErrorMsg, sizeof(szErrorMsg),
-                 "Corrupted .shp file : shape %d : nEntitySize = %d",
-                 hEntity, nEntitySize); 
-        psSHP->sHooks.Error( szErrorMsg );
-        SHPDestroyObject(psShape);
-        return NULL;
-    }
-    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;
-
-        if ( 40 + 8 + 4 > nEntitySize )
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d : nEntitySize = %d",
-                     hEntity, nEntitySize); 
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-/* -------------------------------------------------------------------- */
-/*     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 );
-
-        if (nPoints < 0 || nParts < 0 ||
-            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
-                     hEntity, nPoints, nParts);
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-        
-        /* With the previous checks on nPoints and nParts, */
-        /* we should not overflow here and after */
-        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
-        nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
-        if ( psShape->nSHPType == SHPT_POLYGONZ
-             || psShape->nSHPType == SHPT_ARCZ
-             || psShape->nSHPType == SHPT_MULTIPATCH )
-        {
-            nRequiredSize += 16 + 8 * nPoints;
-        }
-        if( psShape->nSHPType == SHPT_MULTIPATCH )
-        {
-            nRequiredSize += 4 * nParts;
-        }
-        if (nRequiredSize > nEntitySize)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
-                     hEntity, nPoints, nParts, nEntitySize);
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-
-        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));
-        
-        if (psShape->padfX == NULL ||
-            psShape->padfY == NULL ||
-            psShape->padfZ == NULL ||
-            psShape->padfM == NULL ||
-            psShape->panPartStart == NULL ||
-            psShape->panPartType == NULL)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
-                     "Probably broken SHP file", hEntity, nPoints, nParts );
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-
-        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 );
-
-            /* We check that the offset is inside the vertex array */
-            if (psShape->panPartStart[i] < 0
-                || (psShape->panPartStart[i] >= psShape->nVertices
-                    && psShape->nVertices > 0) )
-            {
-                snprintf(szErrorMsg, sizeof(szErrorMsg),
-                         "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
-                         hEntity, i, psShape->panPartStart[i], psShape->nVertices); 
-                psSHP->sHooks.Error( szErrorMsg );
-                SHPDestroyObject(psShape);
-                return NULL;
-            }
-            if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
-            {
-                snprintf(szErrorMsg, sizeof(szErrorMsg),
-                         "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
-                         hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]); 
-                psSHP->sHooks.Error( szErrorMsg );
-                SHPDestroyObject(psShape);
-                return NULL;
-            }
-        }
-
-        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,
-                   psSHP->pabyRec + nOffset + i * 16 + 8,
-                   8 );
-
-            if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
-            if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
-        }
-
-        nOffset += 16*nPoints;
-        
-/* -------------------------------------------------------------------- */
-/*      If we have a Z coordinate, collect that now.                    */
-/* -------------------------------------------------------------------- */
-        if( psShape->nSHPType == SHPT_POLYGONZ
-            || psShape->nSHPType == SHPT_ARCZ
-            || psShape->nSHPType == SHPT_MULTIPATCH )
-        {
-            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,
-                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
-                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
-            }
-
-            nOffset += 16 + 8*nPoints;
-        }
-
-/* -------------------------------------------------------------------- */
-/*      If we have a M measure value, then read it now.  We assume      */
-/*      that the measure can be present for any shape if the size is    */
-/*      big enough, but really it will only occur for the Z shapes      */
-/*      (options), and the M shapes.                                    */
-/* -------------------------------------------------------------------- */
-        if( nEntitySize >= nOffset + 16 + 8*nPoints )
-        {
-            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,
-                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
-                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
-            }
-            psShape->bMeasureIsUsed = TRUE;
-        }
-    }
-
-/* ==================================================================== */
-/*  Extract vertices for a MultiPoint.                                 */
-/* ==================================================================== */
-    else if( psShape->nSHPType == SHPT_MULTIPOINT
-             || psShape->nSHPType == SHPT_MULTIPOINTM
-             || psShape->nSHPType == SHPT_MULTIPOINTZ )
-    {
-        int32          nPoints;
-        int                    i, nOffset;
-
-        if ( 44 + 4 > nEntitySize )
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d : nEntitySize = %d",
-                     hEntity, nEntitySize); 
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-        memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
-
-        if( bBigEndian ) SwapWord( 4, &nPoints );
-
-        if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d : nPoints = %d",
-                     hEntity, nPoints); 
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-
-        nRequiredSize = 48 + nPoints * 16;
-        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
-        {
-            nRequiredSize += 16 + nPoints * 8;
-        }
-        if (nRequiredSize > nEntitySize)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
-                     hEntity, nPoints, nEntitySize); 
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-        
-        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));
-
-        if (psShape->padfX == NULL ||
-            psShape->padfY == NULL ||
-            psShape->padfZ == NULL ||
-            psShape->padfM == NULL)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
-                     "Probably broken SHP file", hEntity, nPoints );
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-
-        for( i = 0; i < nPoints; i++ )
-        {
-            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 );
-        }
-
-        nOffset = 48 + 16*nPoints;
-        
-/* -------------------------------------------------------------------- */
-/*     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) );
-
-/* -------------------------------------------------------------------- */
-/*      If we have a Z coordinate, collect that now.                    */
-/* -------------------------------------------------------------------- */
-        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
-        {
-            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,
-                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
-                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
-            }
-
-            nOffset += 16 + 8*nPoints;
-        }
-
-/* -------------------------------------------------------------------- */
-/*      If we have a M measure value, then read it now.  We assume      */
-/*      that the measure can be present for any shape if the size is    */
-/*      big enough, but really it will only occur for the Z shapes      */
-/*      (options), and the M shapes.                                    */
-/* -------------------------------------------------------------------- */
-        if( nEntitySize >= nOffset + 16 + 8*nPoints )
-        {
-            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,
-                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
-                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
-            }
-            psShape->bMeasureIsUsed = TRUE;
-        }
-    }
-
-/* ==================================================================== */
-/*      Extract vertices for a point.                                   */
-/* ==================================================================== */
-    else if( psShape->nSHPType == SHPT_POINT
-             || psShape->nSHPType == SHPT_POINTM
-             || psShape->nSHPType == SHPT_POINTZ )
-    {
-        int    nOffset;
-        
-        psShape->nVertices = 1;
-        psShape->padfX = (double *) calloc(1,sizeof(double));
-        psShape->padfY = (double *) calloc(1,sizeof(double));
-        psShape->padfZ = (double *) calloc(1,sizeof(double));
-        psShape->padfM = (double *) calloc(1,sizeof(double));
-
-        if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
-        {
-            snprintf(szErrorMsg, sizeof(szErrorMsg),
-                     "Corrupted .shp file : shape %d : nEntitySize = %d",
-                     hEntity, nEntitySize); 
-            psSHP->sHooks.Error( szErrorMsg );
-            SHPDestroyObject(psShape);
-            return NULL;
-        }
-        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 );
-
-        nOffset = 20 + 8;
-        
-/* -------------------------------------------------------------------- */
-/*      If we have a Z coordinate, collect that now.                    */
-/* -------------------------------------------------------------------- */
-        if( psShape->nSHPType == SHPT_POINTZ )
-        {
-            memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 );
-        
-            if( bBigEndian ) SwapWord( 8, psShape->padfZ );
-            
-            nOffset += 8;
-        }
-
-/* -------------------------------------------------------------------- */
-/*      If we have a M measure value, then read it now.  We assume      */
-/*      that the measure can be present for any shape if the size is    */
-/*      big enough, but really it will only occur for the Z shapes      */
-/*      (options), and the M shapes.                                    */
-/* -------------------------------------------------------------------- */
-        if( nEntitySize >= nOffset + 8 )
-        {
-            memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
-        
-            if( bBigEndian ) SwapWord( 8, psShape->padfM );
-            psShape->bMeasureIsUsed = TRUE;
-        }
-
-/* -------------------------------------------------------------------- */
-/*      Since no extents are supplied in the record, we will apply      */
-/*      them from the single vertex.                                    */
-/* -------------------------------------------------------------------- */
-        psShape->dfXMin = psShape->dfXMax = psShape->padfX[0];
-        psShape->dfYMin = psShape->dfYMax = psShape->padfY[0];
-        psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0];
-        psShape->dfMMin = psShape->dfMMax = psShape->padfM[0];
-    }
-
-    return( psShape );
-}
-
-/************************************************************************/
-/*                            SHPTypeName()                             */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-SHPTypeName( int nSHPType )
-
-{
-    switch( nSHPType )
-    {
-      case SHPT_NULL:
-        return "NullShape";
-
-      case SHPT_POINT:
-        return "Point";
-
-      case SHPT_ARC:
-        return "Arc";
-
-      case SHPT_POLYGON:
-        return "Polygon";
-
-      case SHPT_MULTIPOINT:
-        return "MultiPoint";
-        
-      case SHPT_POINTZ:
-        return "PointZ";
-
-      case SHPT_ARCZ:
-        return "ArcZ";
-
-      case SHPT_POLYGONZ:
-        return "PolygonZ";
-
-      case SHPT_MULTIPOINTZ:
-        return "MultiPointZ";
-        
-      case SHPT_POINTM:
-        return "PointM";
-
-      case SHPT_ARCM:
-        return "ArcM";
-
-      case SHPT_POLYGONM:
-        return "PolygonM";
-
-      case SHPT_MULTIPOINTM:
-        return "MultiPointM";
-
-      case SHPT_MULTIPATCH:
-        return "MultiPatch";
-
-      default:
-        return "UnknownShapeType";
-    }
-}
-
-/************************************************************************/
-/*                          SHPPartTypeName()                           */
-/************************************************************************/
-
-const char SHPAPI_CALL1(*)
-SHPPartTypeName( int nPartType )
-
-{
-    switch( nPartType )
-    {
-      case SHPP_TRISTRIP:
-        return "TriangleStrip";
-        
-      case SHPP_TRIFAN:
-        return "TriangleFan";
-
-      case SHPP_OUTERRING:
-        return "OuterRing";
-
-      case SHPP_INNERRING:
-        return "InnerRing";
-
-      case SHPP_FIRSTRING:
-        return "FirstRing";
-
-      case SHPP_RING:
-        return "Ring";
-
-      default:
-        return "UnknownPartType";
-    }
-}
-
-/************************************************************************/
-/*                          SHPDestroyObject()                          */
-/************************************************************************/
-
-void SHPAPI_CALL
-SHPDestroyObject( SHPObject * psShape )
-
-{
-    if( psShape == NULL )
-        return;
-    
-    if( psShape->padfX != NULL )
-        free( psShape->padfX );
-    if( psShape->padfY != NULL )
-        free( psShape->padfY );
-    if( psShape->padfZ != NULL )
-        free( psShape->padfZ );
-    if( psShape->padfM != NULL )
-        free( psShape->padfM );
-
-    if( psShape->panPartStart != NULL )
-        free( psShape->panPartStart );
-    if( psShape->panPartType != NULL )
-        free( psShape->panPartType );
-
-    free( psShape );
-}
-
-/************************************************************************/
-/*                          SHPRewindObject()                           */
-/*                                                                      */
-/*      Reset the winding of polygon objects to adhere to the           */
-/*      specification.                                                  */
-/************************************************************************/
-
-int SHPAPI_CALL
-SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
-
-{
-    int  iOpRing, bAltered = 0;
-
-/* -------------------------------------------------------------------- */
-/*      Do nothing if this is not a polygon object.                     */
-/* -------------------------------------------------------------------- */
-    if( psObject->nSHPType != SHPT_POLYGON
-        && psObject->nSHPType != SHPT_POLYGONZ
-        && psObject->nSHPType != SHPT_POLYGONM )
-        return 0;
-
-    if( psObject->nVertices == 0 || psObject->nParts == 0 )
-        return 0;
-
-/* -------------------------------------------------------------------- */
-/*      Process each of the rings.                                      */
-/* -------------------------------------------------------------------- */
-    for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ )
-    {
-        int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
-        double   dfSum, dfTestX, dfTestY;
-
-/* -------------------------------------------------------------------- */
-/*      Determine if this ring is an inner ring or an outer ring        */
-/*      relative to all the other rings.  For now we assume the         */
-/*      first ring is outer and all others are inner, but eventually    */
-/*      we need to fix this to handle multiple island polygons and      */
-/*      unordered sets of rings.                                        */
-/*                                                                      */
-/* -------------------------------------------------------------------- */
-
-        /* Use point in the middle of segment to avoid testing
-         * common points of rings.
-         */
-        dfTestX = ( psObject->padfX[psObject->panPartStart[iOpRing]]
-                    + psObject->padfX[psObject->panPartStart[iOpRing] + 1] ) / 2;
-        dfTestY = ( psObject->padfY[psObject->panPartStart[iOpRing]]
-                    + psObject->padfY[psObject->panPartStart[iOpRing] + 1] ) / 2;
-
-        bInner = FALSE;
-        for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
-        {
-            int iEdge;
-
-            if( iCheckRing == iOpRing )
-                continue;
-            
-            nVertStart = psObject->panPartStart[iCheckRing];
-
-            if( iCheckRing == psObject->nParts-1 )
-                nVertCount = psObject->nVertices 
-                    - psObject->panPartStart[iCheckRing];
-            else
-                nVertCount = psObject->panPartStart[iCheckRing+1] 
-                    - psObject->panPartStart[iCheckRing];
-
-            for( iEdge = 0; iEdge < nVertCount; iEdge++ )
-            {
-                int iNext;
-
-                if( iEdge < nVertCount-1 )
-                    iNext = iEdge+1;
-                else
-                    iNext = 0;
-
-                /* Rule #1:
-                 * Test whether the edge 'straddles' the horizontal ray from the test point (dfTestY,dfTestY)
-                 * The rule #1 also excludes edges collinear with the ray.
-                 */
-                if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY
-                       && dfTestY <= psObject->padfY[iNext+nVertStart] )
-                     || ( psObject->padfY[iNext+nVertStart] < dfTestY
-                          && dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
-                {
-                    /* Rule #2:
-                     * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
-                     */
-                    double const intersect = 
-                        ( psObject->padfX[iEdge+nVertStart]
-                          + ( dfTestY - psObject->padfY[iEdge+nVertStart] ) 
-                          / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] )
-                          * ( psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart] ) );
-
-                    if (intersect  < dfTestX)
-                    {
-                        bInner = !bInner;
-                    }
-                }    
-            }
-        } /* for iCheckRing */
-
-/* -------------------------------------------------------------------- */
-/*      Determine the current order of this ring so we will know if     */
-/*      it has to be reversed.                                          */
-/* -------------------------------------------------------------------- */
-        nVertStart = psObject->panPartStart[iOpRing];
-
-        if( iOpRing == psObject->nParts-1 )
-            nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
-        else
-            nVertCount = psObject->panPartStart[iOpRing+1] 
-                - psObject->panPartStart[iOpRing];
-
-        if (nVertCount < 2)
-            continue;
-
-        dfSum = psObject->padfX[nVertStart] * (psObject->padfY[nVertStart+1] - psObject->padfY[nVertStart+nVertCount-1]);
-        for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ )
-        {
-            dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] - psObject->padfY[iVert-1]);
-        }
-
-        dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] - psObject->padfY[iVert-1]);
-
-/* -------------------------------------------------------------------- */
-/*      Reverse if necessary.                                           */
-/* -------------------------------------------------------------------- */
-        if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
-        {
-            int   i;
-
-            bAltered++;
-            for( i = 0; i < nVertCount/2; i++ )
-            {
-                double dfSaved;
-
-                /* Swap X */
-                dfSaved = psObject->padfX[nVertStart+i];
-                psObject->padfX[nVertStart+i] = 
-                    psObject->padfX[nVertStart+nVertCount-i-1];
-                psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved;
-
-                /* Swap Y */
-                dfSaved = psObject->padfY[nVertStart+i];
-                psObject->padfY[nVertStart+i] = 
-                    psObject->padfY[nVertStart+nVertCount-i-1];
-                psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved;
-
-                /* Swap Z */
-                if( psObject->padfZ )
-                {
-                    dfSaved = psObject->padfZ[nVertStart+i];
-                    psObject->padfZ[nVertStart+i] = 
-                        psObject->padfZ[nVertStart+nVertCount-i-1];
-                    psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved;
-                }
-
-                /* Swap M */
-                if( psObject->padfM )
-                {
-                    dfSaved = psObject->padfM[nVertStart+i];
-                    psObject->padfM[nVertStart+i] = 
-                        psObject->padfM[nVertStart+nVertCount-i-1];
-                    psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved;
-                }
-            }
-        }
-    }
-
-    return bAltered;
-}
diff --git a/src/HYDROData/shapelib/shptree.c b/src/HYDROData/shapelib/shptree.c
deleted file mode 100644 (file)
index 409134e..0000000
+++ /dev/null
@@ -1,1187 +0,0 @@
-/******************************************************************************
- * $Id: shptree.c,v 1.17 2012-01-27 21:09:26 fwarmerdam Exp $
- *
- * Project:  Shapelib
- * Purpose:  Implementation of quadtree building and searching functions.
- * Author:   Frank Warmerdam, warmerdam@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 1999, 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: shptree.c,v $
- * Revision 1.17  2012-01-27 21:09:26  fwarmerdam
- * optimize .qix output (gdal #4472)
- *
- * Revision 1.16  2011-12-11 22:26:46  fwarmerdam
- * upgrade .qix access code to use SAHooks (gdal #3365)
- *
- * Revision 1.15  2011-07-24 05:59:25  fwarmerdam
- * minimize use of CPLError in favor of SAHooks.Error()
- *
- * Revision 1.14  2010-08-27 23:43:27  fwarmerdam
- * add SHPAPI_CALL attribute in code
- *
- * Revision 1.13  2010-06-29 05:50:15  fwarmerdam
- * fix sign of Z/M comparisons in SHPCheckObjectContained (#2223)
- *
- * Revision 1.12  2008-11-12 15:39:50  fwarmerdam
- * improve safety in face of buggy .shp file.
- *
- * Revision 1.11  2007/10/27 03:31:14  fwarmerdam
- * limit default depth of tree to 12 levels (gdal ticket #1594)
- *
- * Revision 1.10  2005/01/03 22:30:13  fwarmerdam
- * added support for saved quadtrees
- *
- * Revision 1.9  2003/01/28 15:53:41  warmerda
- * Avoid build warnings.
- *
- * Revision 1.8  2002/05/07 13:07:45  warmerda
- * use qsort() - patch from Bernhard Herzog
- *
- * Revision 1.7  2002/01/15 14:36:07  warmerda
- * updated email address
- *
- * Revision 1.6  2001/05/23 13:36:52  warmerda
- * added use of SHPAPI_CALL
- *
- * Revision 1.5  1999/11/05 14:12:05  warmerda
- * updated license terms
- *
- * Revision 1.4  1999/06/02 18:24:21  warmerda
- * added trimming code
- *
- * Revision 1.3  1999/06/02 17:56:12  warmerda
- * added quad'' subnode support for trees
- *
- * Revision 1.2  1999/05/18 19:11:11  warmerda
- * Added example searching capability
- *
- * Revision 1.1  1999/05/18 17:49:20  warmerda
- * New
- *
- */
-
-#include "shapefil.h"
-
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef USE_CPL
-#include "cpl_error.h"
-#endif
-
-SHP_CVSID("$Id: shptree.c,v 1.17 2012-01-27 21:09:26 fwarmerdam Exp $")
-
-#ifndef TRUE
-#  define TRUE 1
-#  define FALSE 0
-#endif
-
-static int bBigEndian = 0;
-
-
-/* -------------------------------------------------------------------- */
-/*      If the following is 0.5, nodes will be split in half.  If it    */
-/*      is 0.6 then each subnode will contain 60% of the parent         */
-/*      node, with 20% representing overlap.  This can be help to       */
-/*      prevent small objects on a boundary from shifting too high      */
-/*      up the tree.                                                    */
-/* -------------------------------------------------------------------- */
-
-#define SHP_SPLIT_RATIO        0.55
-
-/************************************************************************/
-/*                             SfRealloc()                              */
-/*                                                                      */
-/*      A realloc cover function that will access a NULL pointer as     */
-/*      a valid input.                                                  */
-/************************************************************************/
-
-static void * SfRealloc( void * pMem, int nNewSize )
-
-{
-    if( pMem == NULL )
-        return( (void *) malloc(nNewSize) );
-    else
-        return( (void *) realloc(pMem,nNewSize) );
-}
-
-/************************************************************************/
-/*                          SHPTreeNodeInit()                           */
-/*                                                                      */
-/*      Initialize a tree node.                                         */
-/************************************************************************/
-
-static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin,
-                                       double * padfBoundsMax )
-
-{
-    SHPTreeNode        *psTreeNode;
-
-    psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode));
-    if( NULL == psTreeNode )
-        return NULL;
-
-    psTreeNode->nShapeCount = 0;
-    psTreeNode->panShapeIds = NULL;
-    psTreeNode->papsShapeObj = NULL;
-
-    psTreeNode->nSubNodes = 0;
-
-    if( padfBoundsMin != NULL )
-        memcpy( psTreeNode->adfBoundsMin, padfBoundsMin, sizeof(double) * 4 );
-
-    if( padfBoundsMax != NULL )
-        memcpy( psTreeNode->adfBoundsMax, padfBoundsMax, sizeof(double) * 4 );
-
-    return psTreeNode;
-}
-
-
-/************************************************************************/
-/*                           SHPCreateTree()                            */
-/************************************************************************/
-
-SHPTree SHPAPI_CALL1(*)
-    SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
-                   double *padfBoundsMin, double *padfBoundsMax )
-
-{
-    SHPTree    *psTree;
-
-    if( padfBoundsMin == NULL && hSHP == NULL )
-        return NULL;
-
-/* -------------------------------------------------------------------- */
-/*      Allocate the tree object                                        */
-/* -------------------------------------------------------------------- */
-    psTree = (SHPTree *) malloc(sizeof(SHPTree));
-    if( NULL == psTree )
-    {
-        return NULL;
-    }
-
-    psTree->hSHP = hSHP;
-    psTree->nMaxDepth = nMaxDepth;
-    psTree->nDimension = nDimension;
-    psTree->nTotalCount = 0;
-
-/* -------------------------------------------------------------------- */
-/*      If no max depth was defined, try to select a reasonable one     */
-/*      that implies approximately 8 shapes per node.                   */
-/* -------------------------------------------------------------------- */
-    if( psTree->nMaxDepth == 0 && hSHP != NULL )
-    {
-        int    nMaxNodeCount = 1;
-        int    nShapeCount;
-
-        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
-        while( nMaxNodeCount*4 < nShapeCount )
-        {
-            psTree->nMaxDepth += 1;
-            nMaxNodeCount = nMaxNodeCount * 2;
-        }
-
-#ifdef USE_CPL
-        CPLDebug( "Shape",
-                  "Estimated spatial index tree depth: %d",
-                  psTree->nMaxDepth );
-#endif
-
-        /* NOTE: Due to problems with memory allocation for deep trees,
-         * automatically estimated depth is limited up to 12 levels.
-         * See Ticket #1594 for detailed discussion.
-         */
-        if( psTree->nMaxDepth > MAX_DEFAULT_TREE_DEPTH )
-        {
-            psTree->nMaxDepth = MAX_DEFAULT_TREE_DEPTH;
-
-#ifdef USE_CPL
-            CPLDebug( "Shape",
-                      "Falling back to max number of allowed index tree levels (%d).",
-                      MAX_DEFAULT_TREE_DEPTH );
-#endif
-        }
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Allocate the root node.                                         */
-/* -------------------------------------------------------------------- */
-    psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );
-    if( NULL == psTree->psRoot )
-    {
-        return NULL;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Assign the bounds to the root node.  If none are passed in,     */
-/*      use the bounds of the provided file otherwise the create        */
-/*      function will have already set the bounds.                      */
-/* -------------------------------------------------------------------- */
-    assert( NULL != psTree );
-    assert( NULL != psTree->psRoot );
-       
-    if( padfBoundsMin == NULL )
-    {
-        SHPGetInfo( hSHP, NULL, NULL,
-                    psTree->psRoot->adfBoundsMin, 
-                    psTree->psRoot->adfBoundsMax );
-    }
-
-/* -------------------------------------------------------------------- */
-/*      If we have a file, insert all it's shapes into the tree.        */
-/* -------------------------------------------------------------------- */
-    if( hSHP != NULL )
-    {
-        int    iShape, nShapeCount;
-        
-        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
-
-        for( iShape = 0; iShape < nShapeCount; iShape++ )
-        {
-            SHPObject  *psShape;
-            
-            psShape = SHPReadObject( hSHP, iShape );
-            if( psShape != NULL )
-            {
-                SHPTreeAddShapeId( psTree, psShape );
-                SHPDestroyObject( psShape );
-            }
-        }
-    }        
-
-    return psTree;
-}
-
-/************************************************************************/
-/*                         SHPDestroyTreeNode()                         */
-/************************************************************************/
-
-static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode )
-
-{
-    int                i;
-    
-       assert( NULL != psTreeNode );
-
-    for( i = 0; i < psTreeNode->nSubNodes; i++ )
-    {
-        if( psTreeNode->apsSubNode[i] != NULL )
-            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
-    }
-    
-    if( psTreeNode->panShapeIds != NULL )
-        free( psTreeNode->panShapeIds );
-
-    if( psTreeNode->papsShapeObj != NULL )
-    {
-        for( i = 0; i < psTreeNode->nShapeCount; i++ )
-        {
-            if( psTreeNode->papsShapeObj[i] != NULL )
-                SHPDestroyObject( psTreeNode->papsShapeObj[i] );
-        }
-
-        free( psTreeNode->papsShapeObj );
-    }
-
-    free( psTreeNode );
-}
-
-/************************************************************************/
-/*                           SHPDestroyTree()                           */
-/************************************************************************/
-
-void SHPAPI_CALL
-SHPDestroyTree( SHPTree * psTree )
-
-{
-    SHPDestroyTreeNode( psTree->psRoot );
-    free( psTree );
-}
-
-/************************************************************************/
-/*                       SHPCheckBoundsOverlap()                        */
-/*                                                                      */
-/*      Do the given boxes overlap at all?                              */
-/************************************************************************/
-
-int SHPAPI_CALL
-SHPCheckBoundsOverlap( double * padfBox1Min, double * padfBox1Max,
-                       double * padfBox2Min, double * padfBox2Max,
-                       int nDimension )
-
-{
-    int                iDim;
-
-    for( iDim = 0; iDim < nDimension; iDim++ )
-    {
-        if( padfBox2Max[iDim] < padfBox1Min[iDim] )
-            return FALSE;
-        
-        if( padfBox1Max[iDim] < padfBox2Min[iDim] )
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                      SHPCheckObjectContained()                       */
-/*                                                                      */
-/*      Does the given shape fit within the indicated extents?          */
-/************************************************************************/
-
-static int SHPCheckObjectContained( SHPObject * psObject, int nDimension,
-                           double * padfBoundsMin, double * padfBoundsMax )
-
-{
-    if( psObject->dfXMin < padfBoundsMin[0]
-        || psObject->dfXMax > padfBoundsMax[0] )
-        return FALSE;
-    
-    if( psObject->dfYMin < padfBoundsMin[1]
-        || psObject->dfYMax > padfBoundsMax[1] )
-        return FALSE;
-
-    if( nDimension == 2 )
-        return TRUE;
-    
-    if( psObject->dfZMin < padfBoundsMin[2]
-        || psObject->dfZMax > padfBoundsMax[2] )
-        return FALSE;
-        
-    if( nDimension == 3 )
-        return TRUE;
-
-    if( psObject->dfMMin < padfBoundsMin[3]
-        || psObject->dfMMax > padfBoundsMax[3] )
-        return FALSE;
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                         SHPTreeSplitBounds()                         */
-/*                                                                      */
-/*      Split a region into two subregion evenly, cutting along the     */
-/*      longest dimension.                                              */
-/************************************************************************/
-
-void SHPAPI_CALL
-SHPTreeSplitBounds( double *padfBoundsMinIn, double *padfBoundsMaxIn,
-                    double *padfBoundsMin1, double * padfBoundsMax1,
-                    double *padfBoundsMin2, double * padfBoundsMax2 )
-
-{
-/* -------------------------------------------------------------------- */
-/*      The output bounds will be very similar to the input bounds,     */
-/*      so just copy over to start.                                     */
-/* -------------------------------------------------------------------- */
-    memcpy( padfBoundsMin1, padfBoundsMinIn, sizeof(double) * 4 );
-    memcpy( padfBoundsMax1, padfBoundsMaxIn, sizeof(double) * 4 );
-    memcpy( padfBoundsMin2, padfBoundsMinIn, sizeof(double) * 4 );
-    memcpy( padfBoundsMax2, padfBoundsMaxIn, sizeof(double) * 4 );
-    
-/* -------------------------------------------------------------------- */
-/*      Split in X direction.                                           */
-/* -------------------------------------------------------------------- */
-    if( (padfBoundsMaxIn[0] - padfBoundsMinIn[0])
-                               > (padfBoundsMaxIn[1] - padfBoundsMinIn[1]) )
-    {
-        double dfRange = padfBoundsMaxIn[0] - padfBoundsMinIn[0];
-
-        padfBoundsMax1[0] = padfBoundsMinIn[0] + dfRange * SHP_SPLIT_RATIO;
-        padfBoundsMin2[0] = padfBoundsMaxIn[0] - dfRange * SHP_SPLIT_RATIO;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Otherwise split in Y direction.                                 */
-/* -------------------------------------------------------------------- */
-    else
-    {
-        double dfRange = padfBoundsMaxIn[1] - padfBoundsMinIn[1];
-
-        padfBoundsMax1[1] = padfBoundsMinIn[1] + dfRange * SHP_SPLIT_RATIO;
-        padfBoundsMin2[1] = padfBoundsMaxIn[1] - dfRange * SHP_SPLIT_RATIO;
-    }
-}
-
-/************************************************************************/
-/*                       SHPTreeNodeAddShapeId()                        */
-/************************************************************************/
-
-static int
-SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject,
-                       int nMaxDepth, int nDimension )
-
-{
-    int                i;
-    
-/* -------------------------------------------------------------------- */
-/*      If there are subnodes, then consider wiether this object        */
-/*      will fit in them.                                               */
-/* -------------------------------------------------------------------- */
-    if( nMaxDepth > 1 && psTreeNode->nSubNodes > 0 )
-    {
-        for( i = 0; i < psTreeNode->nSubNodes; i++ )
-        {
-            if( SHPCheckObjectContained(psObject, nDimension,
-                                      psTreeNode->apsSubNode[i]->adfBoundsMin,
-                                      psTreeNode->apsSubNode[i]->adfBoundsMax))
-            {
-                return SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[i],
-                                              psObject, nMaxDepth-1,
-                                              nDimension );
-            }
-        }
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Otherwise, consider creating four subnodes if could fit into    */
-/*      them, and adding to the appropriate subnode.                    */
-/* -------------------------------------------------------------------- */
-#if MAX_SUBNODE == 4
-    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
-    {
-        double adfBoundsMinH1[4], adfBoundsMaxH1[4];
-        double adfBoundsMinH2[4], adfBoundsMaxH2[4];
-        double adfBoundsMin1[4], adfBoundsMax1[4];
-        double adfBoundsMin2[4], adfBoundsMax2[4];
-        double adfBoundsMin3[4], adfBoundsMax3[4];
-        double adfBoundsMin4[4], adfBoundsMax4[4];
-
-        SHPTreeSplitBounds( psTreeNode->adfBoundsMin,
-                            psTreeNode->adfBoundsMax,
-                            adfBoundsMinH1, adfBoundsMaxH1,
-                            adfBoundsMinH2, adfBoundsMaxH2 );
-
-        SHPTreeSplitBounds( adfBoundsMinH1, adfBoundsMaxH1,
-                            adfBoundsMin1, adfBoundsMax1,
-                            adfBoundsMin2, adfBoundsMax2 );
-
-        SHPTreeSplitBounds( adfBoundsMinH2, adfBoundsMaxH2,
-                            adfBoundsMin3, adfBoundsMax3,
-                            adfBoundsMin4, adfBoundsMax4 );
-
-        if( SHPCheckObjectContained(psObject, nDimension,
-                                    adfBoundsMin1, adfBoundsMax1)
-            || SHPCheckObjectContained(psObject, nDimension,
-                                    adfBoundsMin2, adfBoundsMax2)
-            || SHPCheckObjectContained(psObject, nDimension,
-                                    adfBoundsMin3, adfBoundsMax3)
-            || SHPCheckObjectContained(psObject, nDimension,
-                                    adfBoundsMin4, adfBoundsMax4) )
-        {
-            psTreeNode->nSubNodes = 4;
-            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
-                                                           adfBoundsMax1 );
-            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
-                                                           adfBoundsMax2 );
-            psTreeNode->apsSubNode[2] = SHPTreeNodeCreate( adfBoundsMin3,
-                                                           adfBoundsMax3 );
-            psTreeNode->apsSubNode[3] = SHPTreeNodeCreate( adfBoundsMin4,
-                                                           adfBoundsMax4 );
-
-            /* recurse back on this node now that it has subnodes */
-            return( SHPTreeNodeAddShapeId( psTreeNode, psObject,
-                                           nMaxDepth, nDimension ) );
-        }
-    }
-#endif /* MAX_SUBNODE == 4 */
-
-/* -------------------------------------------------------------------- */
-/*      Otherwise, consider creating two subnodes if could fit into     */
-/*      them, and adding to the appropriate subnode.                    */
-/* -------------------------------------------------------------------- */
-#if MAX_SUBNODE == 2
-    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
-    {
-        double adfBoundsMin1[4], adfBoundsMax1[4];
-        double adfBoundsMin2[4], adfBoundsMax2[4];
-
-        SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax,
-                            adfBoundsMin1, adfBoundsMax1,
-                            adfBoundsMin2, adfBoundsMax2 );
-
-        if( SHPCheckObjectContained(psObject, nDimension,
-                                 adfBoundsMin1, adfBoundsMax1))
-        {
-            psTreeNode->nSubNodes = 2;
-            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
-                                                           adfBoundsMax1 );
-            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
-                                                           adfBoundsMax2 );
-
-            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[0], psObject,
-                                           nMaxDepth - 1, nDimension ) );
-        }
-        else if( SHPCheckObjectContained(psObject, nDimension,
-                                         adfBoundsMin2, adfBoundsMax2) )
-        {
-            psTreeNode->nSubNodes = 2;
-            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
-                                                           adfBoundsMax1 );
-            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
-                                                           adfBoundsMax2 );
-
-            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[1], psObject,
-                                           nMaxDepth - 1, nDimension ) );
-        }
-    }
-#endif /* MAX_SUBNODE == 2 */
-
-/* -------------------------------------------------------------------- */
-/*      If none of that worked, just add it to this nodes list.         */
-/* -------------------------------------------------------------------- */
-    psTreeNode->nShapeCount++;
-
-    psTreeNode->panShapeIds = (int *) 
-        SfRealloc( psTreeNode->panShapeIds,
-                   sizeof(int) * psTreeNode->nShapeCount );
-    psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId;
-
-    if( psTreeNode->papsShapeObj != NULL )
-    {
-        psTreeNode->papsShapeObj = (SHPObject **)
-            SfRealloc( psTreeNode->papsShapeObj,
-                       sizeof(void *) * psTreeNode->nShapeCount );
-        psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL;
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                         SHPTreeAddShapeId()                          */
-/*                                                                      */
-/*      Add a shape to the tree, but don't keep a pointer to the        */
-/*      object data, just keep the shapeid.                             */
-/************************************************************************/
-
-int SHPAPI_CALL
-SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject )
-
-{
-    psTree->nTotalCount++;
-
-    return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject,
-                                   psTree->nMaxDepth, psTree->nDimension ) );
-}
-
-/************************************************************************/
-/*                      SHPTreeCollectShapesIds()                       */
-/*                                                                      */
-/*      Work function implementing SHPTreeFindLikelyShapes() on a       */
-/*      tree node by tree node basis.                                   */
-/************************************************************************/
-
-void SHPAPI_CALL
-SHPTreeCollectShapeIds( SHPTree *hTree, SHPTreeNode * psTreeNode,
-                        double * padfBoundsMin, double * padfBoundsMax,
-                        int * pnShapeCount, int * pnMaxShapes,
-                        int ** ppanShapeList )
-
-{
-    int                i;
-    
-/* -------------------------------------------------------------------- */
-/*      Does this node overlap the area of interest at all?  If not,    */
-/*      return without adding to the list at all.                       */
-/* -------------------------------------------------------------------- */
-    if( !SHPCheckBoundsOverlap( psTreeNode->adfBoundsMin,
-                                psTreeNode->adfBoundsMax,
-                                padfBoundsMin,
-                                padfBoundsMax,
-                                hTree->nDimension ) )
-        return;
-
-/* -------------------------------------------------------------------- */
-/*      Grow the list to hold the shapes on this node.                  */
-/* -------------------------------------------------------------------- */
-    if( *pnShapeCount + psTreeNode->nShapeCount > *pnMaxShapes )
-    {
-        *pnMaxShapes = (*pnShapeCount + psTreeNode->nShapeCount) * 2 + 20;
-        *ppanShapeList = (int *)
-            SfRealloc(*ppanShapeList,sizeof(int) * *pnMaxShapes);
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Add the local nodes shapeids to the list.                       */
-/* -------------------------------------------------------------------- */
-    for( i = 0; i < psTreeNode->nShapeCount; i++ )
-    {
-        (*ppanShapeList)[(*pnShapeCount)++] = psTreeNode->panShapeIds[i];
-    }
-    
-/* -------------------------------------------------------------------- */
-/*      Recurse to subnodes if they exist.                              */
-/* -------------------------------------------------------------------- */
-    for( i = 0; i < psTreeNode->nSubNodes; i++ )
-    {
-        if( psTreeNode->apsSubNode[i] != NULL )
-            SHPTreeCollectShapeIds( hTree, psTreeNode->apsSubNode[i],
-                                    padfBoundsMin, padfBoundsMax,
-                                    pnShapeCount, pnMaxShapes,
-                                    ppanShapeList );
-    }
-}
-
-/************************************************************************/
-/*                      SHPTreeFindLikelyShapes()                       */
-/*                                                                      */
-/*      Find all shapes within tree nodes for which the tree node       */
-/*      bounding box overlaps the search box.  The return value is      */
-/*      an array of shapeids terminated by a -1.  The shapeids will     */
-/*      be in order, as hopefully this will result in faster (more      */
-/*      sequential) reading from the file.                              */
-/************************************************************************/
-
-/* helper for qsort */
-static int
-compare_ints( const void * a, const void * b)
-{
-    return (*(int*)a) - (*(int*)b);
-}
-
-int SHPAPI_CALL1(*)
-SHPTreeFindLikelyShapes( SHPTree * hTree,
-                         double * padfBoundsMin, double * padfBoundsMax,
-                         int * pnShapeCount )
-
-{
-    int        *panShapeList=NULL, nMaxShapes = 0;
-
-/* -------------------------------------------------------------------- */
-/*      Perform the search by recursive descent.                        */
-/* -------------------------------------------------------------------- */
-    *pnShapeCount = 0;
-
-    SHPTreeCollectShapeIds( hTree, hTree->psRoot,
-                            padfBoundsMin, padfBoundsMax,
-                            pnShapeCount, &nMaxShapes,
-                            &panShapeList );
-
-/* -------------------------------------------------------------------- */
-/*      Sort the id array                                               */
-/* -------------------------------------------------------------------- */
-
-    qsort(panShapeList, *pnShapeCount, sizeof(int), compare_ints);
-
-    return panShapeList;
-}
-
-/************************************************************************/
-/*                          SHPTreeNodeTrim()                           */
-/*                                                                      */
-/*      This is the recurve version of SHPTreeTrimExtraNodes() that     */
-/*      walks the tree cleaning it up.                                  */
-/************************************************************************/
-
-static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode )
-
-{
-    int                i;
-
-/* -------------------------------------------------------------------- */
-/*      Trim subtrees, and free subnodes that come back empty.          */
-/* -------------------------------------------------------------------- */
-    for( i = 0; i < psTreeNode->nSubNodes; i++ )
-    {
-        if( SHPTreeNodeTrim( psTreeNode->apsSubNode[i] ) )
-        {
-            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
-
-            psTreeNode->apsSubNode[i] =
-                psTreeNode->apsSubNode[psTreeNode->nSubNodes-1];
-
-            psTreeNode->nSubNodes--;
-
-            i--; /* process the new occupant of this subnode entry */
-        }
-    }
-
-/* -------------------------------------------------------------------- */
-/*      If the current node has 1 subnode and no shapes, promote that   */
-/*      subnode to the current node position.                           */
-/* -------------------------------------------------------------------- */
-    if( psTreeNode->nSubNodes == 1 && psTreeNode->nShapeCount == 0)
-    {
-        SHPTreeNode* psSubNode = psTreeNode->apsSubNode[0];
-
-        memcpy(psTreeNode->adfBoundsMin, psSubNode->adfBoundsMin,
-               sizeof(psSubNode->adfBoundsMin));
-        memcpy(psTreeNode->adfBoundsMax, psSubNode->adfBoundsMax,
-               sizeof(psSubNode->adfBoundsMax));
-        psTreeNode->nShapeCount = psSubNode->nShapeCount;
-        assert(psTreeNode->panShapeIds == NULL);
-        psTreeNode->panShapeIds = psSubNode->panShapeIds;
-        assert(psTreeNode->papsShapeObj == NULL);
-        psTreeNode->papsShapeObj = psSubNode->papsShapeObj;
-        psTreeNode->nSubNodes = psSubNode->nSubNodes;
-        for( i = 0; i < psSubNode->nSubNodes; i++ )
-            psTreeNode->apsSubNode[i] = psSubNode->apsSubNode[i];
-        free(psSubNode);
-    }
-
-/* -------------------------------------------------------------------- */
-/*      We should be trimmed if we have no subnodes, and no shapes.     */
-/* -------------------------------------------------------------------- */
-    return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 );
-}
-
-/************************************************************************/
-/*                       SHPTreeTrimExtraNodes()                        */
-/*                                                                      */
-/*      Trim empty nodes from the tree.  Note that we never trim an     */
-/*      empty root node.                                                */
-/************************************************************************/
-
-void SHPAPI_CALL
-SHPTreeTrimExtraNodes( SHPTree * hTree )
-
-{
-    SHPTreeNodeTrim( hTree->psRoot );
-}
-
-/************************************************************************/
-/*                              SwapWord()                              */
-/*                                                                      */
-/*      Swap a 2, 4 or 8 byte word.                                     */
-/************************************************************************/
-
-static void SwapWord( int length, void * wordP )
-
-{
-    int                i;
-    unsigned char      temp;
-
-    for( i=0; i < length/2; i++ )
-    {
-       temp = ((unsigned char *) wordP)[i];
-       ((unsigned char *)wordP)[i] = ((unsigned char *) wordP)[length-i-1];
-       ((unsigned char *) wordP)[length-i-1] = temp;
-    }
-}
-
-
-struct SHPDiskTreeInfo
-{
-    SAHooks sHooks;
-    SAFile  fpQIX;
-};
-
-/************************************************************************/
-/*                         SHPOpenDiskTree()                            */
-/************************************************************************/
-
-SHPTreeDiskHandle SHPOpenDiskTree( const char* pszQIXFilename,
-                                   SAHooks *psHooks )
-{
-    SHPTreeDiskHandle hDiskTree;
-
-    hDiskTree = (SHPTreeDiskHandle) calloc(sizeof(struct SHPDiskTreeInfo),1);
-
-    if (psHooks == NULL)
-        SASetupDefaultHooks( &(hDiskTree->sHooks) );
-    else
-        memcpy( &(hDiskTree->sHooks), psHooks, sizeof(SAHooks) );
-
-    hDiskTree->fpQIX = hDiskTree->sHooks.FOpen(pszQIXFilename, "rb");
-    if (hDiskTree->fpQIX == NULL)
-    {
-        free(hDiskTree);
-        return NULL;
-    }
-
-    return hDiskTree;
-}
-
-/***********************************************************************/
-/*                         SHPCloseDiskTree()                           */
-/************************************************************************/
-
-void SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree )
-{
-    if (hDiskTree == NULL)
-        return;
-
-    hDiskTree->sHooks.FClose(hDiskTree->fpQIX);
-    free(hDiskTree);
-}
-
-/************************************************************************/
-/*                       SHPSearchDiskTreeNode()                        */
-/************************************************************************/
-
-static int
-SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, double *padfBoundsMax,
-                       int **ppanResultBuffer, int *pnBufferMax, 
-                       int *pnResultCount, int bNeedSwap )
-
-{
-    int i;
-    int offset;
-    int numshapes, numsubnodes;
-    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];
-
-/* -------------------------------------------------------------------- */
-/*      Read and unswap first part of node info.                        */
-/* -------------------------------------------------------------------- */
-    hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX );
-    if ( bNeedSwap ) SwapWord ( 4, &offset );
-
-    hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX );
-    hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX );
-    if ( bNeedSwap )
-    {
-        SwapWord( 8, adfNodeBoundsMin + 0 );
-        SwapWord( 8, adfNodeBoundsMin + 1 );
-        SwapWord( 8, adfNodeBoundsMax + 0 );
-        SwapWord( 8, adfNodeBoundsMax + 1 );
-    }
-      
-    hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX );
-    if ( bNeedSwap ) SwapWord ( 4, &numshapes );
-
-/* -------------------------------------------------------------------- */
-/*      If we don't overlap this node at all, we can just fseek()       */
-/*      pass this node info and all subnodes.                           */
-/* -------------------------------------------------------------------- */
-    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
-                                padfBoundsMin, padfBoundsMax, 2 ) )
-    {
-        offset += numshapes*sizeof(int) + sizeof(int);
-        hDiskTree->sHooks.FSeek(hDiskTree->fpQIX, offset, SEEK_CUR);
-        return TRUE;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Add all the shapeids at this node to our list.                  */
-/* -------------------------------------------------------------------- */
-    if(numshapes > 0) 
-    {
-        if( *pnResultCount + numshapes > *pnBufferMax )
-        {
-            *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25);
-            *ppanResultBuffer = (int *) 
-                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );
-        }
-
-        hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount, 
-               sizeof(int), numshapes, hDiskTree->fpQIX );
-
-        if (bNeedSwap )
-        {
-            for( i=0; i<numshapes; i++ )
-                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
-        }
-
-        *pnResultCount += numshapes; 
-    } 
-
-/* -------------------------------------------------------------------- */
-/*      Process the subnodes.                                           */
-/* -------------------------------------------------------------------- */
-    hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX );
-    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );
-
-    for(i=0; i<numsubnodes; i++)
-    {
-        if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
-                                    ppanResultBuffer, pnBufferMax, 
-                                    pnResultCount, bNeedSwap ) )
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-/************************************************************************/
-/*                          SHPTreeReadLibc()                           */
-/************************************************************************/
-
-static
-SAOffset SHPTreeReadLibc( void *p, SAOffset size, SAOffset nmemb, SAFile file )
-
-{
-    return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
-                                 (FILE *) file );
-}
-
-/************************************************************************/
-/*                          SHPTreeSeekLibc()                           */
-/************************************************************************/
-
-static
-SAOffset SHPTreeSeekLibc( SAFile file, SAOffset offset, int whence )
-
-{
-    return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
-}
-
-/************************************************************************/
-/*                         SHPSearchDiskTree()                          */
-/************************************************************************/
-
-int SHPAPI_CALL1(*) 
-SHPSearchDiskTree( FILE *fp, 
-                   double *padfBoundsMin, double *padfBoundsMax,
-                   int *pnShapeCount )
-{
-    struct SHPDiskTreeInfo sDiskTree;
-    memset(&sDiskTree.sHooks, 0, sizeof(sDiskTree.sHooks));
-
-    /* We do not use SASetupDefaultHooks() because the FILE* */
-    /* is a libc FILE* */
-    sDiskTree.sHooks.FSeek = SHPTreeSeekLibc;
-    sDiskTree.sHooks.FRead = SHPTreeReadLibc;
-
-    sDiskTree.fpQIX = (SAFile)fp;
-
-    return SHPSearchDiskTreeEx( &sDiskTree, padfBoundsMin, padfBoundsMax,
-                                 pnShapeCount );
-}
-
-/***********************************************************************/
-/*                       SHPSearchDiskTreeEx()                         */
-/************************************************************************/
-
-int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, 
-                     double *padfBoundsMin, double *padfBoundsMax,
-                     int *pnShapeCount )
-
-{
-    int i, bNeedSwap, nBufferMax = 0;
-    unsigned char abyBuf[16];
-    int *panResultBuffer = NULL;
-
-    *pnShapeCount = 0;
-
-/* -------------------------------------------------------------------- */
-/*     Establish the byte order on this machine.                       */
-/* -------------------------------------------------------------------- */
-    i = 1;
-    if( *((unsigned char *) &i) == 1 )
-        bBigEndian = FALSE;
-    else
-        bBigEndian = TRUE;
-
-/* -------------------------------------------------------------------- */
-/*      Read the header.                                                */
-/* -------------------------------------------------------------------- */
-    hDiskTree->sHooks.FSeek( hDiskTree->fpQIX, 0, SEEK_SET );
-    hDiskTree->sHooks.FRead( abyBuf, 16, 1, hDiskTree->fpQIX );
-
-    if( memcmp( abyBuf, "SQT", 3 ) != 0 )
-        return NULL;
-
-    if( (abyBuf[3] == 2 && bBigEndian)
-        || (abyBuf[3] == 1 && !bBigEndian) )
-        bNeedSwap = FALSE;
-    else
-        bNeedSwap = TRUE;
-
-/* -------------------------------------------------------------------- */
-/*      Search through root node and it's decendents.                   */
-/* -------------------------------------------------------------------- */
-    if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
-                                &panResultBuffer, &nBufferMax, 
-                                pnShapeCount, bNeedSwap ) )
-    {
-        if( panResultBuffer != NULL )
-            free( panResultBuffer );
-        *pnShapeCount = 0;
-        return NULL;
-    }
-/* -------------------------------------------------------------------- */
-/*      Sort the id array                                               */
-/* -------------------------------------------------------------------- */
-    qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints);
-    
-    return panResultBuffer;
-}
-
-/************************************************************************/
-/*                        SHPGetSubNodeOffset()                         */
-/*                                                                      */
-/*      Determine how big all the subnodes of this node (and their      */
-/*      children) will be.  This will allow disk based searchers to     */
-/*      seek past them all efficiently.                                 */
-/************************************************************************/
-
-static int SHPGetSubNodeOffset( SHPTreeNode *node) 
-{
-    int i;
-    long offset=0;
-
-    for(i=0; i<node->nSubNodes; i++ ) 
-    {
-        if(node->apsSubNode[i]) 
-        {
-            offset += 4*sizeof(double) 
-                + (node->apsSubNode[i]->nShapeCount+3)*sizeof(int);
-            offset += SHPGetSubNodeOffset(node->apsSubNode[i]);
-        }
-    }
-
-    return(offset);
-}
-
-/************************************************************************/
-/*                          SHPWriteTreeNode()                          */
-/************************************************************************/
-
-static void SHPWriteTreeNode( SAFile fp, SHPTreeNode *node, SAHooks* psHooks) 
-{
-    int i,j;
-    int offset;
-    unsigned char *pabyRec = NULL;
-    assert( NULL != node );
-
-    offset = SHPGetSubNodeOffset(node);
-  
-    pabyRec = (unsigned char *) 
-        malloc(sizeof(double) * 4
-               + (3 * sizeof(int)) + (node->nShapeCount * sizeof(int)) );
-    if( NULL == pabyRec )
-    {
-#ifdef USE_CPL
-        CPLError( CE_Fatal, CPLE_OutOfMemory, "Memory allocation failure");
-#endif
-        assert( 0 );
-        return;
-    }
-
-    memcpy( pabyRec, &offset, 4);
-
-    /* minx, miny, maxx, maxy */
-    memcpy( pabyRec+ 4, node->adfBoundsMin+0, sizeof(double) );
-    memcpy( pabyRec+12, node->adfBoundsMin+1, sizeof(double) );
-    memcpy( pabyRec+20, node->adfBoundsMax+0, sizeof(double) );
-    memcpy( pabyRec+28, node->adfBoundsMax+1, sizeof(double) );
-
-    memcpy( pabyRec+36, &node->nShapeCount, 4);
-    j = node->nShapeCount * sizeof(int);
-    memcpy( pabyRec+40, node->panShapeIds, j);
-    memcpy( pabyRec+j+40, &node->nSubNodes, 4);
-
-    psHooks->FWrite( pabyRec, 44+j, 1, fp );
-    free (pabyRec);
-  
-    for(i=0; i<node->nSubNodes; i++ ) 
-    {
-        if(node->apsSubNode[i])
-            SHPWriteTreeNode( fp, node->apsSubNode[i], psHooks);
-    }
-}
-
-/************************************************************************/
-/*                            SHPWriteTree()                            */
-/************************************************************************/
-
-int SHPAPI_CALL SHPWriteTree(SHPTree *tree, const char *filename )
-{
-    SAHooks sHooks;
-
-    SASetupDefaultHooks( &sHooks );
-
-    return SHPWriteTreeLL(tree, filename, &sHooks);
-}
-
-/************************************************************************/
-/*                           SHPWriteTreeLL()                           */
-/************************************************************************/
-
-int SHPWriteTreeLL(SHPTree *tree, const char *filename, SAHooks* psHooks )
-{
-    char               signature[4] = "SQT";
-    int                        i;
-    char               abyBuf[32];
-    SAFile              fp;
-
-    SAHooks sHooks;
-    if (psHooks == NULL)
-    {
-        SASetupDefaultHooks( &sHooks );
-        psHooks = &sHooks;
-    }
-  
-/* -------------------------------------------------------------------- */
-/*      Open the output file.                                           */
-/* -------------------------------------------------------------------- */
-    fp = psHooks->FOpen(filename, "wb");
-    if( fp == NULL ) 
-    {
-        return FALSE;
-    }
-
-/* -------------------------------------------------------------------- */
-/*     Establish the byte order on this machine.                       */
-/* -------------------------------------------------------------------- */
-    i = 1;
-    if( *((unsigned char *) &i) == 1 )
-        bBigEndian = FALSE;
-    else
-        bBigEndian = TRUE;
-  
-/* -------------------------------------------------------------------- */
-/*      Write the header.                                               */
-/* -------------------------------------------------------------------- */
-    memcpy( abyBuf+0, signature, 3 );
-    
-    if( bBigEndian )
-        abyBuf[3] = 2; /* New MSB */
-    else
-        abyBuf[3] = 1; /* New LSB */
-
-    abyBuf[4] = 1; /* version */
-    abyBuf[5] = 0; /* next 3 reserved */
-    abyBuf[6] = 0;
-    abyBuf[7] = 0;
-
-    psHooks->FWrite( abyBuf, 8, 1, fp );
-
-    psHooks->FWrite( &(tree->nTotalCount), 4, 1, fp );
-
-    /* write maxdepth */
-
-    psHooks->FWrite( &(tree->nMaxDepth), 4, 1, fp );
-
-/* -------------------------------------------------------------------- */
-/*      Write all the nodes "in order".                                 */
-/* -------------------------------------------------------------------- */
-
-    SHPWriteTreeNode( fp, tree->psRoot, psHooks );  
-    
-    psHooks->FClose( fp );
-
-    return TRUE;
-}
diff --git a/src/HYDROData/shapelib/shputils.c b/src/HYDROData/shapelib/shputils.c
deleted file mode 100644 (file)
index b2c7f06..0000000
+++ /dev/null
@@ -1,1072 +0,0 @@
-/******************************************************************************
- * $Id: shputils.c,v 1.10 2007-12-13 19:59:23 fwarmerdam Exp $
- *
- * Project:  Shapelib
- * Purpose:  
- *   Altered "shpdump" and "dbfdump" to allow two files to be appended.
- *   Other Functions:
- *     Selecting from the DBF before the write occurs.
- *     Change the UNITS between Feet and Meters and Shift X,Y.
- *     Clip and Erase boundary.  The program only passes thru the
- *     data once.
- *
- *   Bill Miller   North Carolina - Department of Transporation 
- *   Feb. 1997 -- bmiller@dot.state.nc.us
- *         There was not a lot of time to debug hidden problems;
- *         And the code is not very well organized or documented.
- *         The clip/erase function was not well tested.
- *   Oct. 2000 -- bmiller@dot.state.nc.us
- *         Fixed the problem when select is using numbers
- *         larger than short integer.  It now reads long integer.
- *   NOTE: DBF files created using windows NT will read as a string with
- *         a length of 381 characters.  This is a bug in "dbfopen".
- *
- *
- * Author:   Bill Miller (bmiller@dot.state.nc.us)
- *
- ******************************************************************************
- * Copyright (c) 1999, 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
- * option is discussed in more detail in shapelib.html.
- *
- * --
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************
- *
- * $Log: shputils.c,v $
- * Revision 1.10  2007-12-13 19:59:23  fwarmerdam
- * reindent code, avoid some warnings.
- *
- * Revision 1.9  2004/01/14 14:56:00  fwarmerdam
- * Some cleanlyness improvements.
- *
- * Revision 1.8  2004/01/14 14:40:22  fwarmerdam
- * Fixed exit() call to include code.
- *
- * Revision 1.7  2003/02/25 17:20:22  warmerda
- * Set psCShape to NULL after SHPDestroyObject() to avoid multi-frees of
- * the same memory ... as submitted by Fred Fox.
- *
- * Revision 1.6  2001/08/28 13:57:14  warmerda
- * fixed DBFAddField return value check
- *
- * Revision 1.5  2000/11/02 13:52:48  warmerda
- * major upgrade from Bill Miller
- *
- * Revision 1.4  1999/11/05 14:12:05  warmerda
- * updated license terms
- *
- * Revision 1.3  1998/12/03 15:47:39  warmerda
- * Did a bunch of rewriting to make it work with the V1.2 API.
- *
- * Revision 1.2  1998/06/18 01:19:49  warmerda
- * Made C++ compilable.
- *
- * Revision 1.1  1997/05/27 20:40:27  warmerda
- * Initial revision
- */
-
-#include "shapefil.h"
-#include "string.h"
-#include <stdlib.h>
-
-SHP_CVSID("$Id: shputils.c,v 1.10 2007-12-13 19:59:23 fwarmerdam Exp $")
-
-#ifndef FALSE
-#  define FALSE                0
-#  define TRUE         1
-#endif
-
-char            infile[80], outfile[80], temp[400];
-
-/* Variables for shape files */
-SHPHandle      hSHP;
-SHPHandle      hSHPappend;
-int            nShapeType, nEntities, iPart;
-int            nShapeTypeAppend, nEntitiesAppend;
-SHPObject      *psCShape;
-double         adfBoundsMin[4], adfBoundsMax[4];
-
-
-/* Variables for DBF files */
-DBFHandle      hDBF;
-DBFHandle      hDBFappend;
-    
-DBFFieldType    iType;
-DBFFieldType    jType;
-    
-char   iszTitle[12];
-char   jszTitle[12];
-
-int    *pt;
-char   iszFormat[32], iszField[1024];
-char   jszFormat[32], jszField[1024];
-int    i, ti, iWidth, iDecimals, iRecord;
-int    j, tj, jWidth, jDecimals, jRecord;
-
-
-int clip_boundary();
-double findunit(char *unit);
-void openfiles(void);
-void setext(char *pt, char *ext);
-int strncasecmp2(char *s1, char *s2, int n);
-void mergefields(void);
-void findselect(void);
-void showitems(void);
-int selectrec();
-void check_theme_bnd();
-int clip_boundary();
-void error();
-
-
-/* -------------------------------------------------------------------- */
-/* Variables for the DESCRIBE function */
-/* -------------------------------------------------------------------- */
-   int       ilist = FALSE, iall = FALSE;
-/* -------------------------------------------------------------------- */
-/* Variables for the SELECT function */
-/* -------------------------------------------------------------------- */
-   int       found = FALSE, newdbf = FALSE;
-   char      selectitem[40], *cpt;
-   long int  selectvalues[150], selcount=0;
-   int       iselect = FALSE, iselectitem = -1;
-   int       iunselect = FALSE;
-
-/* -------------------------------------------------------------------- */
-/* Variables for the CLIP and ERASE functions */
-/* -------------------------------------------------------------------- */
-   double  cxmin, cymin, cxmax, cymax; 
-   int     iclip  = FALSE, ierase = FALSE;
-   int     itouch = FALSE, iinside = FALSE, icut = FALSE;
-   int     ibound = FALSE, ipoly = FALSE;
-   char    clipfile[80];
-
-/* -------------------------------------------------------------------- */
-/* Variables for the FACTOR function */
-/* -------------------------------------------------------------------- */
-   double  infactor,outfactor,factor = 0;  /* NO FACTOR */
-   int     iunit = FALSE;
-   int     ifactor = FALSE;
-
-   
-/* -------------------------------------------------------------------- */
-/* Variables for the SHIFT function */
-/* -------------------------------------------------------------------- */
-   double  xshift = 0, yshift = 0;  /* NO SHIFT */
-      
-int main( int argc, char ** argv )
-{
-
-/* -------------------------------------------------------------------- */
-/*      Check command line usage.                                       */
-/* -------------------------------------------------------------------- */
-    if( argc < 2 ) error();
-    strcpy(infile, argv[1]);
-    if (argc > 2) {
-        strcpy(outfile,argv[2]);
-        if (strncasecmp2(outfile, "LIST",0) == 0) { ilist = TRUE; }
-        if (strncasecmp2(outfile, "ALL",0) == 0)  { iall  = TRUE; }
-    } 
-    if (ilist || iall || argc == 2 ) {
-        setext(infile, "shp");
-        printf("DESCRIBE: %s\n",infile);
-        strcpy(outfile,"");
-    }
-/* -------------------------------------------------------------------- */
-/*     Look for other functions on the command line. (SELECT, UNIT)    */
-/* -------------------------------------------------------------------- */
-    for (i = 3; i < argc; i++)
-    {
-       if ((strncasecmp2(argv[i],  "SEL",3) == 0) ||
-            (strncasecmp2(argv[i],  "UNSEL",5) == 0))
-       {
-            if (strncasecmp2(argv[i],  "UNSEL",5) == 0) iunselect=TRUE;
-           i++;
-           if (i >= argc) error();
-           strcpy(selectitem,argv[i]);
-           i++;
-           if (i >= argc) error();
-           selcount=0;
-           strcpy(temp,argv[i]);
-           cpt=temp;
-           tj = atoi(cpt);
-           ti = 0;
-           while (tj>0) {
-                selectvalues[selcount] = tj;
-                while( *cpt >= '0' && *cpt <= '9')
-                    cpt++; 
-                while( *cpt > '\0' && (*cpt < '0' || *cpt > '9') )
-                    cpt++; 
-                tj=atoi(cpt);
-                selcount++;
-           }
-           iselect=TRUE;
-       }  /*** End SEL & UNSEL ***/
-       else
-            if ((strncasecmp2(argv[i], "CLIP",4) == 0) ||
-                (strncasecmp2(argv[i],  "ERASE",5) == 0))
-            {
-                if (strncasecmp2(argv[i],  "ERASE",5) == 0) ierase=TRUE;
-                i++;
-                if (i >= argc) error();
-                strcpy(clipfile,argv[i]);
-                sscanf(argv[i],"%lf",&cxmin);
-                i++;
-                if (i >= argc) error();
-                if (strncasecmp2(argv[i],  "BOUND",5) == 0) {
-                    setext(clipfile, "shp");
-                    hSHP = SHPOpen( clipfile, "rb" );
-                    if( hSHP == NULL )
-                    {
-                        printf( "ERROR: Unable to open the clip shape file:%s\n", clipfile );
-                        exit( 1 );
-                    }
-                    SHPGetInfo( hSHPappend, NULL, NULL,
-                                adfBoundsMin, adfBoundsMax );
-                    cxmin = adfBoundsMin[0];
-                    cymin = adfBoundsMin[1];
-                    cxmax = adfBoundsMax[0];
-                    cymax = adfBoundsMax[1];
-                    printf("Theme Clip Boundary: (%lf,%lf) - (%lf,%lf)\n",
-                           cxmin, cymin, cxmax, cymax);
-                    ibound=TRUE;
-                } else {  /*** xmin,ymin,xmax,ymax ***/
-                    sscanf(argv[i],"%lf",&cymin);
-                    i++;
-                    if (i >= argc) error();
-                    sscanf(argv[i],"%lf",&cxmax);
-                    i++;
-                    if (i >= argc) error();
-                    sscanf(argv[i],"%lf",&cymax);
-                    printf("Clip Box: (%lf,%lf) - (%lf,%lf)\n",cxmin, cymin, cxmax, cymax);
-                }
-                i++;
-                if (i >= argc) error();
-                if      (strncasecmp2(argv[i], "CUT",3) == 0)    icut=TRUE;
-                else if (strncasecmp2(argv[i], "TOUCH",5) == 0)  itouch=TRUE;
-                else if (strncasecmp2(argv[i], "INSIDE",6) == 0) iinside=TRUE;
-                else error();
-                iclip=TRUE;
-            } /*** End CLIP & ERASE ***/
-            else if (strncasecmp2(argv[i],  "FACTOR",0) == 0)
-            {
-                i++;
-               if (i >= argc) error();
-               infactor=findunit(argv[i]);
-               if (infactor == 0) error();
-                iunit=TRUE;
-                i++;
-               if (i >= argc) error();
-               outfactor=findunit(argv[i]);
-               if (outfactor == 0)
-               {
-                    sscanf(argv[i],"%lf",&factor);
-                    if (factor == 0) error();
-                }
-                if (factor == 0)
-                {
-                    if (infactor ==0)
-                    { puts("ERROR: Input unit must be defined before output unit"); exit(1); }
-                    factor=infactor/outfactor;
-                }
-                printf("Output file coordinate values will be factored by %lg\n",factor);
-                ifactor=(factor != 1); /* True if a valid factor */
-            } /*** End FACTOR ***/
-            else if (strncasecmp2(argv[i],"SHIFT",5) == 0)
-            {
-                i++;
-                if (i >= argc) error();
-                sscanf(argv[i],"%lf",&xshift);
-                i++;
-                if (i >= argc) error();
-                sscanf(argv[i],"%lf",&yshift);
-                iunit=TRUE;
-                printf("X Shift: %lg   Y Shift: %lg\n",xshift,yshift);
-            } /*** End SHIFT ***/
-            else {
-                printf("ERROR: Unknown function %s\n",argv[i]);  error();
-            }
-    }
-/* -------------------------------------------------------------------- */
-/*     If there is no data in this file let the user know.             */
-/* -------------------------------------------------------------------- */
-    openfiles();  /* Open the infile and the outfile for shape and dbf. */
-    if( DBFGetFieldCount(hDBF) == 0 )
-    {
-       puts( "There are no fields in this table!" );
-       exit( 1 );
-    }
-/* -------------------------------------------------------------------- */
-/*      Print out the file bounds.                                      */
-/* -------------------------------------------------------------------- */
-    iRecord = DBFGetRecordCount( hDBF );
-    SHPGetInfo( hSHP, NULL, NULL, adfBoundsMin, adfBoundsMax );
-
-    printf( "Input Bounds:  (%lg,%lg) - (%lg,%lg)   Entities: %d   DBF: %d\n",
-           adfBoundsMin[0], adfBoundsMin[1],
-            adfBoundsMax[0], adfBoundsMax[1],
-            nEntities, iRecord );
-           
-    if (strcmp(outfile,"") == 0) /* Describe the shapefile; No other functions */
-    {
-       ti = DBFGetFieldCount( hDBF );
-       showitems();
-       exit(0);
-    }
-     
-    if (iclip) check_theme_bnd();
-    
-    jRecord = DBFGetRecordCount( hDBFappend );
-    SHPGetInfo( hSHPappend, NULL, NULL, adfBoundsMin, adfBoundsMax );
-    if (nEntitiesAppend == 0)
-        puts("New Output File\n");
-    else
-        printf( "Append Bounds: (%lg,%lg)-(%lg,%lg)   Entities: %d  DBF: %d\n",
-                adfBoundsMin[0], adfBoundsMin[1],
-                adfBoundsMax[0], adfBoundsMax[1],
-                nEntitiesAppend, jRecord );
-    
-/* -------------------------------------------------------------------- */
-/*     Find matching fields in the append file or add new items.       */
-/* -------------------------------------------------------------------- */
-    mergefields();
-/* -------------------------------------------------------------------- */
-/*     Find selection field if needed.                                 */
-/* -------------------------------------------------------------------- */
-    if (iselect)    findselect();
-
-/* -------------------------------------------------------------------- */
-/*  Read all the records                                               */
-/* -------------------------------------------------------------------- */
-    jRecord = DBFGetRecordCount( hDBFappend );
-    for( iRecord = 0; iRecord < nEntities; iRecord++)  /** DBFGetRecordCount(hDBF) **/
-    {
-/* -------------------------------------------------------------------- */
-/*      SELECT for values if needed. (Can the record be skipped.)       */
-/* -------------------------------------------------------------------- */
-        if (iselect)
-            if (selectrec() == 0) goto SKIP_RECORD;   /** SKIP RECORD **/
-
-/* -------------------------------------------------------------------- */
-/*      Read a Shape record                                             */
-/* -------------------------------------------------------------------- */
-        psCShape = SHPReadObject( hSHP, iRecord );
-
-/* -------------------------------------------------------------------- */
-/*      Clip coordinates of shapes if needed.                           */
-/* -------------------------------------------------------------------- */
-        if (iclip)
-            if (clip_boundary() == 0) goto SKIP_RECORD; /** SKIP RECORD **/
-
-/* -------------------------------------------------------------------- */
-/*      Read a DBF record and copy each field.                          */
-/* -------------------------------------------------------------------- */
-       for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
-       {
-/* -------------------------------------------------------------------- */
-/*      Store the record according to the type and formatting           */
-/*      information implicit in the DBF field description.              */
-/* -------------------------------------------------------------------- */
-            if (pt[i] > -1)  /* if the current field exists in output file */
-            {
-                switch( DBFGetFieldInfo( hDBF, i, NULL, &iWidth, &iDecimals ) )
-                {
-                  case FTString:
-                  case FTLogical:
-                    DBFWriteStringAttribute(hDBFappend, jRecord, pt[i],
-                                            (DBFReadStringAttribute( hDBF, iRecord, i )) );
-                    break;
-
-                  case FTInteger:
-                    DBFWriteIntegerAttribute(hDBFappend, jRecord, pt[i],
-                                             (DBFReadIntegerAttribute( hDBF, iRecord, i )) );
-                    break;
-
-                  case FTDouble:
-                    DBFWriteDoubleAttribute(hDBFappend, jRecord, pt[i],
-                                            (DBFReadDoubleAttribute( hDBF, iRecord, i )) );
-                    break;
-
-                  case FTInvalid:
-                    break;
-                }
-            }
-       }
-       jRecord++;
-/* -------------------------------------------------------------------- */
-/*      Change FACTOR and SHIFT coordinates of shapes if needed.        */
-/* -------------------------------------------------------------------- */
-        if (iunit)
-        {
-           for( j = 0; j < psCShape->nVertices; j++ ) 
-           {
-                psCShape->padfX[j] = psCShape->padfX[j] * factor + xshift;
-                psCShape->padfY[j] = psCShape->padfY[j] * factor + yshift;
-           }
-        }
-        
-/* -------------------------------------------------------------------- */
-/*      Write the Shape record after recomputing current extents.       */
-/* -------------------------------------------------------------------- */
-        SHPComputeExtents( psCShape );
-        SHPWriteObject( hSHPappend, -1, psCShape );
-
-      SKIP_RECORD:
-        SHPDestroyObject( psCShape );
-        psCShape = NULL;
-        j=0;
-    }
-
-/* -------------------------------------------------------------------- */
-/*      Print out the # of Entities and the file bounds.                */
-/* -------------------------------------------------------------------- */
-    jRecord = DBFGetRecordCount( hDBFappend );
-    SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend,
-                adfBoundsMin, adfBoundsMax );
-    
-    printf( "Output Bounds: (%lg,%lg) - (%lg,%lg)   Entities: %d  DBF: %d\n\n",
-           adfBoundsMin[0], adfBoundsMin[1],
-            adfBoundsMax[0], adfBoundsMax[1],
-            nEntitiesAppend, jRecord );
-
-/* -------------------------------------------------------------------- */
-/*      Close the both shapefiles.                                      */
-/* -------------------------------------------------------------------- */
-    SHPClose( hSHP );
-    SHPClose( hSHPappend );
-    DBFClose( hDBF );
-    DBFClose( hDBFappend );
-    if (nEntitiesAppend == 0) {
-        puts("Remove the output files.");
-        setext(outfile, "dbf");
-        remove(outfile);
-        setext(outfile, "shp");
-        remove(outfile);
-        setext(outfile, "shx");
-        remove(outfile);
-    }
-    return( 0 );
-}
-
-
-/************************************************************************/
-/*                             openfiles()                              */
-/************************************************************************/
-
-void openfiles() {
-/* -------------------------------------------------------------------- */
-/*      Open the DBF file.                                              */
-/* -------------------------------------------------------------------- */
-    setext(infile, "dbf");
-    hDBF = DBFOpen( infile, "rb" );
-    if( hDBF == NULL )
-    {
-       printf( "ERROR: Unable to open the input DBF:%s\n", infile );
-       exit( 1 );
-    }
-/* -------------------------------------------------------------------- */
-/*      Open the append DBF file.                                       */
-/* -------------------------------------------------------------------- */
-    if (strcmp(outfile,"")) {
-        setext(outfile, "dbf");
-        hDBFappend = DBFOpen( outfile, "rb+" );
-        newdbf=0;
-        if( hDBFappend == NULL )
-        {
-            newdbf=1;
-            hDBFappend = DBFCreate( outfile );
-            if( hDBFappend == NULL )
-            {
-                printf( "ERROR: Unable to open the append DBF:%s\n", outfile );
-                exit( 1 );
-            }
-        }
-    }
-/* -------------------------------------------------------------------- */
-/*      Open the passed shapefile.                                      */
-/* -------------------------------------------------------------------- */
-    setext(infile, "shp");
-    hSHP = SHPOpen( infile, "rb" );
-
-    if( hSHP == NULL )
-    {
-       printf( "ERROR: Unable to open the input shape file:%s\n", infile );
-       exit( 1 );
-    }
-
-    SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
-
-/* -------------------------------------------------------------------- */
-/*      Open the passed append shapefile.                               */
-/* -------------------------------------------------------------------- */
-    if (strcmp(outfile,"")) {
-        setext(outfile, "shp");
-        hSHPappend = SHPOpen( outfile, "rb+" );
-
-        if( hSHPappend == NULL )
-        {
-            hSHPappend = SHPCreate( outfile, nShapeType );
-            if( hSHPappend == NULL )
-            {
-                printf( "ERROR: Unable to open the append shape file:%s\n",
-                        outfile );
-                exit( 1 );
-            }
-        }
-        SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend,
-                    NULL, NULL );
-
-        if (nShapeType != nShapeTypeAppend) 
-        {
-            puts( "ERROR: Input and Append shape files are of different types.");
-            exit( 1 );
-        }
-    }
-}
-
-/* -------------------------------------------------------------------- */
-/*     Change the extension.  If there is any extension on the         */
-/*     filename, strip it off and add the new extension                */
-/* -------------------------------------------------------------------- */
-void setext(char *pt, char *ext)
-{
-int i;
-    for( i = strlen(pt)-1; 
-        i > 0 && pt[i] != '.' && pt[i] != '/' && pt[i] != '\\';
-        i-- ) {}
-
-    if( pt[i] == '.' )
-        pt[i] = '\0';
-        
-    strcat(pt,".");
-    strcat(pt,ext);
-}
-
-
-
-/* -------------------------------------------------------------------- */
-/*     Find matching fields in the append file.                        */
-/*      Output file must have zero records to add any new fields.       */
-/* -------------------------------------------------------------------- */
-void mergefields()
-{
-    int i,j;
-    ti = DBFGetFieldCount( hDBF );
-    tj = DBFGetFieldCount( hDBFappend );
-    /* Create a pointer array for the max # of fields in the output file */
-    pt = (int *) malloc( (ti+tj+1) * sizeof(int) ); 
-    
-    for( i = 0; i < ti; i++ )
-    {
-        pt[i]= -1;  /* Initial pt values to -1 */
-    }
-    /* DBF must be empty before adding items */
-    jRecord = DBFGetRecordCount( hDBFappend );
-    for( i = 0; i < ti; i++ )
-    {
-       iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
-        found=FALSE;
-        {
-           for( j = 0; j < tj; j++ )   /* Search all field names for a match */
-           {
-               jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals );
-               if (iType == jType && (strcmp(iszTitle, jszTitle) == 0) )
-               {
-                   if (found || newdbf)
-                   {
-                       if (i == j)  pt[i]=j;
-                       printf("Warning: Duplicate field name found (%s)\n",iszTitle);
-                       /* Duplicate field name
-                          (Try to guess the correct field by position) */
-                   }
-                   else
-                   {
-                       pt[i]=j;  found=TRUE; 
-                   }
-               }
-           }
-       }
-       
-       if (pt[i] == -1  && (! found) )  /* Try to force into an existing field */
-       {                                /* Ignore the field name, width, and decimal places */
-           jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals );
-           if (iType == jType) 
-           {
-               pt[i]=i;  found=1;
-           }
-       }
-       if ( (! found) &&  jRecord == 0)  /* Add missing field to the append table */
-       {                 /* The output DBF must be is empty */
-           pt[i]=tj;
-           tj++;
-           if( DBFAddField( hDBFappend, iszTitle, iType, iWidth, iDecimals )
-                == -1 )
-           {
-               printf( "Warning: DBFAddField(%s, TYPE:%d, WIDTH:%d  DEC:%d, ITEM#:%d of %d) failed.\n",
-                        iszTitle, iType, iWidth, iDecimals, (i+1), (ti+1) );
-               pt[i]=-1;
-           }
-       }
-    }
-}
-
-
-void findselect()
-{
-    /* Find the select field name */
-    iselectitem = -1;
-    for( i = 0; i < ti  &&  iselectitem < 0; i++ )
-    {
-       iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
-        if (strncasecmp2(iszTitle, selectitem, 0) == 0) iselectitem = i;
-    }
-    if (iselectitem == -1) 
-    {
-        printf("Warning: Item not found for selection (%s)\n",selectitem);
-        iselect = FALSE;
-        iall = FALSE;
-       showitems();
-        printf("Continued... (Selecting entire file)\n");
-    }
-    /* Extract all of the select values (by field type) */
-    
-}
-
-void showitems()
-{
-    char      stmp[40],slow[40],shigh[40];
-    double    dtmp,dlow,dhigh,dsum,mean;
-    long int  itmp,ilow,ihigh,isum;
-    long int  maxrec;
-    char      *pt;
-
-    printf("Available Items: (%d)",ti);
-    maxrec = DBFGetRecordCount(hDBF);
-    if (maxrec > 5000 && ! iall) 
-    { maxrec=5000; printf("  ** ESTIMATED RANGES (MEAN)  For more records use \"All\""); }
-    else  { printf("          RANGES (MEAN)"); }
-          
-    for( i = 0; i < ti; i++ )
-    {
-        switch( DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ) )
-        {
-          case FTString:
-          case FTLogical:
-            strcpy(slow, "~");
-            strcpy(shigh,"\0");
-            printf("\n  String  %3d  %-16s",iWidth,iszTitle);
-            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-                strncpy(stmp,DBFReadStringAttribute( hDBF, iRecord, i ),39);
-                if (strcmp(stmp,"!!") > 0) {
-                    if (strncasecmp2(stmp,slow,0)  < 0) strncpy(slow, stmp,39);
-                    if (strncasecmp2(stmp,shigh,0) > 0) strncpy(shigh,stmp,39);
-                }
-            }
-            pt=slow+strlen(slow)-1; 
-            while(*pt == ' ') { *pt='\0'; pt--; }
-            pt=shigh+strlen(shigh)-1;
-            while(*pt == ' ') { *pt='\0'; pt--; }
-            if (strncasecmp2(slow,shigh,0) < 0)                printf("%s to %s",slow,shigh);
-            else if (strncasecmp2(slow,shigh,0) == 0)  printf("= %s",slow);
-            else       printf("No Values");
-            break;
-          case FTInteger:
-            printf("\n  Integer %3d  %-16s",iWidth,iszTitle);
-            ilow =  1999999999;
-            ihigh= -1999999999;
-            isum =  0;
-            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-                itmp = DBFReadIntegerAttribute( hDBF, iRecord, i );
-                if (ilow > itmp)  ilow = itmp;
-                if (ihigh < itmp) ihigh = itmp;
-                isum = isum + itmp;
-            }
-            mean=isum/maxrec;
-            if (ilow < ihigh)       printf("%ld to %ld \t(%.1f)",ilow,ihigh,mean);
-            else if (ilow == ihigh) printf("= %ld",ilow);
-            else printf("No Values");
-            break;
-
-          case FTDouble:
-            printf("\n  Real  %3d,%d  %-16s",iWidth,iDecimals,iszTitle);
-            dlow =  999999999999999.0;
-            dhigh= -999999999999999.0;
-            dsum =  0;
-            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-                dtmp = DBFReadDoubleAttribute( hDBF, iRecord, i );
-                if (dlow > dtmp) dlow = dtmp;
-                if (dhigh < dtmp) dhigh = dtmp;
-                dsum = dsum + dtmp;
-            }
-            mean=dsum/maxrec;
-            sprintf(stmp,"%%.%df to %%.%df \t(%%.%df)",iDecimals,iDecimals,iDecimals);
-            if (dlow < dhigh)       printf(stmp,dlow,dhigh,mean);
-            else if (dlow == dhigh) {
-                sprintf(stmp,"= %%.%df",iDecimals);
-                printf(stmp,dlow);
-            }
-            else printf("No Values");
-            break;
-
-          case FTInvalid:
-            break;
-
-        }
-
-    }
-    printf("\n");
-}
-
-int selectrec()
-{
-    long int value, ty;
-
-    ty = DBFGetFieldInfo( hDBF, iselectitem, NULL, &iWidth, &iDecimals);
-    switch(ty)
-    {
-      case FTString:
-        puts("Invalid Item");
-        iselect=FALSE;
-       break;
-      case FTInteger:
-        value = DBFReadIntegerAttribute( hDBF, iRecord, iselectitem );
-        for (j = 0; j<selcount; j++)
-        {
-            if (selectvalues[j] == value)
-            {
-                if (iunselect) return(0);  /* Keep this record */
-                else  return(1);  /* Skip this record */
-            }
-        }
-       break;
-      case FTDouble:
-        puts("Invalid Item");
-        iselect=FALSE;
-        break;
-    }
-    if (iunselect) return(1);  /* Skip this record */
-    else  return(0);  /* Keep this record */
-}
-
-
-void check_theme_bnd()
-{
-    if ( (adfBoundsMin[0] >= cxmin) && (adfBoundsMax[0] <= cxmax) &&
-         (adfBoundsMin[1] >= cymin) && (adfBoundsMax[1] <= cymax) )
-    {   /** Theme is totally inside clip area **/
-        if (ierase) nEntities=0; /** SKIP THEME  **/
-        else   iclip=FALSE; /** WRITE THEME (Clip not needed) **/
-    }
-            
-    if ( ( (adfBoundsMin[0] < cxmin) && (adfBoundsMax[0] < cxmin) ) ||
-         ( (adfBoundsMin[1] < cymin) && (adfBoundsMax[1] < cymin) ) ||
-         ( (adfBoundsMin[0] > cxmax) && (adfBoundsMax[0] > cxmax) ) ||
-         ( (adfBoundsMin[1] > cymax) && (adfBoundsMax[1] > cymax) ) )
-    {   /** Theme is totally outside clip area **/
-        if (ierase) iclip=FALSE; /** WRITE THEME (Clip not needed) **/
-             else   nEntities=0; /** SKIP THEME  **/
-    }
-            
-    if (nEntities == 0)
-        puts("WARNING: Theme is outside the clip area."); /** SKIP THEME  **/
-}
-
-int clip_boundary()
-{
-    int  inside;
-    int  prev_outside;
-    int  i2;
-    int  j2;
-    
-    /*** FIRST check the boundary of the feature ***/
-    if ( ( (psCShape->dfXMin < cxmin) && (psCShape->dfXMax < cxmin) ) ||
-         ( (psCShape->dfYMin < cymin) && (psCShape->dfYMax < cymin) ) ||
-         ( (psCShape->dfXMin > cxmax) && (psCShape->dfXMax > cxmax) ) ||
-         ( (psCShape->dfYMin > cymax) && (psCShape->dfYMax > cymax) ) )
-    {   /** Feature is totally outside clip area **/
-        if (ierase) return(1); /** WRITE RECORD **/
-        else   return(0); /** SKIP  RECORD **/
-    }
-       
-    if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) &&
-         (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) )
-    {   /** Feature is totally inside clip area **/
-        if (ierase) return(0); /** SKIP  RECORD **/
-        else   return(1); /** WRITE RECORD **/
-    }
-            
-    if (iinside) 
-    { /** INSIDE * Feature might touch the boundary or could be outside **/
-        if (ierase)  return(1); /** WRITE RECORD **/
-        else    return(0); /** SKIP  RECORD **/
-    }
-       
-    if (itouch)
-    {   /** TOUCH **/
-        if ( ( (psCShape->dfXMin <= cxmin) || (psCShape->dfXMax >= cxmax) ) && 
-             (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax)    )
-        {   /** Feature intersects the clip boundary only on the X axis **/
-            if (ierase) return(0); /** SKIP  RECORD **/
-            else   return(1); /** WRITE RECORD **/
-        }
-
-        if (   (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax)   && 
-               ( (psCShape->dfYMin <= cymin) || (psCShape->dfYMax >= cymax) )  )
-        {   /** Feature intersects the clip boundary only on the Y axis **/
-            if (ierase) return(0); /** SKIP  RECORD **/
-            else   return(1); /** WRITE RECORD **/
-        }
-               
-        for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
-        {   /** At least one vertex must be inside the clip boundary **/
-            if ( (psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax) ||
-                 (psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax)  )
-            {
-                if (ierase) return(0); /** SKIP  RECORD **/
-                else   return(1); /** WRITE RECORD **/
-            }
-        }
-               
-        /** All vertices are outside the clip boundary **/ 
-        if (ierase) return(1); /** WRITE RECORD **/
-        else   return(0); /** SKIP  RECORD **/
-    }   /** End TOUCH **/
-          
-    if (icut)
-    {   /** CUT **/
-        /*** Check each vertex in the feature with the Boundary and "CUT" ***/
-        /*** THIS CODE WAS NOT COMPLETED!  READ NOTE AT THE BOTTOM ***/
-        i2=0;
-        prev_outside=FALSE;
-        for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
-        {
-            inside = psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax  &&
-                psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax ;
-                      
-            if (ierase) inside=(! inside);
-            if (inside)
-            {
-                if (i2 != j2)
-                {
-                    if (prev_outside)
-                    {
-                        /*** AddIntersection(i2); ***/  /*** Add intersection ***/
-                        prev_outside=FALSE;
-                    }
-                    psCShape->padfX[i2]=psCShape->padfX[j2];     /** move vertex **/
-                    psCShape->padfY[i2]=psCShape->padfY[j2];
-                }
-                i2++;
-            } else {
-                if ( (! prev_outside) && (j2 > 0) )
-                {
-                    /*** AddIntersection(i2); ***//*** Add intersection (Watch out for j2==i2-1) ***/
-                    /*** Also a polygon may overlap twice and will split into a several parts  ***/
-                    prev_outside=TRUE;
-                }
-            }
-        }
-             
-        printf("Vertices:%d   OUT:%d   Number of Parts:%d\n",
-               psCShape->nVertices,i2, psCShape->nParts );
-               
-        psCShape->nVertices = i2;
-             
-        if (i2 < 2) return(0); /** SKIP RECORD **/
-        /*** (WE ARE NOT CREATING INTERESECTIONS and some lines could be reduced to one point) **/
-        
-        if (i2 == 0) return(0); /** SKIP  RECORD **/
-        else    return(1); /** WRITE RECORD **/
-    }  /** End CUT **/
-}
-
-
-/************************************************************************/
-/*                            strncasecmp2()                            */
-/*                                                                      */
-/*      Compare two strings up to n characters                          */
-/*      If n=0 then s1 and s2 must be an exact match                    */
-/************************************************************************/
-
-int strncasecmp2(char *s1, char *s2, int n)
-
-{
-int j,i;
-   if (n<1) n=strlen(s1)+1;
-   for (i=0; i<n; i++)
-   {
-      if (*s1 != *s2)
-      {
-         if (*s1 >= 'a' && *s1 <= 'z') {
-            j=*s1-32;
-            if (j != *s2) return(*s1-*s2);
-         } else {
-            if (*s1 >= 'A' && *s1 <= 'Z') { j=*s1+32; }
-                                   else   { j=*s1;    }
-            if (j != *s2) return(*s1-*s2); 
-         }
-      }
-      s1++;
-      s2++;
-   }
-   return(0);
-}
-
-
-#define  NKEYS (sizeof(unitkeytab) / sizeof(struct unitkey))
-double findunit(char *unit)
-   {
-   struct unitkey {
-     char   *name;
-     double value;
-   } unitkeytab[] = {
-     "CM",            39.37,
-     "CENTIMETER",    39.37,
-     "CENTIMETERS",   39.37,  /** # of inches * 100 in unit **/
-     "METER",          3937,
-     "METERS",         3937,
-     "KM",          3937000,
-     "KILOMETER",   3937000, 
-     "KILOMETERS",  3937000,
-     "INCH",            100,
-     "INCHES",          100,
-     "FEET",           1200,
-     "FOOT",           1200,
-     "YARD",           3600,
-     "YARDS",          3600,       
-     "MILE",        6336000,
-     "MILES",       6336000  
-   };
-
-   double unitfactor=0;
-   for (j = 0; j < NKEYS; j++) {
-    if (strncasecmp2(unit, unitkeytab[j].name, 0) == 0) unitfactor=unitkeytab[j].value;
-   }
-   return(unitfactor);
-}
-
-/* -------------------------------------------------------------------- */
-/*      Display a usage message.                                        */
-/* -------------------------------------------------------------------- */
-void error()
-{      
-    puts( "The program will append to an existing shape file or it will" );
-    puts( "create a new file if needed." );
-    puts( "Only the items in the first output file will be preserved." );
-    puts( "When an item does not match with the append theme then the item");
-    puts( "might be placed to an existing item at the same position and type." );
-    puts( "  OTHER FUNCTIONS:" );
-    puts( "  - Describe all items in the dbase file (Use ALL for more than 5000 recs.)");
-    puts( "  - Select a group of shapes from a comma separated selection list.");
-    puts( "  - UnSelect a group of shapes from a comma separated selection list.");
-    puts( "  - Clip boundary extent or by theme boundary." );
-    puts( "      Touch writes all the shapes that touch the boundary.");
-    puts( "      Inside writes all the shapes that are completely within the boundary.");
-    puts( "      Boundary clips are only the min and max of a theme boundary." );
-    puts( "  - Erase boundary extent or by theme boundary." );
-    puts( "      Erase is the direct opposite of the Clip function." );
-    puts( "  - Change coordinate value units between meters and feet.");
-    puts( "      There is no way to determine the input unit of a shape file.");
-    puts( "      Skip this function if the shape file is already in the correct unit.");
-    puts( "      Clip and Erase will be done before the unit is changed.");
-    puts( "      A shift will be done after the unit is changed."); 
-    puts( "  - Shift X and Y coordinates.\n" );
-    puts( "Finally, There can only be one select or unselect in the command line.");
-    puts( "         There can only be one clip or erase in the command line.");
-    puts( "         There can only be one unit and only one shift in the command line.\n");
-    puts( "Ex: shputils in.shp out.shp   SELECT countycode 3,5,9,13,17,27");
-    puts( "    shputils in.shp out.shp   CLIP   10 10 90 90 Touch   FACTOR Meter Feet");
-    puts( "    shputils in.shp out.shp   FACTOR Meter 3.0");
-    puts( "    shputils in.shp out.shp   CLIP   clip.shp Boundary Touch   SHIFT 40 40");
-    puts( "    shputils in.shp out.shp   SELECT co 112   CLIP clip.shp Boundary Touch\n");
-    puts( "USAGE: shputils  <DescribeShape>   {ALL}");
-    puts( "USAGE: shputils  <InputShape>  <OutShape|AppendShape>" );
-    puts( "   { <FACTOR>       <FEET|MILES|METERS|KM> <FEET|MILES|METERS|KM|factor> }" );
-    puts( "   { <SHIFT>        <xshift> <yshift> }" );
-    puts( "   { <SELECT|UNSEL> <Item> <valuelist> }" );
-    puts( "   { <CLIP|ERASE>   <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
-    puts( "   { <CLIP|ERASE>   <theme>      <BOUNDARY>     <TOUCH|INSIDE|CUT> }" );
-    puts( "     Note: CUT is not complete and does not create intersections.");
-    puts( "           For more information read programmer comment.");
-       
-    /****   Clip functions for Polygon and Cut is not supported
-            There are several web pages that describe methods of doing this function.
-            It seem easy to impliment until you start writting code.  I don't have the
-            time to add these functions but a did leave a simple cut routine in the 
-            program that can be called by using CUT instead of TOUCH in the 
-            CLIP or ERASE functions.  It does not add the intersection of the line and
-            the clip box, so polygons could look incomplete and lines will come up short.
-       
-            Information about clipping lines with a box:
-            http://www.csclub.uwaterloo.ca/u/mpslager/articles/sutherland/wr.html
-            Information about finding the intersection of two lines:
-            http://www.whisqu.se/per/docs/math28.htm
-          
-            THE CODE LOOKS LIKE THIS:
-            ********************************************************     
-            void Intersect_Lines(float x0,float y0,float x1,float y1,
-            float x2,float y2,float x3,float y3,
-            float *xi,float *yi)
-            {
-//  this function computes the intersection of the sent lines
-//  and returns the intersection point, note that the function assumes
-//  the lines intersect. the function can handle vertical as well
-//  as horizontal lines. note the function isn't very clever, it simply
-//  applies the math, but we don't need speed since this is a
-//  pre-processing step
-//  The Intersect_lines program came from (http://www.whisqu.se/per/docs/math28.htm)
-
-float a1,b1,c1, // constants of linear equations 
-a2,b2,c2,
-det_inv,  // the inverse of the determinant of the coefficientmatrix
-m1,m2;    // the slopes of each line
-      
-// compute slopes, note the cludge for infinity, however, this will
-// be close enough
-if ((x1-x0)!=0)
-m1 = (y1-y0)/(x1-x0);
-else
-m1 = (float)1e+10;  // close enough to infinity
-   
-   
-if ((x3-x2)!=0) 
-m2 = (y3-y2)/(x3-x2);
-else
-m2 = (float)1e+10;  // close enough to infinity
-   
-// compute constants
-a1 = m1;
-a2 = m2;
-b1 = -1;
-b2 = -1;
-c1 = (y0-m1*x0);
-c2 = (y2-m2*x2);
-// compute the inverse of the determinate
-det_inv = 1/(a1*b2 - a2*b1);
-// use Kramers rule to compute xi and yi
-*xi=((b1*c2 - b2*c1)*det_inv);
-*yi=((a2*c1 - a1*c2)*det_inv);
-} // end Intersect_Lines
-    **********************************************************/
-
-    exit( 1 );
-}
index b036383260559525859a90efe0ce550458bc1074..ed9f63e832a575303b2659c6a4a7376f52cb58f4 100644 (file)
@@ -292,13 +292,14 @@ include_directories(
 #  ${GEOM_ROOT_DIR}/include/salome
   ${GEOM_INCLUDE_DIRS}
   ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../shapelib
   ${CMAKE_CURRENT_SOURCE_DIR}/../HYDROData
   ${VTK_INCLUDE_DIRS}
 )
 
 
 add_library(HYDROGUI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${PROJECT_HEADERS_MOC})
-target_link_libraries(HYDROGUI HYDROData
+target_link_libraries(HYDROGUI HYDROData shapelib
     ${CAS_TKV3d} ${CAS_TKTopAlgo} ${CAS_TKBrep} ${CAS_TKBO}
     ${GUI_LightApp} ${GUI_CAM} ${GUI_suit} ${GUI_qtx} ${GUI_ObjBrowser} ${GUI_GraphicsView} ${GUI_std} 
     ${GUI_Event} ${GUI_OCCViewer} ${GEOM_GEOM} ${GEOM_GEOMBase} ${GEOM_CurveCreator}
index 886424df1b8fccb415d5ac2041b2334de872ab5f..3fd45f81738620c3119d9171c1928e5556ab0184 100644 (file)
@@ -27,7 +27,7 @@
 #include <vector>
 
 //extern "C" {
-#include <shapelib/shapefil.h> 
+#include <shapefil.h> 
 //};
 
 class SUIT_FileDlg;
index 35c8ef8405df287f840ac8133cef010b11e45473..62fe730174a0730353690de1483898a2da092ff6 100644 (file)
@@ -28,7 +28,7 @@
 #include <QMap>
 
 //extern "C" {
-#include <shapelib/shapefil.h> 
+#include <shapefil.h> 
 //};
 
 class SUIT_FileDlg;
index 157336258bfcc613445b36763078cb780c4cf34d..203b8c8f368f1790c309b6d92612a0602b23ad0d 100644 (file)
@@ -27,7 +27,7 @@
 #include <vector>
 
 //extern "C" {
-#include <shapelib/shapefil.h> 
+#include <shapefil.h> 
 //};
 
 class SUIT_FileDlg;