PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ SHPRewindObject()

int SHPAPI_CALL SHPRewindObject ( CPL_UNUSED SHPHandle  hSHP,
SHPObject psObject 
)

Definition at line 2767 of file shpopen.c.

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