Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting.Views/3.3/VRPSolutionView.cs @ 4185

Last change on this file since 4185 was 4185, checked in by svonolfe, 13 years ago

Improved VRP visualization (#1039)

File size: 9.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Windows.Forms;
25using HeuristicLab.Core.Views;
26using HeuristicLab.Data;
27using HeuristicLab.MainForm;
28using HeuristicLab.Problems.VehicleRouting.Encodings;
29
30namespace HeuristicLab.Problems.VehicleRouting.Views {
31  /// <summary>
32  /// The base class for visual representations of items.
33  /// </summary>
34  [View("VRPSolution View")]
35  [Content(typeof(VRPSolution), true)]
36  public sealed partial class VRPSolutionView : ItemView {
37    public new VRPSolution Content {
38      get { return (VRPSolution)base.Content; }
39      set { base.Content = value; }
40    }
41
42    /// <summary>
43    /// Initializes a new instance of <see cref="ItemBaseView"/>.
44    /// </summary>
45    public VRPSolutionView() {
46      InitializeComponent();
47
48      ToolTip tt = new ToolTip();
49      tt.SetToolTip(pictureBox, "Legend: Blue = Depot, Black = City (OK), Orange = City (too early), Red = City (too late)");
50    }
51
52    protected override void DeregisterContentEvents() {
53      Content.CoordinatesChanged -= new EventHandler(Content_CoordinatesChanged);
54      Content.SolutionChanged -= new EventHandler(Content_SolutionChanged);
55      base.DeregisterContentEvents();
56    }
57    protected override void RegisterContentEvents() {
58      base.RegisterContentEvents();
59      Content.CoordinatesChanged += new EventHandler(Content_CoordinatesChanged);
60      Content.SolutionChanged += new EventHandler(Content_SolutionChanged);
61    }
62
63    protected override void OnContentChanged() {
64      base.OnContentChanged();
65      if (Content == null) {
66        pictureBox.Image = null;
67      } else {
68        GenerateImage();
69        tourViewHost.Content = Content.Solution;
70      }
71    }
72
73    protected override void OnReadOnlyChanged() {
74      base.OnReadOnlyChanged();
75      SetEnabledStateOfControls();
76    }
77
78    protected override void SetEnabledStateOfControls() {
79      base.SetEnabledStateOfControls();
80      pictureBox.Enabled = Content != null;
81      tourGroupBox.Enabled = Content != null;
82    }
83
84    private void GenerateImage() {
85      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
86        if (Content == null) {
87          pictureBox.Image = null;
88        } else {
89          DoubleMatrix coordinates = Content.Coordinates;
90          DoubleMatrix distanceMatrix = Content.DistanceMatrix;
91          BoolValue useDistanceMatrix = Content.UseDistanceMatrix;
92          DoubleArray dueTime = Content.DueTime;
93          DoubleArray serviceTime = Content.ServiceTime;
94          DoubleArray readyTime = Content.ReadyTime;
95
96          Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
97
98          Pen[] pens = {new Pen(Color.FromArgb(92,20,237)), new Pen(Color.FromArgb(237,183,20)), new Pen(Color.FromArgb(237,20,219)), new Pen(Color.FromArgb(20,237,76)),
99                    new Pen(Color.FromArgb(237,61,20)), new Pen(Color.FromArgb(115,78,26)), new Pen(Color.FromArgb(20,237,229)), new Pen(Color.FromArgb(39,101,19)),
100                    new Pen(Color.FromArgb(230,170,229)), new Pen(Color.FromArgb(142,136,89)), new Pen(Color.FromArgb(157,217,166)), new Pen(Color.FromArgb(31,19,101)),
101                    new Pen(Color.FromArgb(173,237,20)), new Pen(Color.FromArgb(230,231,161)), new Pen(Color.FromArgb(142,89,89)), new Pen(Color.FromArgb(93,89,142)),
102                    new Pen(Color.FromArgb(146,203,217)), new Pen(Color.FromArgb(101,19,75)), new Pen(Color.FromArgb(198,20,237)), new Pen(Color.FromArgb(185,185,185)),
103                    new Pen(Color.FromArgb(179,32,32)), new Pen(Color.FromArgb(18,119,115)), new Pen(Color.FromArgb(104,158,239)), new Pen(Color.Black)};
104
105          if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) {
106            double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
107            for (int i = 0; i < coordinates.Rows; i++) {
108              if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
109              if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
110              if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
111              if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
112            }
113
114            int border = 20;
115            double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
116            double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
117
118            using (Graphics graphics = Graphics.FromImage(bitmap)) {
119              if (Content.Solution != null) {
120                int currentTour = 0;
121                foreach (Tour tour in Content.Solution.Tours) {
122                  double t = 0.0;
123                  Point[] tourPoints = new Point[tour.Cities.Count + 2];
124                  Brush[] customerBrushes = new Brush[tour.Cities.Count];
125                  int lastCustomer = 0;
126
127                  for (int i = -1; i <= tour.Cities.Count; i++) {
128                    int location = 0;
129
130                    if (i == -1 || i == tour.Cities.Count)
131                      location = 0; //depot
132                    else
133                      location = tour.Cities[i];
134
135                    Point locationPoint = new Point(border + ((int)((coordinates[location, 0] - xMin) * xStep)),
136                                    bitmap.Height - (border + ((int)((coordinates[location, 1] - yMin) * yStep))));
137                    tourPoints[i + 1] = locationPoint;
138
139                    if (i != -1 && i != tour.Cities.Count) {
140                      Brush customerBrush = Brushes.Black;
141
142                      t += VRPUtilities.GetDistance(
143                        lastCustomer, location, coordinates, distanceMatrix, useDistanceMatrix);
144
145                      if (t < readyTime[location]) {
146                        t = readyTime[location];
147                        customerBrush = Brushes.Orange;
148                      } else if (t > dueTime[location]) {
149                        customerBrush = Brushes.Red;
150                      }
151
152                      t += serviceTime[location];
153                      customerBrushes[i] = customerBrush;
154                    }
155                    lastCustomer = location;
156                  }
157
158                  graphics.DrawPolygon(pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))], tourPoints);
159
160                  for (int i = 0; i < tour.Cities.Count; i++) {
161                    graphics.FillRectangle(customerBrushes[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
162                  }
163
164                  graphics.FillEllipse(Brushes.Blue, tourPoints[0].X - 5, tourPoints[0].Y - 5, 10, 10);
165
166                  currentTour++;
167                }
168              } else {
169                Point locationPoint;
170                //just draw customers
171                for (int i = 1; i < coordinates.Rows; i++) {
172                  locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
173                                  bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
174
175                  graphics.FillRectangle(Brushes.Black, locationPoint.X - 3, locationPoint.Y - 3, 6, 6);
176                }
177
178                locationPoint = new Point(border + ((int)((coordinates[0, 0] - xMin) * xStep)),
179                                  bitmap.Height - (border + ((int)((coordinates[0, 1] - yMin) * yStep))));
180                graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10);
181              }
182            }
183          }
184
185          for (int i = 0; i < pens.Length; i++)
186            pens[i].Dispose();
187
188          pictureBox.Image = bitmap;
189        }
190      }
191    }
192
193    private void Content_CoordinatesChanged(object sender, EventArgs e) {
194      if (InvokeRequired)
195        Invoke(new EventHandler(Content_CoordinatesChanged), sender, e);
196      else
197        GenerateImage();
198    }
199    private void Content_SolutionChanged(object sender, EventArgs e) {
200      if (InvokeRequired)
201        Invoke(new EventHandler(Content_SolutionChanged), sender, e);
202      else {
203        GenerateImage();
204        tourViewHost.Content = Content.Solution;
205      }
206    }
207    private void pictureBox_SizeChanged(object sender, EventArgs e) {
208      GenerateImage();
209    }
210  }
211}
Note: See TracBrowser for help on using the repository browser.