PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ SHPWriteObject()

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

Definition at line 1336 of file shpopen.c.

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