using System.Collections; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.GeometriesGraph; namespace GisSharpBlog.NetTopologySuite.Index.Chain { /// /// A MonotoneChainBuilder implements static functions /// to determine the monotone chains in a sequence of points. /// public class MonotoneChainBuilder { /// /// Only static methods! /// private MonotoneChainBuilder() {} /// /// /// /// /// public static int[] ToIntArray(IList list) { int[] array = new int[list.Count]; for (int i = 0; i < array.Length; i++) { array[i] = (int) list[i]; } return array; } /// /// /// /// /// public static IList GetChains(ICoordinate[] pts) { return GetChains(pts, null); } /// /// Return a list of the MonotoneChains /// for the given list of coordinates. /// /// /// public static IList GetChains(ICoordinate[] pts, object context) { IList mcList = new ArrayList(); int[] startIndex = GetChainStartIndices(pts); for (int i = 0; i < startIndex.Length - 1; i++) { MonotoneChain mc = new MonotoneChain(pts, startIndex[i], startIndex[i + 1], context); mcList.Add(mc); } return mcList; } /// /// Return an array containing lists of start/end indexes of the monotone chains /// for the given list of coordinates. /// The last entry in the array points to the end point of the point array, /// for use as a sentinel. /// /// public static int[] GetChainStartIndices(ICoordinate[] pts) { // find the startpoint (and endpoints) of all monotone chains in this edge int start = 0; IList startIndexList = new ArrayList(); startIndexList.Add(start); do { int last = FindChainEnd(pts, start); startIndexList.Add(last); start = last; } while (start < pts.Length - 1); // copy list to an array of ints, for efficiency int[] startIndex = ToIntArray(startIndexList); return startIndex; } /// /// /// /// /// /// /// The index of the last point in the monotone chain starting at start. /// private static int FindChainEnd(ICoordinate[] pts, int start) { // determine quadrant for chain int chainQuad = QuadrantOp.Quadrant(pts[start], pts[start + 1]); int last = start + 1; while (last < pts.Length) { // compute quadrant for next possible segment in chain int quad = QuadrantOp.Quadrant(pts[last - 1], pts[last]); if (quad != chainQuad) { break; } last++; } return last - 1; } } }