/// <summary> /// 构造函数。 /// </summary> /// <param name="line">所属线路。</param> /// <param name="from">来源站点。</param> /// <param name="to">目标站点。</param> /// <exception cref="ArgumentNullException">如果from或to为空引用,则抛出该异常。</exception> public MetroLink(MetroLine line, MetroNode from, MetroNode to) { if (line == null) { throw new ArgumentNullException("line"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } m_line = line; m_from = from; m_to = to; }
/// <summary> /// 获取指定两个线路的中转站。 /// </summary> /// <param name="line1">线路1。</param> /// <param name="line2">线路2。</param> /// <returns>中转站。</returns> /// <exception cref="ArgumentNullException">如果line1或line2为空引用,则抛出该异常。</exception> public IEnumerable <MetroNode> GetTransferNodes(MetroLine line1, MetroLine line2) { if (line1 == null) { throw new ArgumentNullException("line1"); } if (line2 == null) { throw new ArgumentNullException("line2"); } if (line1 == line2) { yield break; } foreach (var node in this.Nodes.Where(c => c.Links.Count > 2 && c.Links.Exists(k => k.Line == line1) && c.Links.Exists(k => k.Line == line2))) { yield return(node); } }
/// <summary> /// 查找指定两个节点之间的最短路径。 /// </summary> /// <param name="startNode">开始节点。</param> /// <param name="endNode">结束节点。</param> /// <param name="line">目标线路(为null表示不限制线路)。</param> /// <returns>乘车路线列表。</returns> private List <MetroPath> FindShortestPaths(MetroNode startNode, MetroNode endNode, MetroLine line) { List <MetroPath> pathtList = new List <MetroPath>(); if (startNode == endNode) { return(pathtList); } //路径队列,用于遍历路径 Queue <MetroPath> pathQueue = new Queue <MetroPath>(); pathQueue.Enqueue(new MetroPath()); while (pathQueue.Count > 0) { var path = pathQueue.Dequeue(); //如果已经超过最短路径,则直接返回 if (pathtList.Count > 0 && path.Links.Count > pathtList[0].Links.Count) { continue; } //路径的最后一个节点 MetroNode prevNode = path.Links.Count > 0 ? path.Links[path.Links.Count - 1].From : null; MetroNode lastNode = path.Links.Count > 0 ? path.Links[path.Links.Count - 1].To : startNode; //继续寻找后续节点 foreach (var link in lastNode.Links.Where(c => c.To != prevNode && (line == null || c.Line == line))) { if (link.To == endNode) { MetroPath newPath = path.Append(link); if (pathtList.Count == 0 || newPath.Links.Count == pathtList[0].Links.Count) {//找到一条路径 pathtList.Add(newPath); } else if (newPath.Links.Count < pathtList[0].Links.Count) {//找到一条更短的路径 pathtList.Clear(); pathtList.Add(newPath); } else { break; //更长的路径没有意义 } } else if (!path.ContainsNode(link.To)) { pathQueue.Enqueue(path.Append(link)); } } } return(pathtList); }
private void button1_Click(object sender, EventArgs e) { if (!metroGraphView1.Graph.Nodes.Contains(textBox5.Text)) { MessageBox.Show("没有此前站点", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } if (!metroGraphView1.Graph.Nodes.Contains(textBox6.Text)) { MessageBox.Show("没有此后站点", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } if (metroGraphView1.Graph.Nodes.Contains(textBox1.Text) && metroGraphView1.Graph.Lines.Contains(numericUpDown1.Text + "号线")) { MessageBox.Show("已存在该线路中的该站点", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } MetroLine nLine; if (!metroGraphView1.Graph.Lines.Contains(numericUpDown1.Text + "号线")) { nLine = new MetroLine(); nLine.Name = numericUpDown1.Text + "号线"; nLine.Color = Color.FromArgb(new Random().Next()); metroGraphView1.Graph.Lines.Add(nLine); } else { nLine = metroGraphView1.Graph.Lines[numericUpDown1.Text + "号线"]; } MetroNode temp = new MetroNode(); temp.Name = textBox1.Text; temp.X = (metroGraphView1.Graph.Nodes[textBox5.Text].X + metroGraphView1.Graph.Nodes[textBox6.Text].X) / 2; temp.Y = (metroGraphView1.Graph.Nodes[textBox5.Text].Y + metroGraphView1.Graph.Nodes[textBox6.Text].Y) / 2; temp.Links.Add(new MetroLink(nLine, metroGraphView1.Graph.Nodes[textBox5.Text], metroGraphView1.Graph.Nodes[textBox6.Text])); metroGraphView1.Graph.Nodes[textBox5.Text].Links.Add(new MetroLink(nLine, metroGraphView1.Graph.Nodes[textBox6.Text], temp)); metroGraphView1.Graph.Nodes.Add(temp); String fileName = Application.StartupPath + "\\MetroGraph_new.xml"; if (string.IsNullOrEmpty(fileName)) { return; } XmlDocument doc = new XmlDocument(); doc.LoadXml("<?xml version=\"1.0\" encoding=\"gb2312\"?><MetroGraph/>"); var graphNode = doc.DocumentElement; metroGraphView1.AddAtrribute(graphNode, "ScrollX", metroGraphView1.ScrollX.ToString()); metroGraphView1.AddAtrribute(graphNode, "ScrollY", metroGraphView1.ScrollY.ToString()); metroGraphView1.AddAtrribute(graphNode, "ZoomScale", metroGraphView1.ZoomScale.ToString()); //线路 var linesNode = metroGraphView1.AddChildNode(graphNode, "Lines"); foreach (var line in metroGraphView1.Graph.Lines) { var lineNode = metroGraphView1.AddChildNode(linesNode, "Line"); metroGraphView1.AddAtrribute(lineNode, "Name", line.Name); metroGraphView1.AddAtrribute(lineNode, "Color", line.Color.ToArgb().ToString()); } //站点 var sitesNode = metroGraphView1.AddChildNode(graphNode, "Nodes"); foreach (var site in metroGraphView1.Graph.Nodes) { var siteNode = metroGraphView1.AddChildNode(sitesNode, "Node"); metroGraphView1.AddAtrribute(siteNode, "Name", site.Name); metroGraphView1.AddAtrribute(siteNode, "X", site.X.ToString()); metroGraphView1.AddAtrribute(siteNode, "Y", site.Y.ToString()); //路径 foreach (var link in site.Links) { var linkNode = metroGraphView1.AddChildNode(siteNode, "Link"); metroGraphView1.AddAtrribute(linkNode, "To", link.To.Name); metroGraphView1.AddAtrribute(linkNode, "Line", link.Line.Name); metroGraphView1.AddAtrribute(linkNode, "Flag", link.Flag.ToString()); metroGraphView1.AddAtrribute(linkNode, "Weight", link.Weight.ToString()); } } doc.Save(fileName); metroGraphView1.OpenFromFile(fileName); }