PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ SHPRewindObject()

int SHPAPI_CALL SHPRewindObject ( CPL_UNUSED SHPHandle  hSHP,
SHPObject psObject 
)

Definition at line 2778 of file shpopen.c.

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