225 #include <grass/shapefil.h>
234 SHP_CVSID(
"$Id: shpopen.c 32581 2008-08-06 19:30:45Z neteler $")
238 #if UINT_MAX == 65535
249 #define ByteCopy( a, b, c ) memcpy( b, a, c )
251 # define MIN(a,b) ((a<b) ? a : b)
252 # define MAX(a,b) ((a>b) ? a : b)
255 static int bBigEndian;
264 static void SwapWord(
int length,
void * wordP )
270 for( i=0; i < length/2; i++ )
272 temp = ((uchar *) wordP)[i];
273 ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1];
274 ((uchar *) wordP)[length-i-1] = temp;
285 static void * SfRealloc(
void * pMem,
int nNewSize )
289 return( (
void *) malloc(nNewSize) );
291 return( (
void *) realloc(pMem,nNewSize) );
304 uchar abyHeader[100];
312 psSHP->
sHooks.
Error(
"SHPWriteHeader failed : SHX file is closed");
319 for( i = 0; i < 100; i++ )
327 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
331 if( bBigEndian ) SwapWord( 4, abyHeader+28 );
335 if( bBigEndian ) SwapWord( 4, abyHeader+32 );
338 ByteCopy( &dValue, abyHeader+36, 8 );
339 if( bBigEndian ) SwapWord( 8, abyHeader+36 );
342 ByteCopy( &dValue, abyHeader+44, 8 );
343 if( bBigEndian ) SwapWord( 8, abyHeader+44 );
346 ByteCopy( &dValue, abyHeader+52, 8 );
347 if( bBigEndian ) SwapWord( 8, abyHeader+52 );
350 ByteCopy( &dValue, abyHeader+60, 8 );
351 if( bBigEndian ) SwapWord( 8, abyHeader+60 );
354 ByteCopy( &dValue, abyHeader+68, 8 );
355 if( bBigEndian ) SwapWord( 8, abyHeader+68 );
358 ByteCopy( &dValue, abyHeader+76, 8 );
359 if( bBigEndian ) SwapWord( 8, abyHeader+76 );
362 ByteCopy( &dValue, abyHeader+84, 8 );
363 if( bBigEndian ) SwapWord( 8, abyHeader+84 );
366 ByteCopy( &dValue, abyHeader+92, 8 );
367 if( bBigEndian ) SwapWord( 8, abyHeader+92 );
375 psSHP->
sHooks.
Error(
"Failure writing .shp header" );
384 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
389 psSHP->
sHooks.
Error(
"Failure writing .shx header" );
396 panSHX = (int32 *) malloc(
sizeof(int32) * 2 * psSHP->
nRecords);
398 for( i = 0; i < psSHP->
nRecords; i++ )
402 if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
403 if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
409 psSHP->
sHooks.
Error(
"Failure writing .shx contents" );
426 SHPOpen(
const char * pszLayer,
const char * pszAccess )
433 return SHPOpenLL( pszLayer, pszAccess, &sHooks );
447 char *pszFullname, *pszBasename;
459 if( strcmp(pszAccess,
"rb+") == 0 || strcmp(pszAccess,
"r+b") == 0
460 || strcmp(pszAccess,
"r+") == 0 )
469 if( *((uchar *) &i) == 1 )
486 pszBasename = (
char *) malloc(strlen(pszLayer)+5);
487 strcpy( pszBasename, pszLayer );
488 for( i = strlen(pszBasename)-1;
489 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/'
490 && pszBasename[i] !=
'\\';
493 if( pszBasename[i] ==
'.' )
494 pszBasename[i] =
'\0';
500 pszFullname = (
char *) malloc(strlen(pszBasename) + 5);
501 sprintf( pszFullname,
"%s.shp", pszBasename ) ;
505 sprintf( pszFullname,
"%s.SHP", pszBasename );
512 CPLError( CE_Failure, CPLE_OpenFailed,
513 "Unable to open %s.shp or %s.SHP.",
514 pszBasename, pszBasename );
522 sprintf( pszFullname,
"%s.shx", pszBasename );
526 sprintf( pszFullname,
"%s.SHX", pszBasename );
533 CPLError( CE_Failure, CPLE_OpenFailed,
534 "Unable to open %s.shx or %s.SHX.",
535 pszBasename, pszBasename );
550 pabyBuf = (uchar *) malloc(100);
553 psSHP->
nFileSize = (pabyBuf[24] * 256 * 256 * 256
554 + pabyBuf[25] * 256 * 256
564 || pabyBuf[2] != 0x27
565 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
567 psSHP->
sHooks.
Error(
".shx file is unreadable, or corrupt." );
575 psSHP->
nRecords = pabyBuf[27] + pabyBuf[26] * 256
576 + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
586 "Record count in .shp header is %d, which seems\n"
587 "unreasonable. Assuming header is corrupt.",
601 if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
602 memcpy( &dValue, pabyBuf+36, 8 );
605 if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
606 memcpy( &dValue, pabyBuf+44, 8 );
609 if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
610 memcpy( &dValue, pabyBuf+52, 8 );
613 if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
614 memcpy( &dValue, pabyBuf+60, 8 );
617 if( bBigEndian ) SwapWord( 8, pabyBuf+68 );
618 memcpy( &dValue, pabyBuf+68, 8 );
621 if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
622 memcpy( &dValue, pabyBuf+76, 8 );
625 if( bBigEndian ) SwapWord( 8, pabyBuf+84 );
626 memcpy( &dValue, pabyBuf+84, 8 );
629 if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
630 memcpy( &dValue, pabyBuf+92, 8 );
645 pabyBuf = (uchar *) malloc(8 *
MAX(1,psSHP->
nRecords) );
654 "Not enough memory to allocate requested memory (nRecords=%d).\n"
655 "Probably broken SHP file",
662 if (pabyBuf) free( pabyBuf );
673 "Failed to read all values for %d records in .shx file.",
689 if (strcmp(pszAccess,
"rb") == 0)
695 for( i = 0; i < psSHP->
nRecords; i++ )
697 int32 nOffset, nLength;
699 memcpy( &nOffset, pabyBuf + i * 8, 4 );
700 if( !bBigEndian ) SwapWord( 4, &nOffset );
702 memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
703 if( !bBigEndian ) SwapWord( 4, &nLength );
758 double * padfMinBound,
double * padfMaxBound )
766 if( pnEntities !=
NULL )
769 if( pnShapeType !=
NULL )
772 for( i = 0; i < 4; i++ )
774 if( padfMinBound !=
NULL )
776 if( padfMaxBound !=
NULL )
796 return SHPCreateLL( pszLayer, nShapeType, &sHooks );
810 char *pszBasename, *pszFullname;
813 uchar abyHeader[100];
821 if( *((uchar *) &i) == 1 )
830 pszBasename = (
char *) malloc(strlen(pszLayer)+5);
831 strcpy( pszBasename, pszLayer );
832 for( i = strlen(pszBasename)-1;
833 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/'
834 && pszBasename[i] !=
'\\';
837 if( pszBasename[i] ==
'.' )
838 pszBasename[i] =
'\0';
843 pszFullname = (
char *) malloc(strlen(pszBasename) + 5);
844 sprintf( pszFullname,
"%s.shp", pszBasename );
845 fpSHP = psHooks->
FOpen(pszFullname,
"wb" );
848 psHooks->
Error(
"Failed to create file .shp file." );
852 sprintf( pszFullname,
"%s.shx", pszBasename );
853 fpSHX = psHooks->
FOpen(pszFullname,
"wb" );
856 psHooks->
Error(
"Failed to create file .shx file." );
866 for( i = 0; i < 100; i++ )
874 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
878 if( bBigEndian ) SwapWord( 4, abyHeader+28 );
882 if( bBigEndian ) SwapWord( 4, abyHeader+32 );
885 ByteCopy( &dValue, abyHeader+36, 8 );
886 ByteCopy( &dValue, abyHeader+44, 8 );
887 ByteCopy( &dValue, abyHeader+52, 8 );
888 ByteCopy( &dValue, abyHeader+60, 8 );
893 if( psHooks->
FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
895 psHooks->
Error(
"Failed to write .shp header." );
904 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
906 if( psHooks->
FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
908 psHooks->
Error(
"Failed to write .shx header." );
918 return(
SHPOpenLL( pszLayer,
"r+b", psHooks ) );
938 SwapWord( 8, pabyRec + 0 );
939 SwapWord( 8, pabyRec + 8 );
940 SwapWord( 8, pabyRec + 16 );
941 SwapWord( 8, pabyRec + 24 );
969 for( i = 0; i < psObject->
nVertices; i++ )
992 const
int * panPartStart, const
int * panPartType,
993 int nVertices, const
double *padfX, const
double *padfY,
994 const
double * padfZ, const
double * padfM )
1043 malloc(
sizeof(
int) * psObject->
nParts);
1045 malloc(
sizeof(
int) * psObject->
nParts);
1050 for( i = 0; i < nParts; i++ )
1054 if( panPartType !=
NULL )
1075 assert( padfX !=
NULL );
1076 assert( padfY !=
NULL );
1080 psObject->
padfX[i] = padfX[i];
1081 psObject->
padfY[i] = padfY[i];
1082 if( padfZ !=
NULL && bHasZ )
1083 psObject->
padfZ[i] = padfZ[i];
1084 if( padfM !=
NULL && bHasM )
1085 psObject->
padfM[i] = padfM[i];
1087 if( padfM !=
NULL && bHasM )
1109 const
double * padfX, const
double * padfY,
1110 const
double * padfZ )
1114 nVertices, padfX, padfY, padfZ,
NULL ) );
1128 int nRecordOffset, i, nRecordSize=0;
1146 assert( nShapeId == -1
1147 || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
1149 if( nShapeId != -1 && nShapeId >= psSHP->
nRecords )
1168 pabyRec = (uchar *) malloc(psObject->
nVertices * 4 *
sizeof(
double)
1169 + psObject->
nParts * 8 + 128);
1182 int32 nPoints, nParts;
1186 nParts = psObject->
nParts;
1188 _SHPSetBounds( pabyRec + 12, psObject );
1190 if( bBigEndian ) SwapWord( 4, &nPoints );
1191 if( bBigEndian ) SwapWord( 4, &nParts );
1193 ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
1194 ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
1203 for( i = 0; i < psObject->
nParts; i++ )
1205 if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
1214 memcpy( pabyRec + nRecordSize, psObject->
panPartType,
1216 for( i = 0; i < psObject->
nParts; i++ )
1218 if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
1226 for( i = 0; i < psObject->
nVertices; i++ )
1229 ByteCopy( psObject->
padfY + i, pabyRec + nRecordSize + 8, 8 );
1232 SwapWord( 8, pabyRec + nRecordSize );
1235 SwapWord( 8, pabyRec + nRecordSize + 8 );
1237 nRecordSize += 2 * 8;
1248 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1252 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1255 for( i = 0; i < psObject->
nVertices; i++ )
1258 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1276 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1280 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1283 for( i = 0; i < psObject->
nVertices; i++ )
1286 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1304 _SHPSetBounds( pabyRec + 12, psObject );
1306 if( bBigEndian ) SwapWord( 4, &nPoints );
1307 ByteCopy( &nPoints, pabyRec + 44, 4 );
1309 for( i = 0; i < psObject->
nVertices; i++ )
1312 ByteCopy( psObject->
padfY + i, pabyRec + 48 + i*16 + 8, 8 );
1314 if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
1315 if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
1318 nRecordSize = 48 + 16 * psObject->
nVertices;
1323 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1327 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1330 for( i = 0; i < psObject->
nVertices; i++ )
1333 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1343 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1347 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1350 for( i = 0; i < psObject->
nVertices; i++ )
1353 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1369 if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
1370 if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
1377 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1386 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1410 if( nShapeId == -1 || psSHP->
panRecSize[nShapeId] < nRecordSize-8 )
1412 if( nShapeId == -1 )
1429 if( !bBigEndian ) SwapWord( 4, &i32 );
1432 i32 = (nRecordSize-8)/2;
1433 if( !bBigEndian ) SwapWord( 4, &i32 );
1437 if( bBigEndian ) SwapWord( 4, &i32 );
1446 psSHP->
sHooks.
Error(
"Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." );
1477 for( i = 0; i < psObject->
nVertices; i++ )
1505 char pszErrorMsg[128];
1510 if( hEntity < 0 || hEntity >= psSHP->nRecords )
1516 nEntitySize = psSHP->panRecSize[hEntity]+8;
1517 if( nEntitySize > psSHP->nBufSize )
1519 psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
1520 if (psSHP->pabyRec ==
NULL)
1525 psSHP->pabyRec = malloc(psSHP->nBufSize);
1528 "Not enough memory to allocate requested memory (nBufSize=%d). "
1529 "Probably broken SHP file", psSHP->nBufSize );
1530 psSHP->sHooks.Error( szError );
1547 if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
1548 || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1,
1549 psSHP->fpSHP ) != 1 )
1556 psSHP->sHooks.Error(
"Error in fseek() or fread() reading object from .shp file." );
1567 if ( 8 + 4 > nEntitySize )
1569 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1570 hEntity, nEntitySize);
1571 psSHP->sHooks.Error( pszErrorMsg );
1575 memcpy( &psShape->
nSHPType, psSHP->pabyRec + 8, 4 );
1589 int32 nPoints, nParts;
1592 if ( 40 + 8 + 4 > nEntitySize )
1594 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1595 hEntity, nEntitySize);
1596 psSHP->sHooks.Error( pszErrorMsg );
1603 memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 + 4, 8 );
1604 memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1605 memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1606 memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1608 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
1609 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
1610 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
1611 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
1617 memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1618 memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1620 if( bBigEndian ) SwapWord( 4, &nPoints );
1621 if( bBigEndian ) SwapWord( 4, &nParts );
1623 if (nPoints < 0 || nParts < 0 ||
1624 nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
1626 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
1627 hEntity, nPoints, nParts);
1628 psSHP->sHooks.Error( pszErrorMsg );
1636 nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
1641 nRequiredSize += 16 + 8 * nPoints;
1645 nRequiredSize += 4 * nParts;
1647 if (nRequiredSize > nEntitySize)
1649 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
1650 hEntity, nPoints, nParts, nEntitySize);
1651 psSHP->sHooks.Error( pszErrorMsg );
1657 psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
1658 psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
1659 psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
1660 psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
1662 psShape->
nParts = nParts;
1663 psShape->
panPartStart = (
int *) calloc(nParts,
sizeof(
int));
1664 psShape->
panPartType = (
int *) calloc(nParts,
sizeof(
int));
1673 snprintf(pszErrorMsg, 128,
1674 "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
1675 "Probably broken SHP file", hEntity, nPoints, nParts );
1676 psSHP->sHooks.Error( pszErrorMsg );
1681 for( i = 0; i < nParts; i++ )
1687 memcpy( psShape->
panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1688 for( i = 0; i < nParts; i++ )
1690 if( bBigEndian ) SwapWord( 4, psShape->
panPartStart+i );
1696 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
1698 psSHP->sHooks.Error( pszErrorMsg );
1704 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
1706 psSHP->sHooks.Error( pszErrorMsg );
1712 nOffset = 44 + 8 + 4*nParts;
1719 memcpy( psShape->
panPartType, psSHP->pabyRec + nOffset, 4*nParts );
1720 for( i = 0; i < nParts; i++ )
1722 if( bBigEndian ) SwapWord( 4, psShape->
panPartType+i );
1725 nOffset += 4*nParts;
1731 for( i = 0; i < nPoints; i++ )
1733 memcpy(psShape->
padfX + i,
1734 psSHP->pabyRec + nOffset + i * 16,
1737 memcpy(psShape->
padfY + i,
1738 psSHP->pabyRec + nOffset + i * 16 + 8,
1741 if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
1742 if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
1745 nOffset += 16*nPoints;
1754 memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
1755 memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1757 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
1758 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
1760 for( i = 0; i < nPoints; i++ )
1762 memcpy( psShape->
padfZ + i,
1763 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1764 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
1767 nOffset += 16 + 8*nPoints;
1776 if( nEntitySize >= nOffset + 16 + 8*nPoints )
1778 memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
1779 memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1781 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
1782 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
1784 for( i = 0; i < nPoints; i++ )
1786 memcpy( psShape->
padfM + i,
1787 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1788 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
1804 if ( 44 + 4 > nEntitySize )
1806 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1807 hEntity, nEntitySize);
1808 psSHP->sHooks.Error( pszErrorMsg );
1812 memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
1814 if( bBigEndian ) SwapWord( 4, &nPoints );
1816 if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
1818 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nPoints = %d",
1820 psSHP->sHooks.Error( pszErrorMsg );
1825 nRequiredSize = 48 + nPoints * 16;
1828 nRequiredSize += 16 + nPoints * 8;
1830 if (nRequiredSize > nEntitySize)
1832 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
1833 hEntity, nPoints, nEntitySize);
1834 psSHP->sHooks.Error( pszErrorMsg );
1840 psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
1841 psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
1842 psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
1843 psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
1850 snprintf(pszErrorMsg, 128,
1851 "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
1852 "Probably broken SHP file", hEntity, nPoints );
1853 psSHP->sHooks.Error( pszErrorMsg );
1858 for( i = 0; i < nPoints; i++ )
1860 memcpy(psShape->
padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
1861 memcpy(psShape->
padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
1863 if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
1864 if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
1867 nOffset = 48 + 16*nPoints;
1872 memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 + 4, 8 );
1873 memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1874 memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1875 memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1877 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
1878 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
1879 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
1880 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
1887 memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
1888 memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1890 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
1891 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
1893 for( i = 0; i < nPoints; i++ )
1895 memcpy( psShape->
padfZ + i,
1896 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1897 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
1900 nOffset += 16 + 8*nPoints;
1909 if( nEntitySize >= nOffset + 16 + 8*nPoints )
1911 memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
1912 memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1914 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
1915 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
1917 for( i = 0; i < nPoints; i++ )
1919 memcpy( psShape->
padfM + i,
1920 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1921 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
1937 psShape->
padfX = (
double *) calloc(1,
sizeof(
double));
1938 psShape->
padfY = (
double *) calloc(1,
sizeof(
double));
1939 psShape->
padfZ = (
double *) calloc(1,
sizeof(
double));
1940 psShape->
padfM = (
double *) calloc(1,
sizeof(
double));
1944 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1945 hEntity, nEntitySize);
1946 psSHP->sHooks.Error( pszErrorMsg );
1950 memcpy( psShape->
padfX, psSHP->pabyRec + 12, 8 );
1951 memcpy( psShape->
padfY, psSHP->pabyRec + 20, 8 );
1953 if( bBigEndian ) SwapWord( 8, psShape->
padfX );
1954 if( bBigEndian ) SwapWord( 8, psShape->
padfY );
1963 memcpy( psShape->
padfZ, psSHP->pabyRec + nOffset, 8 );
1965 if( bBigEndian ) SwapWord( 8, psShape->
padfZ );
1976 if( nEntitySize >= nOffset + 8 )
1978 memcpy( psShape->
padfM, psSHP->pabyRec + nOffset, 8 );
1980 if( bBigEndian ) SwapWord( 8, psShape->
padfM );
2020 return "MultiPoint";
2032 return "MultiPointZ";
2044 return "MultiPointM";
2047 return "MultiPatch";
2050 return "UnknownShapeType";
2065 return "TriangleStrip";
2068 return "TriangleFan";
2083 return "UnknownPartType";
2095 if( psShape ==
NULL )
2099 free( psShape->
padfX );
2101 free( psShape->
padfY );
2103 free( psShape->
padfZ );
2105 free( psShape->
padfM );
2126 int iOpRing, bAltered = 0;
2142 for( iOpRing = 0; iOpRing < psObject->
nParts; iOpRing++ )
2144 int bInner, iVert, nVertCount, nVertStart, iCheckRing;
2145 double dfSum, dfTestX, dfTestY;
2165 for( iCheckRing = 0; iCheckRing < psObject->
nParts; iCheckRing++ )
2169 if( iCheckRing == iOpRing )
2174 if( iCheckRing == psObject->
nParts-1 )
2181 for( iEdge = 0; iEdge < nVertCount; iEdge++ )
2185 if( iEdge < nVertCount-1 )
2194 if ( ( psObject->
padfY[iEdge+nVertStart] < dfTestY
2195 && dfTestY <= psObject->padfY[iNext+nVertStart] )
2196 || ( psObject->
padfY[iNext+nVertStart] < dfTestY
2197 && dfTestY <= psObject->
padfY[iEdge+nVertStart] ) )
2202 double const intersect =
2203 ( psObject->
padfX[iEdge+nVertStart]
2204 + ( dfTestY - psObject->
padfY[iEdge+nVertStart] )
2205 / ( psObject->
padfY[iNext+nVertStart] - psObject->
padfY[iEdge+nVertStart] )
2206 * ( psObject->
padfX[iNext+nVertStart] - psObject->
padfX[iEdge+nVertStart] ) );
2208 if (intersect < dfTestX)
2222 if( iOpRing == psObject->
nParts-1 )
2229 for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
2231 dfSum += psObject->
padfX[iVert] * psObject->
padfY[iVert+1]
2232 - psObject->
padfY[iVert] * psObject->
padfX[iVert+1];
2235 dfSum += psObject->
padfX[iVert] * psObject->
padfY[nVertStart]
2236 - psObject->
padfY[iVert] * psObject->
padfX[nVertStart];
2241 if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
2246 for( i = 0; i < nVertCount/2; i++ )
2251 dfSaved = psObject->
padfX[nVertStart+i];
2252 psObject->
padfX[nVertStart+i] =
2253 psObject->
padfX[nVertStart+nVertCount-i-1];
2254 psObject->
padfX[nVertStart+nVertCount-i-1] = dfSaved;
2257 dfSaved = psObject->
padfY[nVertStart+i];
2258 psObject->
padfY[nVertStart+i] =
2259 psObject->
padfY[nVertStart+nVertCount-i-1];
2260 psObject->
padfY[nVertStart+nVertCount-i-1] = dfSaved;
2263 if( psObject->
padfZ )
2265 dfSaved = psObject->
padfZ[nVertStart+i];
2266 psObject->
padfZ[nVertStart+i] =
2267 psObject->
padfZ[nVertStart+nVertCount-i-1];
2268 psObject->
padfZ[nVertStart+nVertCount-i-1] = dfSaved;
2272 if( psObject->
padfM )
2274 dfSaved = psObject->
padfM[nVertStart+i];
2275 psObject->
padfM[nVertStart+i] =
2276 psObject->
padfM[nVertStart+nVertCount-i-1];
2277 psObject->
padfM[nVertStart+nVertCount-i-1] = dfSaved;