//static long[] skipNodes = new long[] //{ // 1022748617, // 1022748358, // 1022774264, // 1022748183, // 1022748524, // 1022748317, // 1022748156, // 1022748462, // 1022748256, // 1022748147 //}; private static void cleanupCorners(TrafficNode[] nodes, bool remove) { foreach (var node in nodes) { if (node.Segments.Count() == 2) { var a = node.Segments.First(); var b = node.Segments.Last(); var dot = Vector3.Dot(a.Tangent, b.Tangent); if (dot > -0.5) { continue; } var otherA = a.Segment.Start == a ? a.Segment.End : a.Segment.Start; var otherB = b.Segment.Start == b ? b.Segment.End : b.Segment.Start; if ((a.Segment.Start == a) == (b.Segment.Start == b)) { continue; } Arc arc2; Arc arc1; BiarcInterpolation.Biarc(otherA, otherB, out arc1, out arc2); Arc arc1A; Arc arc2A; Arc arc1B; Arc arc2B; BiarcInterpolation.Biarc(otherA, a, out arc1A, out arc2A); BiarcInterpolation.Biarc(otherB, b, out arc1B, out arc2B); float maxDistanceSqr = 0; calcDistance(arc1A, arc1, ref maxDistanceSqr); calcDistance(arc1A, arc2, ref maxDistanceSqr); calcDistance(arc2A, arc1, ref maxDistanceSqr); calcDistance(arc2A, arc2, ref maxDistanceSqr); calcDistance(arc1B, arc1, ref maxDistanceSqr); calcDistance(arc1B, arc2, ref maxDistanceSqr); calcDistance(arc2B, arc1, ref maxDistanceSqr); calcDistance(arc2B, arc2, ref maxDistanceSqr); if (maxDistanceSqr < 1) { //if (skipNodes.Contains(node.OSMNode?.Id ?? 0)) //continue; node.Manager.MergeSegments(node); } } } }
public void Update() { var dsc = (Description as TrafficSegmentDescription); var mgr = (Manager as CanvasRoadManager); var scale = mgr.Scale; var height = mgr.Drawing.Height; Brush laneColor; if (!laneColors.TryGetValue(dsc.Type, out laneColor)) { laneColor = Brushes.White; } var start = new Point(this.Start.Node.Position.x * scale, height - this.Start.Node.Position.z * scale); var end = new Point(this.End.Node.Position.x * scale, height - this.End.Node.Position.z * scale); var layer1 = mgr.Drawing.GetLayer(DrawingLayer.Ways); var layer2 = mgr.Drawing.GetLayer(DrawingLayer.Outlines); double laneWidth = dsc.Lanes.Sum(w => w.Width); bool isDouble = !dsc.IsOneWay && dsc.Type != "rail" && dsc.Type != "tram"; var pen = new Pen(laneColor, laneWidth * scale) { StartLineCap = PenLineCap.Round, EndLineCap = PenLineCap.Round }; pen.Freeze(); Arc a1; Arc a2; //BiarcInterpolation.Biarc(p1, t1, p2, t2, out a1, out a2); BiarcInterpolation.Biarc(Start, End, out a1, out a2); var cp = a1.Interpolate(1); var center = new Point(cp.x * scale, height - cp.y * scale); var size1 = new Size(a1.radius * scale, a1.radius * scale); var size2 = new Size(a2.radius * scale, a2.radius * scale); var sweep1 = a1.IsClockwise() ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; var sweep2 = a2.IsClockwise() ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; var geometry = new StreamGeometry(); //if (dsc.OsmWay.Id == 198204219 && (End.Node as TrafficNode).OSMNode.Id == 2083678228) { { using (var context = geometry.Open()) { context.BeginFigure(start, false, false); if ((start - center).LengthSquared > 0.01) { if (Math.Abs(a1.angle) < 0.1) { context.LineTo(center, true, false); } else { context.ArcTo(center, size1, 0, a1.IsGreatArc(), sweep1, true, false); } } if ((center - end).LengthSquared > 0.01) { if (a2.radius < 0.1) { context.LineTo(end, true, false); } else { if (Math.Abs(a2.angle) < 0.1) { context.LineTo(end, true, false); } else { context.ArcTo(end, size2, 0, a1.IsGreatArc(), sweep2, true, false); } } } context.LineTo(end, true, true); } geometry.Freeze(); layer1.DrawGeometry(null, pen, geometry); if (isDouble) { var brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 0, 0, 0)); brush.Freeze(); pen = new Pen(brush, 1) { StartLineCap = PenLineCap.Round, EndLineCap = PenLineCap.Round }; pen.Freeze(); var layer3 = mgr.Drawing.GetLayer(DrawingLayer.Markers); layer3.DrawGeometry(null, pen, geometry); } } //layer1.DrawLine(new Pen(laneColor, laneWidth * scale) //{ // StartLineCap = PenLineCap.Round, // EndLineCap = PenLineCap.Round //} //, start, end); //layer2.DrawLine(new Pen(Brushes.Black, laneWidth * scale + 1) //{ // StartLineCap = PenLineCap.Round, // EndLineCap = PenLineCap.Round //}, start, end); }
private void DrawArc(DrawingContext drawingContext, float scale, double height, Pen pen, float offset) { Arc a1; Arc a2; //BiarcInterpolation.Biarc(p1, t1, p2, t2, out a1, out a2); BiarcInterpolation.Biarc(Start, End, out a1, out a2); var cp = a1.Interpolate(1, offset); var sp = a1.Interpolate(0, offset); var ep = a2.Interpolate(1, offset); var start = new Point(sp.x * scale, height - sp.y * scale); var end = new Point(ep.x * scale, height - ep.y * scale); var center = new Point(cp.x * scale, height - cp.y * scale); var r1 = Math.Max(0, a1.radius + (a1.IsClockwise() ? offset : -offset)); var r2 = Math.Max(0, a2.radius + (a2.IsClockwise() ? offset : -offset)); var size1 = new Size(r1 * scale, r1 * scale); var size2 = new Size(r2 * scale, r2 * scale); var sweep1 = a1.IsClockwise() ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; var sweep2 = a2.IsClockwise() ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; var geometry = new StreamGeometry(); using (var context = geometry.Open()) { context.BeginFigure(start, false, false); if ((start - center).LengthSquared > 0.01) { if (Math.Abs(a1.angle) < 0.1) { context.LineTo(center, true, false); } else { context.ArcTo(center, size1, 0, a1.IsGreatArc(), sweep1, true, false); } } if ((center - end).LengthSquared > 0.01) { if (a2.radius < 0.1) { context.LineTo(end, true, false); } else { if (Math.Abs(a2.angle) < 0.1) { context.LineTo(end, true, false); } else { context.ArcTo(end, size2, 0, a1.IsGreatArc(), sweep2, true, false); } } } context.LineTo(end, true, true); } geometry.Freeze(); drawingContext.DrawGeometry(null, pen, geometry); }
protected override void OnRender(DrawingContext drawingContext) { if (node == null) { return; } foreach (TrafficSegmentNodeConnection seg in node.Segments) { RenderAIPaths(drawingContext, seg.Segment.AIRoutes.SelectMany(t => t.Paths), Brushes.Red, new Pen(Brushes.Lime, 1)); RenderAIPaths(drawingContext, seg.AIRoutes.SelectMany(t => t.Paths), Brushes.Blue, null); } this.InvalidateVisual(); var Position = node?.Position ?? new UnityEngine.Vector3(0, 0, 0); var scale = manager.Scale; var height = manager.Height; var nodePoint = new Point(Position.x * scale, (height - Position.z) * scale); base.OnRender(drawingContext); int i = 0; foreach (var con in node.Segments) { i++; var r = i % 3 == 0 ? (byte)0xff : (byte)0x00; var g = i % 3 == 1 ? (byte)0xff : (byte)0x00; var b = i % 3 == 2 ? (byte)0xff : (byte)0x00; var w = con.Segment.GetWidth(); var sPen = new Pen(new SolidColorBrush(System.Windows.Media.Color.FromArgb(0x22, r, g, b)), w * scale); var point = (con.GetPosition()); var p1 = new Point(point.x * scale, (height - point.z) * scale); drawingContext.DrawLine(sPen, nodePoint, p1); } Pen pen = null; if (node.VisitedAsLine) { pen = new Pen(Brushes.Yellow, 1); } if (node.VisitedAsIntersection) { pen = new Pen(Brushes.Magenta, 1); } if (node.IsDeletionPossible) { pen = new Pen(Brushes.Red, 2); } drawingContext.DrawEllipse(node?.IsMarkedForDeletion ?? false ? Brushes.Red : Brushes.Lime, pen, nodePoint, 10, 10); drawingContext.DrawLine(new Pen(Brushes.Blue, 1), nodePoint, mouse); if (node.Segments.Count() == 2) { var a = node.Segments.First(); var b = node.Segments.Last(); var otherA = a.Segment.Start == a ? a.Segment.End : a.Segment.Start; var otherB = b.Segment.Start == b ? b.Segment.End : b.Segment.Start; var point1 = otherA.Node.Position; var nodePoint1 = new Point(point1.x * scale, (height - point1.z) * scale); var point2 = otherB.Node.Position; var nodePoint2 = new Point(point2.x * scale, (height - point2.z) * scale); Arc arc2; Arc arc1; BiarcInterpolation.Biarc(otherA, otherB, out arc1, out arc2); float snap; if (arc1.GetClosestPoint(node.Position, true, 0, out snap)) { var closestPoint = arc1.Interpolate(snap); var nodeCp = new Point(closestPoint.x * scale, (height - closestPoint.y) * scale); drawingContext.DrawLine(new Pen(Brushes.Lime, 2), nodeCp, nodePoint); } if (arc2.GetClosestPoint(node.Position, true, 0, out snap)) { var closestPoint = arc2.Interpolate(snap); var nodeCp = new Point(closestPoint.x * scale, (height - closestPoint.y) * scale); drawingContext.DrawLine(new Pen(Brushes.Magenta, 2), nodeCp, nodePoint); } drawingContext.DrawLine(new Pen(Brushes.HotPink, 2), nodePoint1, nodePoint2); } if (node != null) { foreach (var con in node.Segments) { var seg = con.Segment as TrafficSegment; var dsc = seg.Description as TrafficSegmentDescription; if (seg.End == null || seg.Start == null) { continue; } var center = (seg.Start.Node.Position + seg.End.Node.Position) / 2; var centerPoint = new Point(center.x * scale, (height - center.z) * scale); var sb = new StringBuilder(); sb.Append(dsc.Type); sb.Append(" "); sb.Append(dsc.LaneCount); if (dsc.IsOneWay) { sb.Append(" OneWay"); } sb.AppendLine(); sb.Append(dsc.Name); sb.AppendLine(); sb.Append(dsc.OsmWay?.Id?.ToString() ?? "<custom>"); sb.AppendLine(); var text = new FormattedText(sb.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 10, Brushes.Black); drawingContext.DrawText(text, centerPoint); sb = new StringBuilder(); foreach (var tag in dsc.OsmWay.Tags) { sb.Append(tag.Key); sb.Append(" = "); sb.Append(tag.Value); sb.AppendLine(); } centerPoint.Y += text.Height; drawingContext.DrawText(new FormattedText(sb.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 7.5, Brushes.Black), centerPoint); drawingContext.DrawText(new FormattedText(node.OSMNode?.Id?.ToString() ?? "<custom>", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 7.5, Brushes.Black), nodePoint); } } }