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