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

◆ 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
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: