34 |
****************************************************************************** |
****************************************************************************** |
35 |
* |
* |
36 |
* $Log$ |
* $Log$ |
37 |
* Revision 1.1 2003/08/19 21:29:25 jan |
* Revision 1.2 2003/10/02 15:15:16 bh |
38 |
* These files have been moved here from thuban/extensions/shapelib/ |
* Update to shapelib 1.2.10 |
39 |
* See there in the Attic for the older history. |
* |
40 |
* |
* Revision 1.39 2002/08/26 06:46:56 warmerda |
41 |
* Revision 1.3 2002/05/07 14:09:45 bh |
* avoid c++ comments |
42 |
* * extensions/shapelib/shpopen.c, extensions/shapelib/shapefil.h, |
* |
43 |
* extensions/shapelib/dbfopen.c: Really update to the versions of |
* Revision 1.38 2002/05/07 16:43:39 warmerda |
44 |
* shapelib 1.2.9. For some reason it wasn't really done on |
* Removed debugging printf. |
45 |
* 2002-04-11. |
* |
46 |
|
* Revision 1.37 2002/04/10 17:35:22 warmerda |
47 |
|
* fixed bug in ring reversal code |
48 |
|
* |
49 |
|
* Revision 1.36 2002/04/10 16:59:54 warmerda |
50 |
|
* added SHPRewindObject |
51 |
|
* |
52 |
|
* Revision 1.35 2001/12/07 15:10:44 warmerda |
53 |
|
* fix if .shx fails to open |
54 |
|
* |
55 |
|
* Revision 1.34 2001/11/01 16:29:55 warmerda |
56 |
|
* move pabyRec into SHPInfo for thread safety |
57 |
* |
* |
58 |
* Revision 1.33 2001/07/03 12:18:15 warmerda |
* Revision 1.33 2001/07/03 12:18:15 warmerda |
59 |
* Improved cleanup if SHX not found, provied by Riccardo Cohen. |
* Improved cleanup if SHX not found, provied by Riccardo Cohen. |
192 |
#endif |
#endif |
193 |
|
|
194 |
static int bBigEndian; |
static int bBigEndian; |
|
static uchar *pabyRec = NULL; |
|
|
static int nBufSize = 0; |
|
195 |
|
|
196 |
|
|
197 |
/************************************************************************/ |
/************************************************************************/ |
374 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
375 |
/* Initialize the info structure. */ |
/* Initialize the info structure. */ |
376 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
377 |
psSHP = (SHPHandle) malloc(sizeof(SHPInfo)); |
psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); |
378 |
|
|
379 |
psSHP->bUpdated = FALSE; |
psSHP->bUpdated = FALSE; |
380 |
|
|
423 |
|
|
424 |
if( psSHP->fpSHX == NULL ) |
if( psSHP->fpSHX == NULL ) |
425 |
{ |
{ |
426 |
fclose( psSHP->fpSHX ); |
fclose( psSHP->fpSHP ); |
427 |
free( psSHP ); |
free( psSHP ); |
428 |
free( pszBasename ); |
free( pszBasename ); |
429 |
free( pszFullname ); |
free( pszFullname ); |
573 |
fclose( psSHP->fpSHX ); |
fclose( psSHP->fpSHX ); |
574 |
fclose( psSHP->fpSHP ); |
fclose( psSHP->fpSHP ); |
575 |
|
|
576 |
free( psSHP ); |
if( psSHP->pabyRec != NULL ) |
|
|
|
|
if( pabyRec != NULL ) |
|
577 |
{ |
{ |
578 |
free( pabyRec ); |
free( psSHP->pabyRec ); |
|
pabyRec = NULL; |
|
|
nBufSize = 0; |
|
579 |
} |
} |
580 |
|
|
581 |
|
free( psSHP ); |
582 |
} |
} |
583 |
|
|
584 |
/************************************************************************/ |
/************************************************************************/ |
1290 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1291 |
/* Ensure our record buffer is large enough. */ |
/* Ensure our record buffer is large enough. */ |
1292 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1293 |
if( psSHP->panRecSize[hEntity]+8 > nBufSize ) |
if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) |
1294 |
{ |
{ |
1295 |
nBufSize = psSHP->panRecSize[hEntity]+8; |
psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; |
1296 |
pabyRec = (uchar *) SfRealloc(pabyRec,nBufSize); |
psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); |
1297 |
} |
} |
1298 |
|
|
1299 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1300 |
/* Read the record. */ |
/* Read the record. */ |
1301 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1302 |
fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); |
fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); |
1303 |
fread( pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ); |
fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ); |
1304 |
|
|
1305 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1306 |
/* Allocate and minimally initialize the object. */ |
/* Allocate and minimally initialize the object. */ |
1308 |
psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); |
psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); |
1309 |
psShape->nShapeId = hEntity; |
psShape->nShapeId = hEntity; |
1310 |
|
|
1311 |
memcpy( &psShape->nSHPType, pabyRec + 8, 4 ); |
memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); |
1312 |
if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); |
if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); |
1313 |
|
|
1314 |
/* ==================================================================== */ |
/* ==================================================================== */ |
1327 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1328 |
/* Get the X/Y bounds. */ |
/* Get the X/Y bounds. */ |
1329 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1330 |
memcpy( &(psShape->dfXMin), pabyRec + 8 + 4, 8 ); |
memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); |
1331 |
memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 ); |
memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); |
1332 |
memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 ); |
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); |
1333 |
memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 ); |
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); |
1334 |
|
|
1335 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); |
1336 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); |
1341 |
/* Extract part/point count, and build vertex and part arrays */ |
/* Extract part/point count, and build vertex and part arrays */ |
1342 |
/* to proper size. */ |
/* to proper size. */ |
1343 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1344 |
memcpy( &nPoints, pabyRec + 40 + 8, 4 ); |
memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 ); |
1345 |
memcpy( &nParts, pabyRec + 36 + 8, 4 ); |
memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 ); |
1346 |
|
|
1347 |
if( bBigEndian ) SwapWord( 4, &nPoints ); |
if( bBigEndian ) SwapWord( 4, &nPoints ); |
1348 |
if( bBigEndian ) SwapWord( 4, &nParts ); |
if( bBigEndian ) SwapWord( 4, &nParts ); |
1363 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1364 |
/* Copy out the part array from the record. */ |
/* Copy out the part array from the record. */ |
1365 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1366 |
memcpy( psShape->panPartStart, pabyRec + 44 + 8, 4 * nParts ); |
memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); |
1367 |
for( i = 0; i < nParts; i++ ) |
for( i = 0; i < nParts; i++ ) |
1368 |
{ |
{ |
1369 |
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); |
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); |
1376 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1377 |
if( psShape->nSHPType == SHPT_MULTIPATCH ) |
if( psShape->nSHPType == SHPT_MULTIPATCH ) |
1378 |
{ |
{ |
1379 |
memcpy( psShape->panPartType, pabyRec + nOffset, 4*nParts ); |
memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); |
1380 |
for( i = 0; i < nParts; i++ ) |
for( i = 0; i < nParts; i++ ) |
1381 |
{ |
{ |
1382 |
if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); |
if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); |
1391 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1392 |
{ |
{ |
1393 |
memcpy(psShape->padfX + i, |
memcpy(psShape->padfX + i, |
1394 |
pabyRec + nOffset + i * 16, |
psSHP->pabyRec + nOffset + i * 16, |
1395 |
8 ); |
8 ); |
1396 |
|
|
1397 |
memcpy(psShape->padfY + i, |
memcpy(psShape->padfY + i, |
1398 |
pabyRec + nOffset + i * 16 + 8, |
psSHP->pabyRec + nOffset + i * 16 + 8, |
1399 |
8 ); |
8 ); |
1400 |
|
|
1401 |
if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); |
1411 |
|| psShape->nSHPType == SHPT_ARCZ |
|| psShape->nSHPType == SHPT_ARCZ |
1412 |
|| psShape->nSHPType == SHPT_MULTIPATCH ) |
|| psShape->nSHPType == SHPT_MULTIPATCH ) |
1413 |
{ |
{ |
1414 |
memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 ); |
memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); |
1415 |
memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 ); |
memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); |
1416 |
|
|
1417 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); |
1418 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); |
1420 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1421 |
{ |
{ |
1422 |
memcpy( psShape->padfZ + i, |
memcpy( psShape->padfZ + i, |
1423 |
pabyRec + nOffset + 16 + i*8, 8 ); |
psSHP->pabyRec + nOffset + 16 + i*8, 8 ); |
1424 |
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); |
1425 |
} |
} |
1426 |
|
|
1435 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1436 |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) |
1437 |
{ |
{ |
1438 |
memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 ); |
memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); |
1439 |
memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 ); |
memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); |
1440 |
|
|
1441 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); |
1442 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); |
1444 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1445 |
{ |
{ |
1446 |
memcpy( psShape->padfM + i, |
memcpy( psShape->padfM + i, |
1447 |
pabyRec + nOffset + 16 + i*8, 8 ); |
psSHP->pabyRec + nOffset + 16 + i*8, 8 ); |
1448 |
if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); |
1449 |
} |
} |
1450 |
} |
} |
1461 |
int32 nPoints; |
int32 nPoints; |
1462 |
int i, nOffset; |
int i, nOffset; |
1463 |
|
|
1464 |
memcpy( &nPoints, pabyRec + 44, 4 ); |
memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); |
1465 |
if( bBigEndian ) SwapWord( 4, &nPoints ); |
if( bBigEndian ) SwapWord( 4, &nPoints ); |
1466 |
|
|
1467 |
psShape->nVertices = nPoints; |
psShape->nVertices = nPoints; |
1472 |
|
|
1473 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1474 |
{ |
{ |
1475 |
memcpy(psShape->padfX+i, pabyRec + 48 + 16 * i, 8 ); |
memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); |
1476 |
memcpy(psShape->padfY+i, pabyRec + 48 + 16 * i + 8, 8 ); |
memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); |
1477 |
|
|
1478 |
if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); |
1479 |
if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); |
1484 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1485 |
/* Get the X/Y bounds. */ |
/* Get the X/Y bounds. */ |
1486 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1487 |
memcpy( &(psShape->dfXMin), pabyRec + 8 + 4, 8 ); |
memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); |
1488 |
memcpy( &(psShape->dfYMin), pabyRec + 8 + 12, 8 ); |
memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); |
1489 |
memcpy( &(psShape->dfXMax), pabyRec + 8 + 20, 8 ); |
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); |
1490 |
memcpy( &(psShape->dfYMax), pabyRec + 8 + 28, 8 ); |
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); |
1491 |
|
|
1492 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); |
1493 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); |
1499 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1500 |
if( psShape->nSHPType == SHPT_MULTIPOINTZ ) |
if( psShape->nSHPType == SHPT_MULTIPOINTZ ) |
1501 |
{ |
{ |
1502 |
memcpy( &(psShape->dfZMin), pabyRec + nOffset, 8 ); |
memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); |
1503 |
memcpy( &(psShape->dfZMax), pabyRec + nOffset + 8, 8 ); |
memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); |
1504 |
|
|
1505 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); |
1506 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); |
1508 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1509 |
{ |
{ |
1510 |
memcpy( psShape->padfZ + i, |
memcpy( psShape->padfZ + i, |
1511 |
pabyRec + nOffset + 16 + i*8, 8 ); |
psSHP->pabyRec + nOffset + 16 + i*8, 8 ); |
1512 |
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); |
1513 |
} |
} |
1514 |
|
|
1523 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1524 |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) |
1525 |
{ |
{ |
1526 |
memcpy( &(psShape->dfMMin), pabyRec + nOffset, 8 ); |
memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); |
1527 |
memcpy( &(psShape->dfMMax), pabyRec + nOffset + 8, 8 ); |
memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); |
1528 |
|
|
1529 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); |
1530 |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); |
if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); |
1532 |
for( i = 0; i < nPoints; i++ ) |
for( i = 0; i < nPoints; i++ ) |
1533 |
{ |
{ |
1534 |
memcpy( psShape->padfM + i, |
memcpy( psShape->padfM + i, |
1535 |
pabyRec + nOffset + 16 + i*8, 8 ); |
psSHP->pabyRec + nOffset + 16 + i*8, 8 ); |
1536 |
if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); |
if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); |
1537 |
} |
} |
1538 |
} |
} |
1553 |
psShape->padfZ = (double *) calloc(1,sizeof(double)); |
psShape->padfZ = (double *) calloc(1,sizeof(double)); |
1554 |
psShape->padfM = (double *) calloc(1,sizeof(double)); |
psShape->padfM = (double *) calloc(1,sizeof(double)); |
1555 |
|
|
1556 |
memcpy( psShape->padfX, pabyRec + 12, 8 ); |
memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); |
1557 |
memcpy( psShape->padfY, pabyRec + 20, 8 ); |
memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); |
1558 |
|
|
1559 |
if( bBigEndian ) SwapWord( 8, psShape->padfX ); |
if( bBigEndian ) SwapWord( 8, psShape->padfX ); |
1560 |
if( bBigEndian ) SwapWord( 8, psShape->padfY ); |
if( bBigEndian ) SwapWord( 8, psShape->padfY ); |
1566 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1567 |
if( psShape->nSHPType == SHPT_POINTZ ) |
if( psShape->nSHPType == SHPT_POINTZ ) |
1568 |
{ |
{ |
1569 |
memcpy( psShape->padfZ, pabyRec + nOffset, 8 ); |
memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 ); |
1570 |
|
|
1571 |
if( bBigEndian ) SwapWord( 8, psShape->padfZ ); |
if( bBigEndian ) SwapWord( 8, psShape->padfZ ); |
1572 |
|
|
1581 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1582 |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) |
if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) |
1583 |
{ |
{ |
1584 |
memcpy( psShape->padfM, pabyRec + nOffset, 8 ); |
memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); |
1585 |
|
|
1586 |
if( bBigEndian ) SwapWord( 8, psShape->padfM ); |
if( bBigEndian ) SwapWord( 8, psShape->padfM ); |
1587 |
} |
} |
1716 |
|
|
1717 |
free( psShape ); |
free( psShape ); |
1718 |
} |
} |
1719 |
|
|
1720 |
|
/************************************************************************/ |
1721 |
|
/* SHPRewindObject() */ |
1722 |
|
/* */ |
1723 |
|
/* Reset the winding of polygon objects to adhere to the */ |
1724 |
|
/* specification. */ |
1725 |
|
/************************************************************************/ |
1726 |
|
|
1727 |
|
int SHPAPI_CALL |
1728 |
|
SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ) |
1729 |
|
|
1730 |
|
{ |
1731 |
|
int iOpRing, bAltered = 0; |
1732 |
|
|
1733 |
|
/* -------------------------------------------------------------------- */ |
1734 |
|
/* Do nothing if this is not a polygon object. */ |
1735 |
|
/* -------------------------------------------------------------------- */ |
1736 |
|
if( psObject->nSHPType != SHPT_POLYGON |
1737 |
|
&& psObject->nSHPType != SHPT_POLYGONZ |
1738 |
|
&& psObject->nSHPType != SHPT_POLYGONM ) |
1739 |
|
return 0; |
1740 |
|
|
1741 |
|
/* -------------------------------------------------------------------- */ |
1742 |
|
/* Process each of the rings. */ |
1743 |
|
/* -------------------------------------------------------------------- */ |
1744 |
|
for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ ) |
1745 |
|
{ |
1746 |
|
int bInner, iVert, nVertCount, nVertStart, iCheckRing; |
1747 |
|
double dfSum, dfTestX, dfTestY; |
1748 |
|
|
1749 |
|
/* -------------------------------------------------------------------- */ |
1750 |
|
/* Determine if this ring is an inner ring or an outer ring */ |
1751 |
|
/* relative to all the other rings. For now we assume the */ |
1752 |
|
/* first ring is outer and all others are inner, but eventually */ |
1753 |
|
/* we need to fix this to handle multiple island polygons and */ |
1754 |
|
/* unordered sets of rings. */ |
1755 |
|
/* -------------------------------------------------------------------- */ |
1756 |
|
dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]]; |
1757 |
|
dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]]; |
1758 |
|
|
1759 |
|
bInner = FALSE; |
1760 |
|
for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) |
1761 |
|
{ |
1762 |
|
int iEdge; |
1763 |
|
|
1764 |
|
if( iCheckRing == iOpRing ) |
1765 |
|
continue; |
1766 |
|
|
1767 |
|
nVertStart = psObject->panPartStart[iCheckRing]; |
1768 |
|
|
1769 |
|
if( iCheckRing == psObject->nParts-1 ) |
1770 |
|
nVertCount = psObject->nVertices |
1771 |
|
- psObject->panPartStart[iCheckRing]; |
1772 |
|
else |
1773 |
|
nVertCount = psObject->panPartStart[iCheckRing+1] |
1774 |
|
- psObject->panPartStart[iCheckRing]; |
1775 |
|
|
1776 |
|
for( iEdge = 0; iEdge < nVertCount; iEdge++ ) |
1777 |
|
{ |
1778 |
|
int iNext; |
1779 |
|
|
1780 |
|
if( iEdge < nVertCount-1 ) |
1781 |
|
iNext = iEdge+1; |
1782 |
|
else |
1783 |
|
iNext = 0; |
1784 |
|
|
1785 |
|
if( (psObject->padfY[iEdge+nVertStart] < dfTestY |
1786 |
|
&& psObject->padfY[iNext+nVertStart] >= dfTestY) |
1787 |
|
|| (psObject->padfY[iNext+nVertStart] < dfTestY |
1788 |
|
&& psObject->padfY[iEdge+nVertStart] >= dfTestY) ) |
1789 |
|
{ |
1790 |
|
if( psObject->padfX[iEdge+nVertStart] |
1791 |
|
+ (dfTestY - psObject->padfY[iEdge+nVertStart]) |
1792 |
|
/ (psObject->padfY[iNext+nVertStart] |
1793 |
|
- psObject->padfY[iEdge+nVertStart]) |
1794 |
|
* (psObject->padfX[iNext+nVertStart] |
1795 |
|
- psObject->padfX[iEdge+nVertStart]) < dfTestX ) |
1796 |
|
bInner = !bInner; |
1797 |
|
} |
1798 |
|
} |
1799 |
|
} |
1800 |
|
|
1801 |
|
/* -------------------------------------------------------------------- */ |
1802 |
|
/* Determine the current order of this ring so we will know if */ |
1803 |
|
/* it has to be reversed. */ |
1804 |
|
/* -------------------------------------------------------------------- */ |
1805 |
|
nVertStart = psObject->panPartStart[iOpRing]; |
1806 |
|
|
1807 |
|
if( iOpRing == psObject->nParts-1 ) |
1808 |
|
nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing]; |
1809 |
|
else |
1810 |
|
nVertCount = psObject->panPartStart[iOpRing+1] |
1811 |
|
- psObject->panPartStart[iOpRing]; |
1812 |
|
|
1813 |
|
dfSum = 0.0; |
1814 |
|
for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ ) |
1815 |
|
{ |
1816 |
|
dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1] |
1817 |
|
- psObject->padfY[iVert] * psObject->padfX[iVert+1]; |
1818 |
|
} |
1819 |
|
|
1820 |
|
dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart] |
1821 |
|
- psObject->padfY[iVert] * psObject->padfX[nVertStart]; |
1822 |
|
|
1823 |
|
/* -------------------------------------------------------------------- */ |
1824 |
|
/* Reverse if necessary. */ |
1825 |
|
/* -------------------------------------------------------------------- */ |
1826 |
|
if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) ) |
1827 |
|
{ |
1828 |
|
int i; |
1829 |
|
|
1830 |
|
bAltered++; |
1831 |
|
for( i = 0; i < nVertCount/2; i++ ) |
1832 |
|
{ |
1833 |
|
double dfSaved; |
1834 |
|
|
1835 |
|
/* Swap X */ |
1836 |
|
dfSaved = psObject->padfX[nVertStart+i]; |
1837 |
|
psObject->padfX[nVertStart+i] = |
1838 |
|
psObject->padfX[nVertStart+nVertCount-i-1]; |
1839 |
|
psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved; |
1840 |
|
|
1841 |
|
/* Swap Y */ |
1842 |
|
dfSaved = psObject->padfY[nVertStart+i]; |
1843 |
|
psObject->padfY[nVertStart+i] = |
1844 |
|
psObject->padfY[nVertStart+nVertCount-i-1]; |
1845 |
|
psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved; |
1846 |
|
|
1847 |
|
/* Swap Z */ |
1848 |
|
if( psObject->padfZ ) |
1849 |
|
{ |
1850 |
|
dfSaved = psObject->padfZ[nVertStart+i]; |
1851 |
|
psObject->padfZ[nVertStart+i] = |
1852 |
|
psObject->padfZ[nVertStart+nVertCount-i-1]; |
1853 |
|
psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved; |
1854 |
|
} |
1855 |
|
|
1856 |
|
/* Swap M */ |
1857 |
|
if( psObject->padfM ) |
1858 |
|
{ |
1859 |
|
dfSaved = psObject->padfM[nVertStart+i]; |
1860 |
|
psObject->padfM[nVertStart+i] = |
1861 |
|
psObject->padfM[nVertStart+nVertCount-i-1]; |
1862 |
|
psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved; |
1863 |
|
} |
1864 |
|
} |
1865 |
|
} |
1866 |
|
} |
1867 |
|
|
1868 |
|
return bAltered; |
1869 |
|
} |