public void Points() { var a = new LineString(new[] { p0, p1, p2, p3 }); var points = a.Points().ToList(); Assert.AreEqual(4, points.Count); AssertCoordinates(p0, points[0]); AssertCoordinates(p1, points[1]); AssertCoordinates(p2, points[2]); AssertCoordinates(p3, points[3]); }
//http://mapcontext.com/autocarto/proceedings/auto-carto-12/pdf/computation-of-the-hausdorff-distance-between-plane.pdf public static double Distance(LineString a, LineString b) { //computation of distances from the vertices of A to polyline B (need to know specific segments) var aVertices = a.Points().ToList(); var bVertices = b.Points().ToList(); var bSegments = b.Segments().ToList(); var aSegments = a.Segments().ToList(); var closestCache = new Dictionary<IGeometry, Tuple<IGeometry, double>>(); Func<IGeometry, Tuple<IGeometry, double>> closest = p => { if(!closestCache.ContainsKey(p)) { closestCache.Add(p, ClosestGeometry(p, bVertices, bSegments)); } return closestCache[p]; }; Func<IGeometry, IGeometry, bool> pointsAreSuccessiveVertices = (cs, ce) => { var point1 = cs as IPoint; var point2 = ce as IPoint; return (point1 != null && point2 != null) && Math.Abs(bVertices.IndexOf(point1) - bVertices.IndexOf(point2)) == 1; }; var verticesWithDistance = aVertices .Select(pa => { var cst = closest(pa); return Tuple.Create(pa, cst.Item1, cst.Item2); }); var distance = verticesWithDistance.Max(tpl => tpl.Item3); //test to detect whether further calculation is required or a vertex of A bears the greatest distance from A to B var needsInvestigation = aSegments .Where(aseg => { //if we can confirm distance between segments is increasing/decreasing, no need to investigate that segment // test is that closest components for each point (segment OR vertex) are the same, or closest components are successive vertices in B var closestToStart = closest(aseg.StartPoint).Item1; var closestToEnd = closest(aseg.EndPoint).Item1; return !(closestToStart == closestToEnd || pointsAreSuccessiveVertices(closestToStart, closestToEnd)); }) .Select(aseg => { var cst = closest(aseg); return Tuple.Create(aseg, cst.Item1, cst.Item2); }) .ToList(); if(needsInvestigation.Count > 0) //check if a vertex doesn't bear the greatest distance { //and if it doesn't we need to compute the greatest distance on likely segments and reassign distance here throw new NotImplementedException(); } return distance; }