/// <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); }