using System; using System.Collections.Generic; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.Geometries; namespace GisSharpBlog.NetTopologySuite.LinearReferencing { /// /// Builds a linear geometry ( or ) /// incrementally (point-by-point). /// public class LinearGeometryBuilder { private IGeometryFactory geomFact = null; private List lines = new List(); private CoordinateList coordList = null; private bool ignoreInvalidLines = false; private bool fixInvalidLines = false; private ICoordinate lastPt = null; /// /// /// /// public LinearGeometryBuilder(IGeometryFactory geomFact) { this.geomFact = geomFact; } /// /// Allows invalid lines to be fixed rather than causing Exceptions. /// An invalid line is one which has only one unique point. /// public bool FixInvalidLines { get { return fixInvalidLines; } set { fixInvalidLines = value; } } /// /// Allows invalid lines to be ignored rather than causing Exceptions. /// An invalid line is one which has only one unique point. /// public bool IgnoreInvalidLines { get { return ignoreInvalidLines; } set { ignoreInvalidLines = value; } } /// /// Adds a point to the current line. /// /// The to add. public void Add(ICoordinate pt) { Add(pt, true); } /// /// Adds a point to the current line. /// /// The to add. /// If true, allows the insertions of repeated points. public void Add(ICoordinate pt, bool allowRepeatedPoints) { if (coordList == null) coordList = new CoordinateList(); coordList.Add(pt, allowRepeatedPoints); lastPt = pt; } /// /// /// public ICoordinate LastCoordinate { get { return lastPt; } } /// /// Terminate the current . /// public void EndLine() { if (coordList == null) return; if (ignoreInvalidLines && coordList.Count < 2) { coordList = null; return; } ICoordinate[] rawPts = coordList.ToCoordinateArray(); ICoordinate[] pts = rawPts; if (FixInvalidLines) pts = ValidCoordinateSequence(rawPts); coordList = null; ILineString line = null; try { line = geomFact.CreateLineString(pts); } catch (ArgumentException ex) { // exception is due to too few points in line. // only propagate if not ignoring short lines if (!IgnoreInvalidLines) throw ex; } if (line != null) lines.Add(line); } /// /// /// /// /// private ICoordinate[] ValidCoordinateSequence(ICoordinate[] pts) { if (pts.Length >= 2) return pts; ICoordinate[] validPts = new ICoordinate[] { pts[0], pts[0] }; return validPts; } /// /// Builds and returns the . /// /// public IGeometry GetGeometry() { // end last line in case it was not done by user EndLine(); return geomFact.BuildGeometry(lines); } } }