Пример #1
0
        /// <summary>See <see cref="UnwrapDateline(IGeometry)"/>.</summary>
        private static int UnwrapDateline(LineString lineString)
        {
            var cseq = lineString.CoordinateSequence;
            int size = cseq.Count;

            if (size <= 1)
            {
                return(0);
            }

            int    shiftX = 0;                                      //invariant: == shiftXPage*360
            int    shiftXPage = 0;
            int    shiftXPageMin = 0 /* <= 0 */, shiftXPageMax = 0; /* >= 0 */
            double prevX = cseq.GetX(0);

            for (int i = 1; i < size; i++)
            {
                double thisX_orig = cseq.GetX(i);
                Debug.Assert(thisX_orig >= -180 && thisX_orig <= 180);// : "X not in geo bounds";
                double thisX = thisX_orig + shiftX;
                if (prevX - thisX > 180)
                {//cross dateline from left to right
                    thisX        += 360;
                    shiftX       += 360;
                    shiftXPage   += 1;
                    shiftXPageMax = Math.Max(shiftXPageMax, shiftXPage);
                }
                else if (thisX - prevX > 180)
                {//cross dateline from right to left
                    thisX        -= 360;
                    shiftX       -= 360;
                    shiftXPage   -= 1;
                    shiftXPageMin = Math.Min(shiftXPageMin, shiftXPage);
                }
                if (shiftXPage != 0)
                {
                    cseq.SetOrdinate(i, Ordinate.X, thisX);
                }
                prevX = thisX;
            }
            if (lineString is LinearRing)
            {
                Debug.Assert(cseq.GetCoordinate(0).Equals(cseq.GetCoordinate(size - 1)));
                Debug.Assert(shiftXPage == 0);//starts and ends at 0
            }
            Debug.Assert(shiftXPageMax >= 0 && shiftXPageMin <= 0);
            //Unfortunately we are shifting again; it'd be nice to be smarter and shift once
            ShiftGeomByX(lineString, shiftXPageMin * -360);
            int crossings = shiftXPageMax - shiftXPageMin;

            if (crossings > 0)
            {
                lineString.GeometryChanged();
            }
            return(crossings);
        }