225 #include <grass/shapefil.h>
234 SHP_CVSID(
"$Id: shpopen.c 59649 2014-04-08 20:44:17Z mmetz $")
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" );
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 );
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." );
854 sprintf( pszFullname,
"%s.shx", pszBasename );
855 fpSHX = psHooks->
FOpen(pszFullname,
"wb" );
858 psHooks->
Error(
"Failed to create file .shx file." );
870 for( i = 0; i < 100; i++ )
878 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
882 if( bBigEndian ) SwapWord( 4, abyHeader+28 );
886 if( bBigEndian ) SwapWord( 4, abyHeader+32 );
889 ByteCopy( &dValue, abyHeader+36, 8 );
890 ByteCopy( &dValue, abyHeader+44, 8 );
891 ByteCopy( &dValue, abyHeader+52, 8 );
892 ByteCopy( &dValue, abyHeader+60, 8 );
897 if( psHooks->
FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
899 psHooks->
Error(
"Failed to write .shp header." );
908 if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
910 if( psHooks->
FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
912 psHooks->
Error(
"Failed to write .shx header." );
922 return(
SHPOpenLL( pszLayer,
"r+b", psHooks ) );
942 SwapWord( 8, pabyRec + 0 );
943 SwapWord( 8, pabyRec + 8 );
944 SwapWord( 8, pabyRec + 16 );
945 SwapWord( 8, pabyRec + 24 );
973 for( i = 0; i < psObject->
nVertices; i++ )
996 const
int * panPartStart, const
int * panPartType,
997 int nVertices, const
double *padfX, const
double *padfY,
998 const
double * padfZ, const
double * padfM )
1002 int i, bHasM,
bHasZ;
1054 for( i = 0; i < nParts; i++ )
1058 if( panPartType !=
NULL )
1079 assert( padfX !=
NULL );
1080 assert( padfY !=
NULL );
1084 psObject->
padfX[i] = padfX[i];
1085 psObject->
padfY[i] = padfY[i];
1086 if( padfZ !=
NULL && bHasZ )
1087 psObject->
padfZ[i] = padfZ[i];
1088 if( padfM !=
NULL && bHasM )
1089 psObject->
padfM[i] = padfM[i];
1091 if( padfM !=
NULL && bHasM )
1113 const
double * padfX, const
double * padfY,
1114 const
double * padfZ )
1118 nVertices, padfX, padfY, padfZ,
NULL ) );
1132 int nRecordOffset, i, nRecordSize=0;
1150 assert( nShapeId == -1
1151 || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
1153 if( nShapeId != -1 && nShapeId >= psSHP->
nRecords )
1173 + psObject->
nParts * 8 + 128);
1186 int32 nPoints, nParts;
1190 nParts = psObject->
nParts;
1192 _SHPSetBounds( pabyRec + 12, psObject );
1194 if( bBigEndian ) SwapWord( 4, &nPoints );
1195 if( bBigEndian ) SwapWord( 4, &nParts );
1197 ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
1198 ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
1207 for( i = 0; i < psObject->
nParts; i++ )
1209 if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
1218 memcpy( pabyRec + nRecordSize, psObject->
panPartType,
1220 for( i = 0; i < psObject->
nParts; i++ )
1222 if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
1230 for( i = 0; i < psObject->
nVertices; i++ )
1233 ByteCopy( psObject->
padfY + i, pabyRec + nRecordSize + 8, 8 );
1236 SwapWord( 8, pabyRec + nRecordSize );
1239 SwapWord( 8, pabyRec + nRecordSize + 8 );
1241 nRecordSize += 2 * 8;
1252 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1256 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1259 for( i = 0; i < psObject->
nVertices; i++ )
1262 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1280 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1284 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1287 for( i = 0; i < psObject->
nVertices; i++ )
1290 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1308 _SHPSetBounds( pabyRec + 12, psObject );
1310 if( bBigEndian ) SwapWord( 4, &nPoints );
1311 ByteCopy( &nPoints, pabyRec + 44, 4 );
1313 for( i = 0; i < psObject->
nVertices; i++ )
1316 ByteCopy( psObject->
padfY + i, pabyRec + 48 + i*16 + 8, 8 );
1318 if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
1319 if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
1322 nRecordSize = 48 + 16 * psObject->
nVertices;
1327 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1331 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1334 for( i = 0; i < psObject->
nVertices; i++ )
1337 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1347 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1351 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1354 for( i = 0; i < psObject->
nVertices; i++ )
1357 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1373 if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
1374 if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
1381 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1390 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1414 if( nShapeId == -1 || psSHP->
panRecSize[nShapeId] < nRecordSize-8 )
1416 if( nShapeId == -1 )
1433 if( !bBigEndian ) SwapWord( 4, &i32 );
1436 i32 = (nRecordSize-8)/2;
1437 if( !bBigEndian ) SwapWord( 4, &i32 );
1441 if( bBigEndian ) SwapWord( 4, &i32 );
1450 psSHP->
sHooks.
Error(
"Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." );
1481 for( i = 0; i < psObject->
nVertices; i++ )
1509 char pszErrorMsg[128];
1514 if( hEntity < 0 || hEntity >= psSHP->nRecords )
1520 nEntitySize = psSHP->panRecSize[hEntity]+8;
1521 if( nEntitySize > psSHP->nBufSize )
1523 psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
1524 if (psSHP->pabyRec ==
NULL)
1529 psSHP->pabyRec =
malloc(psSHP->nBufSize);
1532 "Not enough memory to allocate requested memory (nBufSize=%d). "
1533 "Probably broken SHP file", psSHP->nBufSize );
1534 psSHP->sHooks.Error( szError );
1551 if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
1552 || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1,
1553 psSHP->fpSHP ) != 1 )
1560 psSHP->sHooks.Error(
"Error in fseek() or fread() reading object from .shp file." );
1571 if ( 8 + 4 > nEntitySize )
1573 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1574 hEntity, nEntitySize);
1575 psSHP->sHooks.Error( pszErrorMsg );
1579 memcpy( &psShape->
nSHPType, psSHP->pabyRec + 8, 4 );
1593 int32 nPoints, nParts;
1596 if ( 40 + 8 + 4 > nEntitySize )
1598 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1599 hEntity, nEntitySize);
1600 psSHP->sHooks.Error( pszErrorMsg );
1607 memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 + 4, 8 );
1608 memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1609 memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1610 memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1612 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
1613 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
1614 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
1615 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
1621 memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1622 memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1624 if( bBigEndian ) SwapWord( 4, &nPoints );
1625 if( bBigEndian ) SwapWord( 4, &nParts );
1627 if (nPoints < 0 || nParts < 0 ||
1628 nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
1630 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
1631 hEntity, nPoints, nParts);
1632 psSHP->sHooks.Error( pszErrorMsg );
1640 nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
1645 nRequiredSize += 16 + 8 * nPoints;
1649 nRequiredSize += 4 * nParts;
1651 if (nRequiredSize > nEntitySize)
1653 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
1654 hEntity, nPoints, nParts, nEntitySize);
1655 psSHP->sHooks.Error( pszErrorMsg );
1661 psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
1662 psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
1663 psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
1664 psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
1666 psShape->
nParts = nParts;
1667 psShape->
panPartStart = (
int *) calloc(nParts,
sizeof(
int));
1668 psShape->
panPartType = (
int *) calloc(nParts,
sizeof(
int));
1677 snprintf(pszErrorMsg, 128,
1678 "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
1679 "Probably broken SHP file", hEntity, nPoints, nParts );
1680 psSHP->sHooks.Error( pszErrorMsg );
1685 for( i = 0; i < nParts; i++ )
1691 memcpy( psShape->
panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1692 for( i = 0; i < nParts; i++ )
1694 if( bBigEndian ) SwapWord( 4, psShape->
panPartStart+i );
1700 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
1702 psSHP->sHooks.Error( pszErrorMsg );
1708 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
1710 psSHP->sHooks.Error( pszErrorMsg );
1716 nOffset = 44 + 8 + 4*nParts;
1723 memcpy( psShape->
panPartType, psSHP->pabyRec + nOffset, 4*nParts );
1724 for( i = 0; i < nParts; i++ )
1726 if( bBigEndian ) SwapWord( 4, psShape->
panPartType+i );
1729 nOffset += 4*nParts;
1735 for( i = 0; i < nPoints; i++ )
1737 memcpy(psShape->
padfX + i,
1738 psSHP->pabyRec + nOffset + i * 16,
1741 memcpy(psShape->
padfY + i,
1742 psSHP->pabyRec + nOffset + i * 16 + 8,
1745 if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
1746 if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
1749 nOffset += 16*nPoints;
1758 memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
1759 memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1761 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
1762 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
1764 for( i = 0; i < nPoints; i++ )
1766 memcpy( psShape->
padfZ + i,
1767 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1768 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
1771 nOffset += 16 + 8*nPoints;
1780 if( nEntitySize >= nOffset + 16 + 8*nPoints )
1782 memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
1783 memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1785 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
1786 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
1788 for( i = 0; i < nPoints; i++ )
1790 memcpy( psShape->
padfM + i,
1791 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1792 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
1808 if ( 44 + 4 > nEntitySize )
1810 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1811 hEntity, nEntitySize);
1812 psSHP->sHooks.Error( pszErrorMsg );
1816 memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
1818 if( bBigEndian ) SwapWord( 4, &nPoints );
1820 if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
1822 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nPoints = %d",
1824 psSHP->sHooks.Error( pszErrorMsg );
1829 nRequiredSize = 48 + nPoints * 16;
1832 nRequiredSize += 16 + nPoints * 8;
1834 if (nRequiredSize > nEntitySize)
1836 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
1837 hEntity, nPoints, nEntitySize);
1838 psSHP->sHooks.Error( pszErrorMsg );
1844 psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
1845 psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
1846 psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
1847 psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
1854 snprintf(pszErrorMsg, 128,
1855 "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
1856 "Probably broken SHP file", hEntity, nPoints );
1857 psSHP->sHooks.Error( pszErrorMsg );
1862 for( i = 0; i < nPoints; i++ )
1864 memcpy(psShape->
padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
1865 memcpy(psShape->
padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
1867 if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
1868 if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
1871 nOffset = 48 + 16*nPoints;
1876 memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 + 4, 8 );
1877 memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1878 memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1879 memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1881 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
1882 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
1883 if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
1884 if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
1891 memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
1892 memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1894 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
1895 if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
1897 for( i = 0; i < nPoints; i++ )
1899 memcpy( psShape->
padfZ + i,
1900 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1901 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
1904 nOffset += 16 + 8*nPoints;
1913 if( nEntitySize >= nOffset + 16 + 8*nPoints )
1915 memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
1916 memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1918 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
1919 if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
1921 for( i = 0; i < nPoints; i++ )
1923 memcpy( psShape->
padfM + i,
1924 psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1925 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
1941 psShape->
padfX = (
double *) calloc(1,
sizeof(
double));
1942 psShape->
padfY = (
double *) calloc(1,
sizeof(
double));
1943 psShape->
padfZ = (
double *) calloc(1,
sizeof(
double));
1944 psShape->
padfM = (
double *) calloc(1,
sizeof(
double));
1948 snprintf(pszErrorMsg, 128,
"Corrupted .shp file : shape %d : nEntitySize = %d",
1949 hEntity, nEntitySize);
1950 psSHP->sHooks.Error( pszErrorMsg );
1954 memcpy( psShape->
padfX, psSHP->pabyRec + 12, 8 );
1955 memcpy( psShape->
padfY, psSHP->pabyRec + 20, 8 );
1957 if( bBigEndian ) SwapWord( 8, psShape->
padfX );
1958 if( bBigEndian ) SwapWord( 8, psShape->
padfY );
1967 memcpy( psShape->
padfZ, psSHP->pabyRec + nOffset, 8 );
1969 if( bBigEndian ) SwapWord( 8, psShape->
padfZ );
1980 if( nEntitySize >= nOffset + 8 )
1982 memcpy( psShape->
padfM, psSHP->pabyRec + nOffset, 8 );
1984 if( bBigEndian ) SwapWord( 8, psShape->
padfM );
2024 return "MultiPoint";
2036 return "MultiPointZ";
2048 return "MultiPointM";
2051 return "MultiPatch";
2054 return "UnknownShapeType";
2069 return "TriangleStrip";
2072 return "TriangleFan";
2087 return "UnknownPartType";
2099 if( psShape ==
NULL )
2130 int iOpRing, bAltered = 0;
2146 for( iOpRing = 0; iOpRing < psObject->
nParts; iOpRing++ )
2148 int bInner, iVert, nVertCount, nVertStart, iCheckRing;
2149 double dfSum, dfTestX, dfTestY;
2169 for( iCheckRing = 0; iCheckRing < psObject->
nParts; iCheckRing++ )
2173 if( iCheckRing == iOpRing )
2178 if( iCheckRing == psObject->
nParts-1 )
2185 for( iEdge = 0; iEdge < nVertCount; iEdge++ )
2189 if( iEdge < nVertCount-1 )
2198 if ( ( psObject->
padfY[iEdge+nVertStart] < dfTestY
2199 && dfTestY <= psObject->padfY[iNext+nVertStart] )
2200 || ( psObject->
padfY[iNext+nVertStart] < dfTestY
2201 && dfTestY <= psObject->
padfY[iEdge+nVertStart] ) )
2206 double const intersect =
2207 ( psObject->
padfX[iEdge+nVertStart]
2208 + ( dfTestY - psObject->
padfY[iEdge+nVertStart] )
2209 / ( psObject->
padfY[iNext+nVertStart] - psObject->
padfY[iEdge+nVertStart] )
2210 * ( psObject->
padfX[iNext+nVertStart] - psObject->
padfX[iEdge+nVertStart] ) );
2212 if (intersect < dfTestX)
2226 if( iOpRing == psObject->
nParts-1 )
2233 for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
2235 dfSum += psObject->
padfX[iVert] * psObject->
padfY[iVert+1]
2236 - psObject->
padfY[iVert] * psObject->
padfX[iVert+1];
2239 dfSum += psObject->
padfX[iVert] * psObject->
padfY[nVertStart]
2240 - psObject->
padfY[iVert] * psObject->
padfX[nVertStart];
2245 if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
2250 for( i = 0; i < nVertCount/2; i++ )
2255 dfSaved = psObject->
padfX[nVertStart+i];
2256 psObject->
padfX[nVertStart+i] =
2257 psObject->
padfX[nVertStart+nVertCount-i-1];
2258 psObject->
padfX[nVertStart+nVertCount-i-1] = dfSaved;
2261 dfSaved = psObject->
padfY[nVertStart+i];
2262 psObject->
padfY[nVertStart+i] =
2263 psObject->
padfY[nVertStart+nVertCount-i-1];
2264 psObject->
padfY[nVertStart+nVertCount-i-1] = dfSaved;
2267 if( psObject->
padfZ )
2269 dfSaved = psObject->
padfZ[nVertStart+i];
2270 psObject->
padfZ[nVertStart+i] =
2271 psObject->
padfZ[nVertStart+nVertCount-i-1];
2272 psObject->
padfZ[nVertStart+nVertCount-i-1] = dfSaved;
2276 if( psObject->
padfM )
2278 dfSaved = psObject->
padfM[nVertStart+i];
2279 psObject->
padfM[nVertStart+i] =
2280 psObject->
padfM[nVertStart+nVertCount-i-1];
2281 psObject->
padfM[nVertStart+nVertCount-i-1] = dfSaved;
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void SHPAPI_CALL SHPComputeExtents(SHPObject *psObject)
int SHPAPI_CALL SHPRewindObject(SHPHandle hSHP, SHPObject *psObject)
SAFile(* FOpen)(const char *filename, const char *path)
void SHPAPI_CALL SHPGetInfo(SHPHandle hSHP, int *pnEntities, int *pnShapeType, double *padfMinBound, double *padfMaxBound)
int(* FClose)(SAFile file)
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
void SHPAPI_CALL SHPClose(SHPHandle hSHP)
int(* FFlush)(SAFile file)
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject *psObject)
SHP_CVSID("$Id: safileio.c,v 1.4 2008/01/16 20:05:14 bram Exp $")
void SASetupDefaultHooks(SAHooks *psHooks)
SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszShapeFile, const char *pszAccess, SAHooks *psHooks)
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType)
void(* Error)(const char *message)
#define ByteCopy(a, b, c)
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)
SHPObject SHPAPI_CALL1 * SHPReadObject(SHPHandle hSHP, int iShape);int SHPAPI_CALLSHPWriteObject(SHPHandle hSHP, int iShape, SHPObject *psObject
SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszShapeFile, int nShapeType, SAHooks *psHooks)
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
const char SHPAPI_CALL1 * SHPPartTypeName(int nPartType){switch(nPartType
SHPHandle SHPAPI_CALL SHPOpen(const char *pszShapeFile, const char *pszAccess)
void SHPAPI_CALL SHPWriteHeader(SHPHandle hSHP)
#define DISABLE_MULTIPATCH_MEASURE
void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject)
const char SHPAPI_CALL1 * SHPTypeName(int nSHPType);const char SHPAPI_CALL1(*) SHPPartTypeName(int nPartType