PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ SHPRewindObject()

int SHPAPI_CALL SHPRewindObject ( CPL_UNUSED SHPHandle  hSHP,
SHPObject psObject 
)

Definition at line 2769 of file shpopen.c.

2771 {
2772  int iOpRing, bAltered = 0;
2773 
2774 /* -------------------------------------------------------------------- */
2775 /* Do nothing if this is not a polygon object. */
2776 /* -------------------------------------------------------------------- */
2777  if( psObject->nSHPType != SHPT_POLYGON
2778  && psObject->nSHPType != SHPT_POLYGONZ
2779  && psObject->nSHPType != SHPT_POLYGONM )
2780  return 0;
2781 
2782  if( psObject->nVertices == 0 || psObject->nParts == 0 )
2783  return 0;
2784 
2785 /* -------------------------------------------------------------------- */
2786 /* Process each of the rings. */
2787 /* -------------------------------------------------------------------- */
2788  for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ )
2789  {
2790  int bInner = FALSE;
2791  int iVert;
2792  double dfSum;
2793 
2794  const int nVertStart = psObject->panPartStart[iOpRing];
2795  const int nVertCount = SHPGetPartVertexCount(psObject, iOpRing);
2796 
2797  if (nVertCount < 2)
2798  continue;
2799 
2800  for( iVert = nVertStart; iVert + 1 < nVertStart + nVertCount; ++iVert )
2801  {
2802  /* Use point in the middle of segment to avoid testing
2803  * common points of rings.
2804  */
2805  const double dfTestX = ( psObject->padfX[iVert] +
2806  psObject->padfX[iVert + 1] ) / 2;
2807  const double dfTestY = ( psObject->padfY[iVert] +
2808  psObject->padfY[iVert + 1] ) / 2;
2809 
2810  bInner = SHPRewindIsInnerRing(psObject, iOpRing, dfTestX, dfTestY);
2811  if( bInner >= 0 )
2812  break;
2813  }
2814  if( bInner < 0 )
2815  {
2816  /* Completely degenerate case. Do not bother touching order. */
2817  continue;
2818  }
2819 
2820 /* -------------------------------------------------------------------- */
2821 /* Determine the current order of this ring so we will know if */
2822 /* it has to be reversed. */
2823 /* -------------------------------------------------------------------- */
2824 
2825  dfSum = psObject->padfX[nVertStart] *
2826  (psObject->padfY[nVertStart+1] -
2827  psObject->padfY[nVertStart+nVertCount-1]);
2828  for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ )
2829  {
2830  dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] -
2831  psObject->padfY[iVert-1]);
2832  }
2833 
2834  dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] -
2835  psObject->padfY[iVert-1]);
2836 
2837 /* -------------------------------------------------------------------- */
2838 /* Reverse if necessary. */
2839 /* -------------------------------------------------------------------- */
2840  if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
2841  {
2842  int i;
2843 
2844  bAltered++;
2845  for( i = 0; i < nVertCount/2; i++ )
2846  {
2847  double dfSaved;
2848 
2849  /* Swap X */
2850  dfSaved = psObject->padfX[nVertStart+i];
2851  psObject->padfX[nVertStart+i] =
2852  psObject->padfX[nVertStart+nVertCount-i-1];
2853  psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved;
2854 
2855  /* Swap Y */
2856  dfSaved = psObject->padfY[nVertStart+i];
2857  psObject->padfY[nVertStart+i] =
2858  psObject->padfY[nVertStart+nVertCount-i-1];
2859  psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved;
2860 
2861  /* Swap Z */
2862  if( psObject->padfZ )
2863  {
2864  dfSaved = psObject->padfZ[nVertStart+i];
2865  psObject->padfZ[nVertStart+i] =
2866  psObject->padfZ[nVertStart+nVertCount-i-1];
2867  psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved;
2868  }
2869 
2870  /* Swap M */
2871  if( psObject->padfM )
2872  {
2873  dfSaved = psObject->padfM[nVertStart+i];
2874  psObject->padfM[nVertStart+i] =
2875  psObject->padfM[nVertStart+nVertCount-i-1];
2876  psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved;
2877  }
2878  }
2879  }
2880  }
2881 
2882  return bAltered;
2883 }
#define SHPT_POLYGONM
Definition: shapefil.h:359
#define SHPT_POLYGON
Definition: shapefil.h:351
#define SHPT_POLYGONZ
Definition: shapefil.h:355
static int SHPGetPartVertexCount(const SHPObject *psObject, int iPart)
Definition: shpopen.c:2676
#define FALSE
Definition: shpopen.c:58
static int SHPRewindIsInnerRing(const SHPObject *psObject, int iOpRing, double dfTestX, double dfTestY)
Definition: shpopen.c:2689
double * padfX
Definition: shapefil.h:390
int nVertices
Definition: shapefil.h:389
double * padfY
Definition: shapefil.h:391
int nSHPType
Definition: shapefil.h:381
double * padfZ
Definition: shapefil.h:392
int * panPartStart
Definition: shapefil.h:386
double * padfM
Definition: shapefil.h:393

References FALSE, tagSHPObject::nParts, tagSHPObject::nSHPType, tagSHPObject::nVertices, tagSHPObject::padfM, tagSHPObject::padfX, tagSHPObject::padfY, tagSHPObject::padfZ, tagSHPObject::panPartStart, SHPGetPartVertexCount(), SHPRewindIsInnerRing(), SHPT_POLYGON, SHPT_POLYGONM, and SHPT_POLYGONZ.

Here is the call graph for this function: