PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ SHPWriteObject()

int SHPAPI_CALL SHPWriteObject ( SHPHandle  psSHP,
int  nShapeId,
SHPObject psObject 
)

Definition at line 1334 of file shpopen.c.

1336 {
1337  SAOffset nRecordOffset;
1338  unsigned int nRecordSize=0;
1339  int i;
1340  uchar *pabyRec;
1341  int32 i32;
1342  int bAppendToLastRecord = FALSE;
1343  int bAppendToFile = FALSE;
1344 
1345  psSHP->bUpdated = TRUE;
1346 
1347 /* -------------------------------------------------------------------- */
1348 /* Ensure that shape object matches the type of the file it is */
1349 /* being written to. */
1350 /* -------------------------------------------------------------------- */
1351  assert( psObject->nSHPType == psSHP->nShapeType
1352  || psObject->nSHPType == SHPT_NULL );
1353 
1354 /* -------------------------------------------------------------------- */
1355 /* Ensure that -1 is used for appends. Either blow an */
1356 /* assertion, or if they are disabled, set the shapeid to -1 */
1357 /* for appends. */
1358 /* -------------------------------------------------------------------- */
1359  assert( nShapeId == -1
1360  || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
1361 
1362  if( nShapeId != -1 && nShapeId >= psSHP->nRecords )
1363  nShapeId = -1;
1364 
1365 /* -------------------------------------------------------------------- */
1366 /* Add the new entity to the in memory index. */
1367 /* -------------------------------------------------------------------- */
1368  if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
1369  {
1370  int nNewMaxRecords = psSHP->nMaxRecords + psSHP->nMaxRecords / 3 + 100;
1371  unsigned int* panRecOffsetNew;
1372  unsigned int* panRecSizeNew;
1373 
1374  panRecOffsetNew = STATIC_CAST(unsigned int *,
1375  SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * nNewMaxRecords ));
1376  if( panRecOffsetNew == SHPLIB_NULLPTR )
1377  return -1;
1378  psSHP->panRecOffset = panRecOffsetNew;
1379 
1380  panRecSizeNew = STATIC_CAST(unsigned int *,
1381  SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * nNewMaxRecords ));
1382  if( panRecSizeNew == SHPLIB_NULLPTR )
1383  return -1;
1384  psSHP->panRecSize = panRecSizeNew;
1385 
1386  psSHP->nMaxRecords = nNewMaxRecords;
1387  }
1388 
1389 /* -------------------------------------------------------------------- */
1390 /* Initialize record. */
1391 /* -------------------------------------------------------------------- */
1392  pabyRec = STATIC_CAST(uchar *, malloc(psObject->nVertices * 4 * sizeof(double)
1393  + psObject->nParts * 8 + 128));
1394  if( pabyRec == SHPLIB_NULLPTR )
1395  return -1;
1396 
1397 /* -------------------------------------------------------------------- */
1398 /* Extract vertices for a Polygon or Arc. */
1399 /* -------------------------------------------------------------------- */
1400  if( psObject->nSHPType == SHPT_POLYGON
1401  || psObject->nSHPType == SHPT_POLYGONZ
1402  || psObject->nSHPType == SHPT_POLYGONM
1403  || psObject->nSHPType == SHPT_ARC
1404  || psObject->nSHPType == SHPT_ARCZ
1405  || psObject->nSHPType == SHPT_ARCM
1406  || psObject->nSHPType == SHPT_MULTIPATCH )
1407  {
1408  int32 nPoints, nParts;
1409 
1410  nPoints = psObject->nVertices;
1411  nParts = psObject->nParts;
1412 
1413  _SHPSetBounds( pabyRec + 12, psObject );
1414 
1415  if( bBigEndian ) SwapWord( 4, &nPoints );
1416  if( bBigEndian ) SwapWord( 4, &nParts );
1417 
1418  ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
1419  ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
1420 
1421  nRecordSize = 52;
1422 
1423  /*
1424  * Write part start positions.
1425  */
1426  ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
1427  4 * psObject->nParts );
1428  for( i = 0; i < psObject->nParts; i++ )
1429  {
1430  if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
1431  nRecordSize += 4;
1432  }
1433 
1434  /*
1435  * Write multipatch part types if needed.
1436  */
1437  if( psObject->nSHPType == SHPT_MULTIPATCH )
1438  {
1439  memcpy( pabyRec + nRecordSize, psObject->panPartType,
1440  4*psObject->nParts );
1441  for( i = 0; i < psObject->nParts; i++ )
1442  {
1443  if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
1444  nRecordSize += 4;
1445  }
1446  }
1447 
1448  /*
1449  * Write the (x,y) vertex values.
1450  */
1451  for( i = 0; i < psObject->nVertices; i++ )
1452  {
1453  ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
1454  ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
1455 
1456  if( bBigEndian )
1457  SwapWord( 8, pabyRec + nRecordSize );
1458 
1459  if( bBigEndian )
1460  SwapWord( 8, pabyRec + nRecordSize + 8 );
1461 
1462  nRecordSize += 2 * 8;
1463  }
1464 
1465  /*
1466  * Write the Z coordinates (if any).
1467  */
1468  if( psObject->nSHPType == SHPT_POLYGONZ
1469  || psObject->nSHPType == SHPT_ARCZ
1470  || psObject->nSHPType == SHPT_MULTIPATCH )
1471  {
1472  ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
1473  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1474  nRecordSize += 8;
1475 
1476  ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
1477  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1478  nRecordSize += 8;
1479 
1480  for( i = 0; i < psObject->nVertices; i++ )
1481  {
1482  ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
1483  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1484  nRecordSize += 8;
1485  }
1486  }
1487 
1488  /*
1489  * Write the M values, if any.
1490  */
1491  if( psObject->bMeasureIsUsed
1492  && (psObject->nSHPType == SHPT_POLYGONM
1493  || psObject->nSHPType == SHPT_ARCM
1495  || psObject->nSHPType == SHPT_MULTIPATCH
1496 #endif
1497  || psObject->nSHPType == SHPT_POLYGONZ
1498  || psObject->nSHPType == SHPT_ARCZ) )
1499  {
1500  ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
1501  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1502  nRecordSize += 8;
1503 
1504  ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
1505  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1506  nRecordSize += 8;
1507 
1508  for( i = 0; i < psObject->nVertices; i++ )
1509  {
1510  ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
1511  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1512  nRecordSize += 8;
1513  }
1514  }
1515  }
1516 
1517 /* -------------------------------------------------------------------- */
1518 /* Extract vertices for a MultiPoint. */
1519 /* -------------------------------------------------------------------- */
1520  else if( psObject->nSHPType == SHPT_MULTIPOINT
1521  || psObject->nSHPType == SHPT_MULTIPOINTZ
1522  || psObject->nSHPType == SHPT_MULTIPOINTM )
1523  {
1524  int32 nPoints;
1525 
1526  nPoints = psObject->nVertices;
1527 
1528  _SHPSetBounds( pabyRec + 12, psObject );
1529 
1530  if( bBigEndian ) SwapWord( 4, &nPoints );
1531  ByteCopy( &nPoints, pabyRec + 44, 4 );
1532 
1533  for( i = 0; i < psObject->nVertices; i++ )
1534  {
1535  ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
1536  ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
1537 
1538  if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
1539  if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
1540  }
1541 
1542  nRecordSize = 48 + 16 * psObject->nVertices;
1543 
1544  if( psObject->nSHPType == SHPT_MULTIPOINTZ )
1545  {
1546  ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
1547  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1548  nRecordSize += 8;
1549 
1550  ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
1551  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1552  nRecordSize += 8;
1553 
1554  for( i = 0; i < psObject->nVertices; i++ )
1555  {
1556  ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
1557  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1558  nRecordSize += 8;
1559  }
1560  }
1561 
1562  if( psObject->bMeasureIsUsed
1563  && (psObject->nSHPType == SHPT_MULTIPOINTZ
1564  || psObject->nSHPType == SHPT_MULTIPOINTM) )
1565  {
1566  ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
1567  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1568  nRecordSize += 8;
1569 
1570  ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
1571  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1572  nRecordSize += 8;
1573 
1574  for( i = 0; i < psObject->nVertices; i++ )
1575  {
1576  ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
1577  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1578  nRecordSize += 8;
1579  }
1580  }
1581  }
1582 
1583 /* -------------------------------------------------------------------- */
1584 /* Write point. */
1585 /* -------------------------------------------------------------------- */
1586  else if( psObject->nSHPType == SHPT_POINT
1587  || psObject->nSHPType == SHPT_POINTZ
1588  || psObject->nSHPType == SHPT_POINTM )
1589  {
1590  ByteCopy( psObject->padfX, pabyRec + 12, 8 );
1591  ByteCopy( psObject->padfY, pabyRec + 20, 8 );
1592 
1593  if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
1594  if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
1595 
1596  nRecordSize = 28;
1597 
1598  if( psObject->nSHPType == SHPT_POINTZ )
1599  {
1600  ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 );
1601  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1602  nRecordSize += 8;
1603  }
1604 
1605  if( psObject->bMeasureIsUsed
1606  && (psObject->nSHPType == SHPT_POINTZ
1607  || psObject->nSHPType == SHPT_POINTM) )
1608  {
1609  ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
1610  if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1611  nRecordSize += 8;
1612  }
1613  }
1614 
1615 /* -------------------------------------------------------------------- */
1616 /* Not much to do for null geometries. */
1617 /* -------------------------------------------------------------------- */
1618  else if( psObject->nSHPType == SHPT_NULL )
1619  {
1620  nRecordSize = 12;
1621  }
1622 
1623  else
1624  {
1625  /* unknown type */
1626  assert( FALSE );
1627  }
1628 
1629 /* -------------------------------------------------------------------- */
1630 /* Establish where we are going to put this record. If we are */
1631 /* rewriting the last record of the file, then we can update it in */
1632 /* place. Otherwise if rewriting an existing record, and it will */
1633 /* fit, then put it back where the original came from. Otherwise */
1634 /* write at the end. */
1635 /* -------------------------------------------------------------------- */
1636  if( nShapeId != -1 && psSHP->panRecOffset[nShapeId] +
1637  psSHP->panRecSize[nShapeId] + 8 == psSHP->nFileSize )
1638  {
1639  nRecordOffset = psSHP->panRecOffset[nShapeId];
1640  bAppendToLastRecord = TRUE;
1641  }
1642  else if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
1643  {
1644  if( psSHP->nFileSize > UINT_MAX - nRecordSize)
1645  {
1646  char str[128];
1647  snprintf( str, sizeof(str), "Failed to write shape object. "
1648  "File size cannot reach %u + %u.",
1649  psSHP->nFileSize, nRecordSize );
1650  str[sizeof(str)-1] = '\0';
1651  psSHP->sHooks.Error( str );
1652  free( pabyRec );
1653  return -1;
1654  }
1655 
1656  bAppendToFile = TRUE;
1657  nRecordOffset = psSHP->nFileSize;
1658  }
1659  else
1660  {
1661  nRecordOffset = psSHP->panRecOffset[nShapeId];
1662  }
1663 
1664 /* -------------------------------------------------------------------- */
1665 /* Set the shape type, record number, and record size. */
1666 /* -------------------------------------------------------------------- */
1667  i32 = (nShapeId < 0) ? psSHP->nRecords+1 : nShapeId+1; /* record # */
1668  if( !bBigEndian ) SwapWord( 4, &i32 );
1669  ByteCopy( &i32, pabyRec, 4 );
1670 
1671  i32 = (nRecordSize-8)/2; /* record size */
1672  if( !bBigEndian ) SwapWord( 4, &i32 );
1673  ByteCopy( &i32, pabyRec + 4, 4 );
1674 
1675  i32 = psObject->nSHPType; /* shape type */
1676  if( bBigEndian ) SwapWord( 4, &i32 );
1677  ByteCopy( &i32, pabyRec + 8, 4 );
1678 
1679 /* -------------------------------------------------------------------- */
1680 /* Write out record. */
1681 /* -------------------------------------------------------------------- */
1682 
1683 /* -------------------------------------------------------------------- */
1684 /* Guard FSeek with check for whether we're already at position; */
1685 /* no-op FSeeks defeat network filesystems' write buffering. */
1686 /* -------------------------------------------------------------------- */
1687 /* TOOK OUT GUARD cause causing mingw64 to fail, see https://trac.osgeo.org/postgis/ticket/4603 */
1688  //if ( psSHP->sHooks.FTell( psSHP->fpSHP ) != nRecordOffset ) {
1689  if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 )
1690  {
1691  char szErrorMsg[200];
1692 
1693  snprintf( szErrorMsg, sizeof(szErrorMsg),
1694  "Error in psSHP->sHooks.FSeek() while writing object to .shp file: %s",
1695  strerror(errno) );
1696  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
1697  psSHP->sHooks.Error( szErrorMsg );
1698 
1699  free( pabyRec );
1700  return -1;
1701  }
1702  //}
1703  if( psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
1704  {
1705  char szErrorMsg[200];
1706 
1707  snprintf( szErrorMsg, sizeof(szErrorMsg),
1708  "Error in psSHP->sHooks.FWrite() while writing object of %u bytes to .shp file: %s",
1709  nRecordSize, strerror(errno) );
1710  szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
1711  psSHP->sHooks.Error( szErrorMsg );
1712 
1713  free( pabyRec );
1714  return -1;
1715  }
1716 
1717  free( pabyRec );
1718 
1719  if( bAppendToLastRecord )
1720  {
1721  psSHP->nFileSize = psSHP->panRecOffset[nShapeId] + nRecordSize;
1722  }
1723  else if( bAppendToFile )
1724  {
1725  if( nShapeId == -1 )
1726  nShapeId = psSHP->nRecords++;
1727 
1728  psSHP->panRecOffset[nShapeId] = psSHP->nFileSize;
1729  psSHP->nFileSize += nRecordSize;
1730  }
1731  psSHP->panRecSize[nShapeId] = nRecordSize-8;
1732 
1733 /* -------------------------------------------------------------------- */
1734 /* Expand file wide bounds based on this shape. */
1735 /* -------------------------------------------------------------------- */
1736  if( psSHP->adBoundsMin[0] == 0.0
1737  && psSHP->adBoundsMax[0] == 0.0
1738  && psSHP->adBoundsMin[1] == 0.0
1739  && psSHP->adBoundsMax[1] == 0.0 )
1740  {
1741  if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
1742  {
1743  psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
1744  psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
1745  psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
1746  psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
1747  }
1748  else
1749  {
1750  psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
1751  psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
1752  psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ ? psObject->padfZ[0] : 0.0;
1753  psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM ? psObject->padfM[0] : 0.0;
1754  }
1755  }
1756 
1757  for( i = 0; i < psObject->nVertices; i++ )
1758  {
1759  psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
1760  psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
1761  psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
1762  psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
1763  if( psObject->padfZ )
1764  {
1765  psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
1766  psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
1767  }
1768  if( psObject->padfM )
1769  {
1770  psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
1771  psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
1772  }
1773  }
1774 
1775  return( nShapeId );
1776 }
#define str(s)
void * malloc(YYSIZE_T)
void free(void *)
#define SHPT_ARCZ
Definition: shapefil.h:354
#define SHPT_MULTIPATCH
Definition: shapefil.h:361
#define SHPT_NULL
Definition: shapefil.h:348
#define SHPT_ARCM
Definition: shapefil.h:358
#define SHPT_POLYGONM
Definition: shapefil.h:359
#define SHPT_ARC
Definition: shapefil.h:350
#define SHPT_POLYGON
Definition: shapefil.h:351
#define DISABLE_MULTIPATCH_MEASURE
Definition: shapefil.h:207
#define SHPT_MULTIPOINT
Definition: shapefil.h:352
#define SHPT_POINTZ
Definition: shapefil.h:353
#define SHPT_MULTIPOINTZ
Definition: shapefil.h:356
#define SHPT_MULTIPOINTM
Definition: shapefil.h:360
#define SHPT_POINTM
Definition: shapefil.h:357
#define SHPT_POINT
Definition: shapefil.h:349
#define SHPT_POLYGONZ
Definition: shapefil.h:355
unsigned long SAOffset
Definition: shapefil.h:286
static int bBigEndian
Definition: shpopen.c:93
psObject nShapeId
Definition: shpopen.c:1210
unsigned int int32
Definition: shpopen.c:54
#define MIN(a, b)
Definition: shpopen.c:64
unsigned char uchar
Definition: shpopen.c:49
static void SwapWord(int length, void *wordP)
Definition: shpopen.c:110
#define STATIC_CAST(type, x)
Definition: shpopen.c:100
#define TRUE
Definition: shpopen.c:59
#define FALSE
Definition: shpopen.c:58
static void * SfRealloc(void *pMem, int nNewSize)
Definition: shpopen.c:131
static void _SHPSetBounds(uchar *pabyRec, SHPObject *psShape)
Definition: shpopen.c:1136
#define SHPLIB_NULLPTR
Definition: shpopen.c:101
#define ByteCopy(a, b, c)
Definition: shpopen.c:62
#define MAX(a, b)
Definition: shpopen.c:65
void(* Error)(const char *message)
Definition: shapefil.h:299
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition: shapefil.h:292
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
Definition: shapefil.h:293
int nShapeType
Definition: shapefil.h:320
SAFile fpSHP
Definition: shapefil.h:317
int nMaxRecords
Definition: shapefil.h:325
unsigned int * panRecSize
Definition: shapefil.h:327
SAHooks sHooks
Definition: shapefil.h:315
double adBoundsMin[4]
Definition: shapefil.h:329
int nRecords
Definition: shapefil.h:324
int bUpdated
Definition: shapefil.h:332
unsigned int nFileSize
Definition: shapefil.h:322
unsigned int * panRecOffset
Definition: shapefil.h:326
double adBoundsMax[4]
Definition: shapefil.h:330
double * padfX
Definition: shapefil.h:390
int * panPartType
Definition: shapefil.h:387
int nVertices
Definition: shapefil.h:389
double * padfY
Definition: shapefil.h:391
int nSHPType
Definition: shapefil.h:381
double dfMMax
Definition: shapefil.h:403
double * padfZ
Definition: shapefil.h:392
double dfZMax
Definition: shapefil.h:402
int * panPartStart
Definition: shapefil.h:386
double * padfM
Definition: shapefil.h:393
double dfMMin
Definition: shapefil.h:398
double dfZMin
Definition: shapefil.h:397
int bMeasureIsUsed
Definition: shapefil.h:405

