using System;
using System.Collections;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Algorithm;
using GisSharpBlog.NetTopologySuite.Geometries;
namespace GisSharpBlog.NetTopologySuite.Noding
{
///
/// Represents a list of contiguous line segments, and supports noding the segments.
/// The line segments are represented by an array of s.
/// Intended to optimize the noding of contiguous segments by
/// reducing the number of allocated objects.
/// s can carry a context object, which is useful
/// for preserving topological or parentage information.
/// All noded substrings are initialized with the same context object.
///
public class SegmentString
{
private readonly SegmentNodeList nodeList;
private readonly ICoordinate[] pts;
///
/// Creates a new segment string from a list of vertices.
///
/// The vertices of the segment string.
/// The user-defined data of this segment string (may be null).
public SegmentString(ICoordinate[] pts, Object data)
{
nodeList = new SegmentNodeList(this);
this.pts = pts;
Data = data;
}
///
/// Gets/Sets the user-defined data for this segment string.
///
public object Data { get; set; }
///
///
///
public SegmentNodeList NodeList
{
get
{
return nodeList;
}
}
///
///
///
///
public int Count
{
get
{
return pts.Length;
}
}
///
///
///
public ICoordinate[] Coordinates
{
get
{
return pts;
}
}
///
///
///
public bool IsClosed
{
get
{
return pts[0].Equals(pts[pts.Length - 1]);
}
}
///
///
///
///
///
public static IList GetNodedSubstrings(IList segStrings)
{
IList resultEdgelist = new ArrayList();
GetNodedSubstrings(segStrings, resultEdgelist);
return resultEdgelist;
}
///
///
///
///
///
public static void GetNodedSubstrings(IList segStrings, IList resultEdgelist)
{
foreach (var obj in segStrings)
{
var ss = (SegmentString) obj;
ss.NodeList.AddSplitEdges(resultEdgelist);
}
}
///
///
///
///
///
public ICoordinate GetCoordinate(int i)
{
return pts[i];
}
///
/// Gets the octant of the segment starting at vertex index.
///
///
/// The index of the vertex starting the segment.
/// Must not be the last index in the vertex list
///
/// The octant of the segment at the vertex
public Octants GetSegmentOctant(int index)
{
return index == pts.Length - 1 ?
Octants.Null :
Octant.GetOctant(GetCoordinate(index), GetCoordinate(index + 1));
}
///
/// Adds EdgeIntersections for one or both
/// intersections found for a segment of an edge to the edge intersection list.
///
///
///
///
public void AddIntersections(LineIntersector li, int segmentIndex, int geomIndex)
{
for (var i = 0; i < li.IntersectionNum; i++)
{
AddIntersection(li, segmentIndex, geomIndex, i);
}
}
///
/// Add an for intersection intIndex.
/// An intersection that falls exactly on a vertex
/// of the is normalized
/// to use the higher of the two possible segmentIndexes.
///
///
///
///
///
public void AddIntersection(LineIntersector li, int segmentIndex, int geomIndex, int intIndex)
{
ICoordinate intPt = new Coordinate(li.GetIntersection(intIndex));
AddIntersection(intPt, segmentIndex);
}
///
///
///
///
///
public void AddIntersection(ICoordinate intPt, int segmentIndex)
{
var normalizedSegmentIndex = segmentIndex;
// normalize the intersection point location
var nextSegIndex = normalizedSegmentIndex + 1;
if (nextSegIndex < pts.Length)
{
var nextPt = pts[nextSegIndex];
// Normalize segment index if intPt falls on vertex
// The check for point equality is 2D only - Z values are ignored
if (intPt.Equals2D(nextPt))
{
normalizedSegmentIndex = nextSegIndex;
}
}
// Add the intersection point to edge intersection list.
var ei = nodeList.Add(intPt, normalizedSegmentIndex);
}
}
}