/[thuban]/branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1612 by jan, Tue Aug 19 21:29:25 2003 UTC revision 2212 by bh, Mon May 17 15:47:57 2004 UTC
# Line 34  Line 34 
34   ******************************************************************************   ******************************************************************************
35   *   *
36   * $Log$   * $Log$
37   * Revision 1.1  2003/08/19 21:29:25  jan   * Revision 1.3  2004/05/17 15:47:57  bh
38   * These files have been moved here from thuban/extensions/shapelib/   * Update to newest shapelib and get rid of Thuban specific extensions,
39   * See there in the Attic for the older history.   * i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge
40   *   *
41   * Revision 1.3  2002/05/07 14:09:45  bh   * * libraries/shapelib/shpopen.c: Update to version from current
42   * * extensions/shapelib/shpopen.c, extensions/shapelib/shapefil.h,   * shapelib CVS.
43   * extensions/shapelib/dbfopen.c: Really update to the versions of   *
44   * shapelib 1.2.9. For some reason it wasn't really done on   * * libraries/shapelib/shapefil.h: Update to version from current
45   * 2002-04-11.   * shapelib CVS.
46     *
47     * * libraries/shapelib/dbfopen.c: Update to version from current
48     * shapelib CVS.
49     * (DBFCommit): Effectively removed since shapelib itself has
50     * DBFUpdateHeader now which is better for what DBFCommit wanted to
51     * achieve.
52     * We're now using an unmodified version of dbfopen.
53     *
54     * * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py:
55     * Update from dbflib.i
56     *
57     * * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of
58     * the commit method.  This new indirection is necessary because we use the
59     * DBFUpdateHeader function now which is not available in shapelib <=
60     * 1.2.10
61     * (DBFFile::commit): Use DBFInfo_commit as implementation
62     * (pragma __class__): New. Kludge to remove the commit method when
63     * the DBFUpdateHeader function isn't available
64     * (_have_commit): New. Helper for the pragma kludge.
65     *
66     * * libraries/pyshapelib/setup.py (dbf_macros): New. Return the
67     * preprocessor macros needed to compile the dbflib wrapper.  Determine
68     * whether DBFUpdateHeader is available and define the right value of
69     * HAVE_UPDATE_HEADER
70     * (extensions): Use dbf_macros for the dbflibc extension
71     *
72     * * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with
73     * value '1' to the Lib.dbflibc extension.  This simply reflects the
74     * shapelib and pyshapelib updates
75     *
76     * Revision 1.44  2003/12/29 00:18:39  fwarmerdam
77     * added error checking for failed IO and optional CPL error reporting
78     *
79     * Revision 1.43  2003/12/01 16:20:08  warmerda
80     * be careful of zero vertex shapes
81     *
82     * Revision 1.42  2003/12/01 14:58:27  warmerda
83     * added degenerate object check in SHPRewindObject()
84     *
85     * Revision 1.41  2003/07/08 15:22:43  warmerda
86     * avoid warning
87     *
88     * Revision 1.40  2003/04/21 18:30:37  warmerda
89     * added header write/update public methods
90     *
91     * Revision 1.39  2002/08/26 06:46:56  warmerda
92     * avoid c++ comments
93     *
94     * Revision 1.38  2002/05/07 16:43:39  warmerda
95     * Removed debugging printf.
96     *
97     * Revision 1.37  2002/04/10 17:35:22  warmerda
98     * fixed bug in ring reversal code
99     *
100     * Revision 1.36  2002/04/10 16:59:54  warmerda
101     * added SHPRewindObject
102     *
103     * Revision 1.35  2001/12/07 15:10:44  warmerda
104     * fix if .shx fails to open
105     *
106     * Revision 1.34  2001/11/01 16:29:55  warmerda
107     * move pabyRec into SHPInfo for thread safety
108   *   *
109   * Revision 1.33  2001/07/03 12:18:15  warmerda   * Revision 1.33  2001/07/03 12:18:15  warmerda
110   * Improved cleanup if SHX not found, provied by Riccardo Cohen.   * Improved cleanup if SHX not found, provied by Riccardo Cohen.
# Line 181  typedef int          int32; Line 243  typedef int          int32;
243  #endif  #endif
244    
245  static int      bBigEndian;  static int      bBigEndian;
 static uchar    *pabyRec = NULL;  
 static int      nBufSize = 0;  
246    
247    
248  /************************************************************************/  /************************************************************************/
# Line 228  static void * SfRealloc( void * pMem, in Line 288  static void * SfRealloc( void * pMem, in
288  /*      contents of the index (.shx) file.                              */  /*      contents of the index (.shx) file.                              */
289  /************************************************************************/  /************************************************************************/
290    
291  static void SHPWriteHeader( SHPHandle psSHP )  void SHPWriteHeader( SHPHandle psSHP )
292    
293  {  {
294      uchar       abyHeader[100];      uchar       abyHeader[100];
# Line 293  static void SHPWriteHeader( SHPHandle ps Line 353  static void SHPWriteHeader( SHPHandle ps
353  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
354  /*      Write .shp file header.                                         */  /*      Write .shp file header.                                         */
355  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
356      fseek( psSHP->fpSHP, 0, 0 );      if( fseek( psSHP->fpSHP, 0, 0 ) != 0
357      fwrite( abyHeader, 100, 1, psSHP->fpSHP );          || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
358        {
359    #ifdef USE_CPL
360            CPLError( CE_Failure, CPLE_OpenFailed,
361                      "Failure writing .shp header." );
362    #endif
363            return;
364        }
365    
366  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
367  /*      Prepare, and write .shx file header.                            */  /*      Prepare, and write .shx file header.                            */
# Line 303  static void SHPWriteHeader( SHPHandle ps Line 370  static void SHPWriteHeader( SHPHandle ps
370      ByteCopy( &i32, abyHeader+24, 4 );      ByteCopy( &i32, abyHeader+24, 4 );
371      if( !bBigEndian ) SwapWord( 4, abyHeader+24 );      if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
372            
373      fseek( psSHP->fpSHX, 0, 0 );      if( fseek( psSHP->fpSHX, 0, 0 ) != 0
374      fwrite( abyHeader, 100, 1, psSHP->fpSHX );          || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
375        {
376    #ifdef USE_CPL
377            CPLError( CE_Failure, CPLE_OpenFailed,
378                      "Failure writing .shx header." );
379    #endif
380            return;
381        }
382    
383  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
384  /*      Write out the .shx contents.                                    */  /*      Write out the .shx contents.                                    */
# Line 319  static void SHPWriteHeader( SHPHandle ps Line 393  static void SHPWriteHeader( SHPHandle ps
393          if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );          if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
394      }      }
395    
396      fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX );      if( fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX )
397            != psSHP->nRecords )
398        {
399    #ifdef USE_CPL
400            CPLError( CE_Failure, CPLE_OpenFailed,
401                      "Failure writing .shx contents." );
402    #endif
403        }
404    
405      free( panSHX );      free( panSHX );
406    
407    /* -------------------------------------------------------------------- */
408    /*      Flush to disk.                                                  */
409    /* -------------------------------------------------------------------- */
410        fflush( psSHP->fpSHP );
411        fflush( psSHP->fpSHX );
412  }  }
413    
414  /************************************************************************/  /************************************************************************/
415  /*                              SHPOpen()                               */  /*                              shpopen()                               */
416  /*                                                                      */  /*                                                                      */
417  /*      Open the .shp and .shx files based on the basename of the       */  /*      Open the .shp and .shx files based on the basename of the       */
418  /*      files or either file name.                                      */  /*      files or either file name.                                      */
# Line 365  SHPOpen( const char * pszLayer, const ch Line 452  SHPOpen( const char * pszLayer, const ch
452  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
453  /*      Initialize the info structure.                                  */  /*      Initialize the info structure.                                  */
454  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
455      psSHP = (SHPHandle) malloc(sizeof(SHPInfo));      psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
456    
457      psSHP->bUpdated = FALSE;      psSHP->bUpdated = FALSE;
458    
# Line 398  SHPOpen( const char * pszLayer, const ch Line 485  SHPOpen( const char * pszLayer, const ch
485            
486      if( psSHP->fpSHP == NULL )      if( psSHP->fpSHP == NULL )
487      {      {
488    #ifdef USE_CPL
489            CPLError( CE_Failure, CPLE_OpenFailed,
490                      "Unable to open %s.shp or %s.SHP.",
491                      pszBasename, pszBasename );
492    #endif
493          free( psSHP );          free( psSHP );
494          free( pszBasename );          free( pszBasename );
495          free( pszFullname );          free( pszFullname );
# Line 414  SHPOpen( const char * pszLayer, const ch Line 506  SHPOpen( const char * pszLayer, const ch
506            
507      if( psSHP->fpSHX == NULL )      if( psSHP->fpSHX == NULL )
508      {      {
509          fclose( psSHP->fpSHX );  #ifdef USE_CPL
510            CPLError( CE_Failure, CPLE_OpenFailed,
511                      "Unable to open %s.shx or %s.SHX.",
512                      pszBasename, pszBasename );
513    #endif
514            fclose( psSHP->fpSHP );
515          free( psSHP );          free( psSHP );
516          free( pszBasename );          free( pszBasename );
517          free( pszFullname );          free( pszFullname );
# Line 438  SHPOpen( const char * pszLayer, const ch Line 535  SHPOpen( const char * pszLayer, const ch
535  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
536  /*  Read SHX file Header info                                           */  /*  Read SHX file Header info                                           */
537  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
538      fread( pabyBuf, 100, 1, psSHP->fpSHX );      if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1
539            || pabyBuf[0] != 0
     if( pabyBuf[0] != 0  
540          || pabyBuf[1] != 0          || pabyBuf[1] != 0
541          || pabyBuf[2] != 0x27          || pabyBuf[2] != 0x27
542          || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )          || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
543      {      {
544    #ifdef USE_CPL
545            CPLError( CE_Failure, CPLE_AppDefined,
546                      ".shx file is unreadable, or corrupt." );
547    #endif
548          fclose( psSHP->fpSHP );          fclose( psSHP->fpSHP );
549          fclose( psSHP->fpSHX );          fclose( psSHP->fpSHX );
550          free( psSHP );          free( psSHP );
# Line 460  SHPOpen( const char * pszLayer, const ch Line 560  SHPOpen( const char * pszLayer, const ch
560    
561      if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )      if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
562      {      {
563          /* this header appears to be corrupt.  Give up. */  #ifdef USE_CPL
564            CPLError( CE_Failure, CPLE_AppDefined,
565                      "Record count in .shp header is %d, which seems\n"
566                      "unreasonable.  Assuming header is corrupt.",
567                      psSHP->nRecords );
568    #endif
569          fclose( psSHP->fpSHP );          fclose( psSHP->fpSHP );
570          fclose( psSHP->fpSHX );          fclose( psSHP->fpSHX );
571          free( psSHP );          free( psSHP );
# Line 517  SHPOpen( const char * pszLayer, const ch Line 622  SHPOpen( const char * pszLayer, const ch
622          (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );          (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
623    
624      pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );      pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
625      fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );      if( fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) != psSHP->nRecords )
626        {
627    #ifdef USE_CPL
628            CPLError( CE_Failure, CPLE_AppDefined,
629                      "Failed to read all values for %d records in .shx file.",
630                      psSHP->nRecords );
631    #endif
632            /* SHX is short or unreadable for some reason. */
633            fclose( psSHP->fpSHP );
634            fclose( psSHP->fpSHX );
635            free( psSHP->panRecOffset );
636            free( psSHP->panRecSize );
637            free( psSHP );
638    
639            return( NULL );
640        }
641    
642      for( i = 0; i < psSHP->nRecords; i++ )      for( i = 0; i < psSHP->nRecords; i++ )
643      {      {
# Line 547  void SHPAPI_CALL Line 667  void SHPAPI_CALL
667  SHPClose(SHPHandle psSHP )  SHPClose(SHPHandle psSHP )
668    
669  {  {
670        if( psSHP == NULL )
671            return;
672    
673  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
674  /*      Update the header if we have modified anything.                 */  /*      Update the header if we have modified anything.                 */
675  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
676      if( psSHP->bUpdated )      if( psSHP->bUpdated )
     {  
677          SHPWriteHeader( psSHP );          SHPWriteHeader( psSHP );
     }  
678    
679  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
680  /*      Free all resources, and close files.                            */  /*      Free all resources, and close files.                            */
# Line 564  SHPClose(SHPHandle psSHP ) Line 685  SHPClose(SHPHandle psSHP )
685      fclose( psSHP->fpSHX );      fclose( psSHP->fpSHX );
686      fclose( psSHP->fpSHP );      fclose( psSHP->fpSHP );
687    
688      free( psSHP );      if( psSHP->pabyRec != NULL )
   
     if( pabyRec != NULL )  
689      {      {
690          free( pabyRec );          free( psSHP->pabyRec );
         pabyRec = NULL;  
         nBufSize = 0;  
691      }      }
692        
693        free( psSHP );
694  }  }
695    
696  /************************************************************************/  /************************************************************************/
# Line 586  SHPGetInfo(SHPHandle psSHP, int * pnEnti Line 705  SHPGetInfo(SHPHandle psSHP, int * pnEnti
705    
706  {  {
707      int         i;      int         i;
708    
709        if( psSHP == NULL )
710            return;
711            
712      if( pnEntities != NULL )      if( pnEntities != NULL )
713          *pnEntities = psSHP->nRecords;          *pnEntities = psSHP->nRecords;
# Line 650  SHPCreate( const char * pszLayer, int nS Line 772  SHPCreate( const char * pszLayer, int nS
772      sprintf( pszFullname, "%s.shp", pszBasename );      sprintf( pszFullname, "%s.shp", pszBasename );
773      fpSHP = fopen(pszFullname, "wb" );      fpSHP = fopen(pszFullname, "wb" );
774      if( fpSHP == NULL )      if( fpSHP == NULL )
775        {
776    #ifdef USE_CPL
777            CPLError( CE_Failure, CPLE_AppDefined,
778                      "Failed to create file %s.",
779                      pszFullname );
780    #endif
781          return( NULL );          return( NULL );
782        }
783    
784      sprintf( pszFullname, "%s.shx", pszBasename );      sprintf( pszFullname, "%s.shx", pszBasename );
785      fpSHX = fopen(pszFullname, "wb" );      fpSHX = fopen(pszFullname, "wb" );
786      if( fpSHX == NULL )      if( fpSHX == NULL )
787        {
788    #ifdef USE_CPL
789            CPLError( CE_Failure, CPLE_AppDefined,
790                      "Failed to create file %s.",
791                      pszFullname );
792    #endif
793          return( NULL );          return( NULL );
794        }
795    
796      free( pszFullname );      free( pszFullname );
797      free( pszBasename );      free( pszBasename );
# Line 690  SHPCreate( const char * pszLayer, int nS Line 826  SHPCreate( const char * pszLayer, int nS
826  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
827  /*      Write .shp file header.                                         */  /*      Write .shp file header.                                         */
828  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
829      fwrite( abyHeader, 100, 1, fpSHP );      if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 )
830        {
831    #ifdef USE_CPL
832            CPLError( CE_Failure, CPLE_AppDefined,
833                      "Failed to write .shp header." );
834    #endif
835            return NULL;
836        }
837    
838  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
839  /*      Prepare, and write .shx file header.                            */  /*      Prepare, and write .shx file header.                            */
# Line 699  SHPCreate( const char * pszLayer, int nS Line 842  SHPCreate( const char * pszLayer, int nS
842      ByteCopy( &i32, abyHeader+24, 4 );      ByteCopy( &i32, abyHeader+24, 4 );
843      if( !bBigEndian ) SwapWord( 4, abyHeader+24 );      if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
844            
845      fwrite( abyHeader, 100, 1, fpSHX );      if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 )
846        {
847    #ifdef USE_CPL
848            CPLError( CE_Failure, CPLE_AppDefined,
849                      "Failed to write .shx header." );
850    #endif
851            return NULL;
852        }
853    
854  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
855  /*      Close the files, and then open them as regular existing files.  */  /*      Close the files, and then open them as regular existing files.  */
# Line 910  int SHPAPI_CALL Line 1060  int SHPAPI_CALL
1060  SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )  SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
1061                                                
1062  {  {
1063      int         nRecordOffset, i, nRecordSize;      int         nRecordOffset, i, nRecordSize=0;
1064      uchar       *pabyRec;      uchar       *pabyRec;
1065      int32       i32;      int32       i32;
1066    
# Line 1224  SHPWriteObject(SHPHandle psSHP, int nSha Line 1374  SHPWriteObject(SHPHandle psSHP, int nSha
1374      if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0      if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
1375          || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )          || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
1376      {      {
1377          printf( "Error in fseek() or fwrite().\n" );  #ifdef USE_CPL
1378            CPLError( CE_Failure, CPLE_FileIO,
1379                    "Error in fseek() or fwrite() writing object to .shp file." );
1380    #endif
1381          free( pabyRec );          free( pabyRec );
1382          return -1;          return -1;
1383      }      }
# Line 1237  SHPWriteObject(SHPHandle psSHP, int nSha Line 1390  SHPWriteObject(SHPHandle psSHP, int nSha
1390      if( psSHP->adBoundsMin[0] == 0.0      if( psSHP->adBoundsMin[0] == 0.0
1391          && psSHP->adBoundsMax[0] == 0.0          && psSHP->adBoundsMax[0] == 0.0
1392          && psSHP->adBoundsMin[1] == 0.0          && psSHP->adBoundsMin[1] == 0.0
1393          && psSHP->adBoundsMax[1] == 0.0          && psSHP->adBoundsMax[1] == 0.0 )
         && psObject->nSHPType != SHPT_NULL )  
1394      {      {
1395          psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];          if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
1396          psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];          {
1397          psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];              psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
1398          psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];              psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
1399                psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
1400                psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
1401            }
1402            else
1403            {
1404                psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
1405                psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
1406                psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
1407                psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
1408            }
1409      }      }
1410    
1411      for( i = 0; i < psObject->nVertices; i++ )      for( i = 0; i < psObject->nVertices; i++ )
# Line 1283  SHPReadObject( SHPHandle psSHP, int hEnt Line 1445  SHPReadObject( SHPHandle psSHP, int hEnt
1445  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1446  /*      Ensure our record buffer is large enough.                       */  /*      Ensure our record buffer is large enough.                       */
1447  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1448      if( psSHP->panRecSize[hEntity]+8 > nBufSize )      if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
1449      {      {
1450          nBufSize = psSHP->panRecSize[hEntity]+8;          psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
1451          pabyRec = (uchar *) SfRealloc(pabyRec,nBufSize);          psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
1452      }      }
1453    
1454  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1455  /*      Read the record.                                                */  /*      Read the record.                                                */
1456  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1457      fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 );      if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
1458      fread( pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );          || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,
1459                      psSHP->fpSHP ) != 1 )
1460        {
1461    #ifdef USE_CPL
1462            CPLError( CE_Failure, CPLE_FileIO,
1463                    "Error in fseek() or fread() reading object from .shp file." );
1464    #endif
1465            return NULL;
1466        }
1467    
1468  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1469  /*      Allocate and minimally initialize the object.                   */  /*      Allocate and minimally initialize the object.                   */
# Line 1301  SHPReadObject( SHPHandle psSHP, int hEnt Line 1471  SHPReadObject( SHPHandle psSHP, int hEnt
1471      psShape = (SHPObject *) calloc(1,sizeof(SHPObject));      psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
1472      psShape->nShapeId = hEntity;      psShape->nShapeId = hEntity;
1473    
1474      memcpy( &psShape->nSHPType, pabyRec + 8, 4 );      memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
1475      if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );      if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
1476    
1477  /* ==================================================================== */  /* ==================================================================== */
# Line 1320  SHPReadObject( SHPHandle psSHP, int hEnt Line 1490  SHPReadObject( SHPHandle psSHP, int hEnt
1490  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1491  /*      Get the X/Y bounds.                                             */  /*      Get the X/Y bounds.                                             */
1492  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1493          memcpy( &(psShape->dfXMin), pabyRec + 8 +  4, 8 );          memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
1494          memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 );          memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1495          memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 );          memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1496          memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 );          memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1497    
1498          if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );          if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1499          if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );          if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
# Line 1334  SHPReadObject( SHPHandle psSHP, int hEnt Line 1504  SHPReadObject( SHPHandle psSHP, int hEnt
1504  /*      Extract part/point count, and build vertex and part arrays      */  /*      Extract part/point count, and build vertex and part arrays      */
1505  /*      to proper size.                                                 */  /*      to proper size.                                                 */
1506  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1507          memcpy( &nPoints, pabyRec + 40 + 8, 4 );          memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1508          memcpy( &nParts, pabyRec + 36 + 8, 4 );          memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1509    
1510          if( bBigEndian ) SwapWord( 4, &nPoints );          if( bBigEndian ) SwapWord( 4, &nPoints );
1511          if( bBigEndian ) SwapWord( 4, &nParts );          if( bBigEndian ) SwapWord( 4, &nParts );
# Line 1356  SHPReadObject( SHPHandle psSHP, int hEnt Line 1526  SHPReadObject( SHPHandle psSHP, int hEnt
1526  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1527  /*      Copy out the part array from the record.                        */  /*      Copy out the part array from the record.                        */
1528  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1529          memcpy( psShape->panPartStart, pabyRec + 44 + 8, 4 * nParts );          memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1530          for( i = 0; i < nParts; i++ )          for( i = 0; i < nParts; i++ )
1531          {          {
1532              if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );              if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
# Line 1369  SHPReadObject( SHPHandle psSHP, int hEnt Line 1539  SHPReadObject( SHPHandle psSHP, int hEnt
1539  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1540          if( psShape->nSHPType == SHPT_MULTIPATCH )          if( psShape->nSHPType == SHPT_MULTIPATCH )
1541          {          {
1542              memcpy( psShape->panPartType, pabyRec + nOffset, 4*nParts );              memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
1543              for( i = 0; i < nParts; i++ )              for( i = 0; i < nParts; i++ )
1544              {              {
1545                  if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );                  if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
# Line 1384  SHPReadObject( SHPHandle psSHP, int hEnt Line 1554  SHPReadObject( SHPHandle psSHP, int hEnt
1554          for( i = 0; i < nPoints; i++ )          for( i = 0; i < nPoints; i++ )
1555          {          {
1556              memcpy(psShape->padfX + i,              memcpy(psShape->padfX + i,
1557                     pabyRec + nOffset + i * 16,                     psSHP->pabyRec + nOffset + i * 16,
1558                     8 );                     8 );
1559    
1560              memcpy(psShape->padfY + i,              memcpy(psShape->padfY + i,
1561                     pabyRec + nOffset + i * 16 + 8,                     psSHP->pabyRec + nOffset + i * 16 + 8,
1562                     8 );                     8 );
1563    
1564              if( bBigEndian ) SwapWord( 8, psShape->padfX + i );              if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
# Line 1404  SHPReadObject( SHPHandle psSHP, int hEnt Line 1574  SHPReadObject( SHPHandle psSHP, int hEnt
1574              || psShape->nSHPType == SHPT_ARCZ              || psShape->nSHPType == SHPT_ARCZ
1575              || psShape->nSHPType == SHPT_MULTIPATCH )              || psShape->nSHPType == SHPT_MULTIPATCH )
1576          {          {
1577              memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 );              memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
1578              memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 );              memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1579                            
1580              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
1581              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
# Line 1413  SHPReadObject( SHPHandle psSHP, int hEnt Line 1583  SHPReadObject( SHPHandle psSHP, int hEnt
1583              for( i = 0; i < nPoints; i++ )              for( i = 0; i < nPoints; i++ )
1584              {              {
1585                  memcpy( psShape->padfZ + i,                  memcpy( psShape->padfZ + i,
1586                          pabyRec + nOffset + 16 + i*8, 8 );                          psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1587                  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );                  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
1588              }              }
1589    
# Line 1428  SHPReadObject( SHPHandle psSHP, int hEnt Line 1598  SHPReadObject( SHPHandle psSHP, int hEnt
1598  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1599          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
1600          {          {
1601              memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 );              memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
1602              memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 );              memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1603                            
1604              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
1605              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
# Line 1437  SHPReadObject( SHPHandle psSHP, int hEnt Line 1607  SHPReadObject( SHPHandle psSHP, int hEnt
1607              for( i = 0; i < nPoints; i++ )              for( i = 0; i < nPoints; i++ )
1608              {              {
1609                  memcpy( psShape->padfM + i,                  memcpy( psShape->padfM + i,
1610                          pabyRec + nOffset + 16 + i*8, 8 );                          psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1611                  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );                  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
1612              }              }
1613          }          }
# Line 1454  SHPReadObject( SHPHandle psSHP, int hEnt Line 1624  SHPReadObject( SHPHandle psSHP, int hEnt
1624          int32           nPoints;          int32           nPoints;
1625          int             i, nOffset;          int             i, nOffset;
1626    
1627          memcpy( &nPoints, pabyRec + 44, 4 );          memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
1628          if( bBigEndian ) SwapWord( 4, &nPoints );          if( bBigEndian ) SwapWord( 4, &nPoints );
1629    
1630          psShape->nVertices = nPoints;          psShape->nVertices = nPoints;
# Line 1465  SHPReadObject( SHPHandle psSHP, int hEnt Line 1635  SHPReadObject( SHPHandle psSHP, int hEnt
1635    
1636          for( i = 0; i < nPoints; i++ )          for( i = 0; i < nPoints; i++ )
1637          {          {
1638              memcpy(psShape->padfX+i, pabyRec + 48 + 16 * i, 8 );              memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
1639              memcpy(psShape->padfY+i, pabyRec + 48 + 16 * i + 8, 8 );              memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
1640    
1641              if( bBigEndian ) SwapWord( 8, psShape->padfX + i );              if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1642              if( bBigEndian ) SwapWord( 8, psShape->padfY + i );              if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
# Line 1477  SHPReadObject( SHPHandle psSHP, int hEnt Line 1647  SHPReadObject( SHPHandle psSHP, int hEnt
1647  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1648  /*      Get the X/Y bounds.                                             */  /*      Get the X/Y bounds.                                             */
1649  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1650          memcpy( &(psShape->dfXMin), pabyRec + 8 +  4, 8 );          memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
1651          memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 );          memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1652          memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 );          memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1653          memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 );          memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1654    
1655          if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );          if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1656          if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );          if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
# Line 1492  SHPReadObject( SHPHandle psSHP, int hEnt Line 1662  SHPReadObject( SHPHandle psSHP, int hEnt
1662  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1663          if( psShape->nSHPType == SHPT_MULTIPOINTZ )          if( psShape->nSHPType == SHPT_MULTIPOINTZ )
1664          {          {
1665              memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 );              memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
1666              memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 );              memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1667                            
1668              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
1669              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
# Line 1501  SHPReadObject( SHPHandle psSHP, int hEnt Line 1671  SHPReadObject( SHPHandle psSHP, int hEnt
1671              for( i = 0; i < nPoints; i++ )              for( i = 0; i < nPoints; i++ )
1672              {              {
1673                  memcpy( psShape->padfZ + i,                  memcpy( psShape->padfZ + i,
1674                          pabyRec + nOffset + 16 + i*8, 8 );                          psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1675                  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );                  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
1676              }              }
1677    
# Line 1516  SHPReadObject( SHPHandle psSHP, int hEnt Line 1686  SHPReadObject( SHPHandle psSHP, int hEnt
1686  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1687          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
1688          {          {
1689              memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 );              memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
1690              memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 );              memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1691                            
1692              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
1693              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );              if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
# Line 1525  SHPReadObject( SHPHandle psSHP, int hEnt Line 1695  SHPReadObject( SHPHandle psSHP, int hEnt
1695              for( i = 0; i < nPoints; i++ )              for( i = 0; i < nPoints; i++ )
1696              {              {
1697                  memcpy( psShape->padfM + i,                  memcpy( psShape->padfM + i,
1698                          pabyRec + nOffset + 16 + i*8, 8 );                          psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1699                  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );                  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
1700              }              }
1701          }          }
# Line 1546  SHPReadObject( SHPHandle psSHP, int hEnt Line 1716  SHPReadObject( SHPHandle psSHP, int hEnt
1716          psShape->padfZ = (double *) calloc(1,sizeof(double));          psShape->padfZ = (double *) calloc(1,sizeof(double));
1717          psShape->padfM = (double *) calloc(1,sizeof(double));          psShape->padfM = (double *) calloc(1,sizeof(double));
1718    
1719          memcpy( psShape->padfX, pabyRec + 12, 8 );          memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
1720          memcpy( psShape->padfY, pabyRec + 20, 8 );          memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
1721    
1722          if( bBigEndian ) SwapWord( 8, psShape->padfX );          if( bBigEndian ) SwapWord( 8, psShape->padfX );
1723          if( bBigEndian ) SwapWord( 8, psShape->padfY );          if( bBigEndian ) SwapWord( 8, psShape->padfY );
# Line 1559  SHPReadObject( SHPHandle psSHP, int hEnt Line 1729  SHPReadObject( SHPHandle psSHP, int hEnt
1729  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1730          if( psShape->nSHPType == SHPT_POINTZ )          if( psShape->nSHPType == SHPT_POINTZ )
1731          {          {
1732              memcpy( psShape->padfZ, pabyRec + nOffset, 8 );              memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 );
1733                    
1734              if( bBigEndian ) SwapWord( 8, psShape->padfZ );              if( bBigEndian ) SwapWord( 8, psShape->padfZ );
1735                            
# Line 1574  SHPReadObject( SHPHandle psSHP, int hEnt Line 1744  SHPReadObject( SHPHandle psSHP, int hEnt
1744  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1745          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )          if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
1746          {          {
1747              memcpy( psShape->padfM, pabyRec + nOffset, 8 );              memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
1748                    
1749              if( bBigEndian ) SwapWord( 8, psShape->padfM );              if( bBigEndian ) SwapWord( 8, psShape->padfM );
1750          }          }
# Line 1709  SHPDestroyObject( SHPObject * psShape ) Line 1879  SHPDestroyObject( SHPObject * psShape )
1879    
1880      free( psShape );      free( psShape );
1881  }  }
1882    
1883    /************************************************************************/
1884    /*                          SHPRewindObject()                           */
1885    /*                                                                      */
1886    /*      Reset the winding of polygon objects to adhere to the           */
1887    /*      specification.                                                  */
1888    /************************************************************************/
1889    
1890    int SHPAPI_CALL
1891    SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
1892    
1893    {
1894        int  iOpRing, bAltered = 0;
1895    
1896    /* -------------------------------------------------------------------- */
1897    /*      Do nothing if this is not a polygon object.                     */
1898    /* -------------------------------------------------------------------- */
1899        if( psObject->nSHPType != SHPT_POLYGON
1900            && psObject->nSHPType != SHPT_POLYGONZ
1901            && psObject->nSHPType != SHPT_POLYGONM )
1902            return 0;
1903    
1904        if( psObject->nVertices == 0 || psObject->nParts == 0 )
1905            return 0;
1906    
1907    /* -------------------------------------------------------------------- */
1908    /*      Process each of the rings.                                      */
1909    /* -------------------------------------------------------------------- */
1910        for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ )
1911        {
1912            int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
1913            double   dfSum, dfTestX, dfTestY;
1914    
1915    /* -------------------------------------------------------------------- */
1916    /*      Determine if this ring is an inner ring or an outer ring        */
1917    /*      relative to all the other rings.  For now we assume the         */
1918    /*      first ring is outer and all others are inner, but eventually    */
1919    /*      we need to fix this to handle multiple island polygons and      */
1920    /*      unordered sets of rings.                                        */
1921    /* -------------------------------------------------------------------- */
1922            dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
1923            dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
1924    
1925            bInner = FALSE;
1926            for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
1927            {
1928                int iEdge;
1929    
1930                if( iCheckRing == iOpRing )
1931                    continue;
1932                
1933                nVertStart = psObject->panPartStart[iCheckRing];
1934    
1935                if( iCheckRing == psObject->nParts-1 )
1936                    nVertCount = psObject->nVertices
1937                        - psObject->panPartStart[iCheckRing];
1938                else
1939                    nVertCount = psObject->panPartStart[iCheckRing+1]
1940                        - psObject->panPartStart[iCheckRing];
1941    
1942                for( iEdge = 0; iEdge < nVertCount; iEdge++ )
1943                {
1944                    int iNext;
1945    
1946                    if( iEdge < nVertCount-1 )
1947                        iNext = iEdge+1;
1948                    else
1949                        iNext = 0;
1950    
1951                    if( (psObject->padfY[iEdge+nVertStart] < dfTestY
1952                         && psObject->padfY[iNext+nVertStart] >= dfTestY)
1953                        || (psObject->padfY[iNext+nVertStart] < dfTestY
1954                            && psObject->padfY[iEdge+nVertStart] >= dfTestY) )
1955                    {
1956                        if( psObject->padfX[iEdge+nVertStart]
1957                            + (dfTestY - psObject->padfY[iEdge+nVertStart])
1958                               / (psObject->padfY[iNext+nVertStart]
1959                                  - psObject->padfY[iEdge+nVertStart])
1960                               * (psObject->padfX[iNext+nVertStart]
1961                                  - psObject->padfX[iEdge+nVertStart]) < dfTestX )
1962                            bInner = !bInner;
1963                    }
1964                }
1965            }
1966    
1967    /* -------------------------------------------------------------------- */
1968    /*      Determine the current order of this ring so we will know if     */
1969    /*      it has to be reversed.                                          */
1970    /* -------------------------------------------------------------------- */
1971            nVertStart = psObject->panPartStart[iOpRing];
1972    
1973            if( iOpRing == psObject->nParts-1 )
1974                nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
1975            else
1976                nVertCount = psObject->panPartStart[iOpRing+1]
1977                    - psObject->panPartStart[iOpRing];
1978    
1979            dfSum = 0.0;
1980            for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
1981            {
1982                dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
1983                    - psObject->padfY[iVert] * psObject->padfX[iVert+1];
1984            }
1985    
1986            dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
1987                   - psObject->padfY[iVert] * psObject->padfX[nVertStart];
1988    
1989    /* -------------------------------------------------------------------- */
1990    /*      Reverse if necessary.                                           */
1991    /* -------------------------------------------------------------------- */
1992            if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
1993            {
1994                int   i;
1995    
1996                bAltered++;
1997                for( i = 0; i < nVertCount/2; i++ )
1998                {
1999                    double dfSaved;
2000    
2001                    /* Swap X */
2002                    dfSaved = psObject->padfX[nVertStart+i];
2003                    psObject->padfX[nVertStart+i] =
2004                        psObject->padfX[nVertStart+nVertCount-i-1];
2005                    psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved;
2006    
2007                    /* Swap Y */
2008                    dfSaved = psObject->padfY[nVertStart+i];
2009                    psObject->padfY[nVertStart+i] =
2010                        psObject->padfY[nVertStart+nVertCount-i-1];
2011                    psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved;
2012    
2013                    /* Swap Z */
2014                    if( psObject->padfZ )
2015                    {
2016                        dfSaved = psObject->padfZ[nVertStart+i];
2017                        psObject->padfZ[nVertStart+i] =
2018                            psObject->padfZ[nVertStart+nVertCount-i-1];
2019                        psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved;
2020                    }
2021    
2022                    /* Swap M */
2023                    if( psObject->padfM )
2024                    {
2025                        dfSaved = psObject->padfM[nVertStart+i];
2026                        psObject->padfM[nVertStart+i] =
2027                            psObject->padfM[nVertStart+nVertCount-i-1];
2028                        psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved;
2029                    }
2030                }
2031            }
2032        }
2033    
2034        return bAltered;
2035    }

Legend:
Removed from v.1612  
changed lines
  Added in v.2212

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26