References _SHPSetBounds(), SHPInfo::adBoundsMax, SHPInfo::adBoundsMin, bBigEndian, tagSHPObject::bMeasureIsUsed, SHPInfo::bUpdated, ByteCopy, tagSHPObject::dfMMax, tagSHPObject::dfMMin, tagSHPObject::dfZMax, tagSHPObject::dfZMin, DISABLE_MULTIPATCH_MEASURE, SAHooks::Error, FALSE, SHPInfo::fpSHP, free(), SAHooks::FSeek, SAHooks::FWrite, malloc(), MAX, MIN, SHPInfo::nFileSize, SHPInfo::nMaxRecords, tagSHPObject::nParts, SHPInfo::nRecords, nShapeId, SHPInfo::nShapeType, tagSHPObject::nSHPType, tagSHPObject::nVertices, tagSHPObject::padfM, tagSHPObject::padfX, tagSHPObject::padfY, tagSHPObject::padfZ, tagSHPObject::panPartStart, tagSHPObject::panPartType, SHPInfo::panRecOffset, SHPInfo::panRecSize, SfRealloc(), SHPInfo::sHooks, SHPLIB_NULLPTR, SHPT_ARC, SHPT_ARCM, SHPT_ARCZ, SHPT_MULTIPATCH, SHPT_MULTIPOINT, SHPT_MULTIPOINTM, SHPT_MULTIPOINTZ, SHPT_NULL, SHPT_POINT, SHPT_POINTM, SHPT_POINTZ, SHPT_POLYGON, SHPT_POLYGONM, SHPT_POLYGONZ, STATIC_CAST, str, SwapWord(), and TRUE.

Referenced by ShpLoaderGenerateShapeRow().

Here is the call graph for this function:
Here is the caller graph for this function: