Mikael Capelle 3 years ago
parent
commit
cfb59ac0f1
37 changed files with 1511 additions and 473 deletions
  1. 2
    0
      .gitignore
  2. 28
    11
      src/main/org/insa/algo/AbstractAlgorithm.java
  3. 20
    0
      src/main/org/insa/algo/AbstractObserver.java
  4. 0
    30
      src/main/org/insa/algo/connectivity/ConnectivityAlgorithm.java
  5. 0
    16
      src/main/org/insa/algo/connectivity/ConnectivityInstance.java
  6. 0
    20
      src/main/org/insa/algo/connectivity/ConnectivitySolution.java
  7. 16
    0
      src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsAlgorithm.java
  8. 16
    0
      src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsInstance.java
  9. 29
    0
      src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsSolution.java
  10. 155
    0
      src/main/org/insa/algo/strongconnectivity/TarjanAlgorithm.java
  11. 46
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java
  12. 38
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentObserver.java
  13. 37
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentTextObserver.java
  14. 127
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java
  15. 16
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsInstance.java
  16. 29
    0
      src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsSolution.java
  17. 0
    58
      src/main/org/insa/base/Couleur.java
  18. 340
    0
      src/main/org/insa/base/MainWindow.java
  19. 0
    115
      src/main/org/insa/base/Openfile.java
  20. 0
    86
      src/main/org/insa/base/Readarg.java
  21. 0
    57
      src/main/org/insa/base/Utils.java
  22. 6
    1
      src/main/org/insa/drawing/Drawing.java
  23. 6
    0
      src/main/org/insa/drawing/DrawingInvisible.java
  24. 53
    66
      src/main/org/insa/drawing/DrawingVisible.java
  25. 6
    0
      src/main/org/insa/drawing/ZoomAndPanListener.java
  26. 97
    0
      src/main/org/insa/drawing/graph/BasicGraphPalette.java
  27. 25
    0
      src/main/org/insa/drawing/graph/BlackAndWhiteGraphPalette.java
  28. 134
    0
      src/main/org/insa/drawing/graph/GraphDrawing.java
  29. 33
    0
      src/main/org/insa/drawing/graph/GraphPalette.java
  30. 52
    0
      src/main/org/insa/drawing/graph/PathDrawing.java
  31. 1
    1
      src/main/org/insa/graph/Arc.java
  32. 12
    0
      src/main/org/insa/graph/Graph.java
  33. 14
    1
      src/main/org/insa/graph/Node.java
  34. 6
    1
      src/main/org/insa/graph/io/BinaryGraphReader.java
  35. 24
    10
      src/main/org/insa/graph/io/BinaryPathReader.java
  36. 83
    0
      src/main/org/insa/graph/io/Openfile.java
  37. 60
    0
      src/test/org/insa/graph/io/BinaryGraphReaderTest.java

+ 2
- 0
.gitignore View File

@@ -0,0 +1,2 @@
1
+.DS_Store
2
+bin

+ 28
- 11
src/main/org/insa/algo/AbstractAlgorithm.java View File

@@ -1,22 +1,40 @@
1 1
 package org.insa.algo ;
2 2
 
3
-import java.io.* ;
3
+import java.util.ArrayList;
4 4
 
5
-public abstract class AbstractAlgorithm {
5
+public abstract class AbstractAlgorithm implements Runnable {
6 6
 
7
-    protected PrintStream output;
8 7
     protected AbstractInstance instance;
9 8
     protected AbstractSolution solution;
9
+
10
+    protected ArrayList<AbstractObserver> observers;
11
+    
12
+    protected AbstractAlgorithm(AbstractInstance instance) {
13
+		this.instance = instance;
14
+		this.observers = new ArrayList<AbstractObserver>();	
15
+		this.solution = null;
16
+    }
17
+
18
+    protected AbstractAlgorithm(AbstractInstance instance, ArrayList<AbstractObserver> observers) {
19
+    		this.instance = instance;
20
+    		this.observers = observers;;	
21
+    		this.solution = null;
22
+    }
10 23
     
11 24
     /**
25
+     * Add an observer to this algorithm.
12 26
      * 
13
-     * @param instance
14
-     * @param logOutput
27
+     * @param observer
15 28
      */
16
-    protected AbstractAlgorithm(AbstractInstance instance, PrintStream logOutput) {
17
-    		this.instance = instance;
18
-    		this.output = logOutput;	
19
-    		this.solution = null;
29
+    public void addObserver(AbstractObserver observer) {
30
+    		observers.add(observer);
31
+    }
32
+    
33
+    /**
34
+     * @return The list of observers for this algorithm.
35
+     */
36
+    public ArrayList<AbstractObserver> getObservers() {
37
+    		return observers;
20 38
     }
21 39
     
22 40
     /**
@@ -44,9 +62,8 @@ public abstract class AbstractAlgorithm {
44 62
      * 
45 63
      * @return true if a feasible solution was found (even non-optimal).
46 64
      */
47
-    public boolean run() {
65
+    public void run() {
48 66
     		this.solution = this.doRun();
49
-    		return this.solution != null && this.solution.isFeasible();
50 67
     }
51 68
     
52 69
     /**

+ 20
- 0
src/main/org/insa/algo/AbstractObserver.java View File

@@ -0,0 +1,20 @@
1
+package org.insa.algo;
2
+
3
+public abstract class AbstractObserver {
4
+	
5
+	// Specify if the observer is graphic or not.
6
+	private final boolean isgraphic;
7
+	
8
+	protected AbstractObserver(boolean isGraphic) {
9
+		this.isgraphic = isGraphic;
10
+	}
11
+	
12
+	/**
13
+	 * @return true if this observer is graphic (use drawing to display
14
+	 * information).
15
+	 */
16
+	public boolean isGraphic() {
17
+		return isgraphic;
18
+	}
19
+	
20
+}

+ 0
- 30
src/main/org/insa/algo/connectivity/ConnectivityAlgorithm.java View File

@@ -1,30 +0,0 @@
1
-package org.insa.algo.connectivity ;
2
-
3
-import java.io.* ;
4
-
5
-import org.insa.algo.AbstractAlgorithm;
6
-import org.insa.algo.AbstractSolution;
7
-
8
-public class ConnectivityAlgorithm extends AbstractAlgorithm {
9
-
10
-	/**
11
-	 * 
12
-	 * @param instance
13
-	 * @param logOutput
14
-	 */
15
-	public ConnectivityAlgorithm(ConnectivityInstance instance, PrintStream logOutput) {
16
-		super(instance, logOutput);
17
-	}
18
-
19
-	/**
20
-	 * {@inheritDoc}
21
-	 */
22
-	@Override
23
-	protected AbstractSolution doRun() {
24
-		ConnectivityInstance instance = (ConnectivityInstance)getInstance();
25
-		ConnectivitySolution solution = null;
26
-		// TODO: 
27
-		return solution;
28
-	}
29
-
30
-}

+ 0
- 16
src/main/org/insa/algo/connectivity/ConnectivityInstance.java View File

@@ -1,16 +0,0 @@
1
-package org.insa.algo.connectivity;
2
-
3
-import org.insa.algo.AbstractInstance;
4
-import org.insa.graph.Graph;
5
-
6
-public class ConnectivityInstance extends AbstractInstance {
7
-
8
-	/**
9
-	 * 
10
-	 * @param graph
11
-	 */
12
-	public ConnectivityInstance(Graph graph) {
13
-		super(graph);
14
-	}
15
-
16
-}

+ 0
- 20
src/main/org/insa/algo/connectivity/ConnectivitySolution.java View File

@@ -1,20 +0,0 @@
1
-package org.insa.algo.connectivity;
2
-
3
-import java.time.Duration;
4
-
5
-import org.insa.algo.AbstractSolution;
6
-
7
-public class ConnectivitySolution extends AbstractSolution {
8
-
9
-	protected ConnectivitySolution(ConnectivityInstance instance) {
10
-		super(instance);
11
-	}
12
-	
13
-	protected ConnectivitySolution(ConnectivityInstance instance, 
14
-					   Duration solvingTime, Status status) {
15
-		super(instance, solvingTime, status);
16
-		
17
-		// TODO:
18
-	}
19
-
20
-}

+ 16
- 0
src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsAlgorithm.java View File

@@ -0,0 +1,16 @@
1
+package org.insa.algo.strongconnectivity ;
2
+
3
+import org.insa.algo.AbstractAlgorithm;
4
+
5
+public abstract class StronglyConnectedComponentsAlgorithm extends AbstractAlgorithm {
6
+
7
+	/**
8
+	 * 
9
+	 * @param instance
10
+	 * @param logOutput
11
+	 */
12
+	public StronglyConnectedComponentsAlgorithm(StronglyConnectedComponentsInstance instance) {
13
+		super(instance);
14
+	}
15
+
16
+}

+ 16
- 0
src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsInstance.java View File

@@ -0,0 +1,16 @@
1
+package org.insa.algo.strongconnectivity;
2
+
3
+import org.insa.algo.AbstractInstance;
4
+import org.insa.graph.Graph;
5
+
6
+public class StronglyConnectedComponentsInstance extends AbstractInstance {
7
+
8
+	/**
9
+	 * 
10
+	 * @param graph
11
+	 */
12
+	public StronglyConnectedComponentsInstance(Graph graph) {
13
+		super(graph);
14
+	}
15
+	
16
+}

+ 29
- 0
src/main/org/insa/algo/strongconnectivity/StronglyConnectedComponentsSolution.java View File

@@ -0,0 +1,29 @@
1
+package org.insa.algo.strongconnectivity;
2
+
3
+import java.time.Duration;
4
+import java.util.ArrayList;
5
+
6
+import org.insa.algo.AbstractSolution;
7
+import org.insa.graph.Node;
8
+
9
+public class StronglyConnectedComponentsSolution extends AbstractSolution {
10
+	
11
+	// Components
12
+	private ArrayList<ArrayList<Node>> components;
13
+
14
+	protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsInstance instance) {
15
+		super(instance);
16
+	}
17
+	
18
+	protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsInstance instance, 
19
+					   Duration solvingTime, Status status, ArrayList<ArrayList<Node>> components) {
20
+		super(instance, solvingTime, status);
21
+		this.components = components;
22
+	}
23
+	
24
+	/**
25
+	 * @return Components of the solution, if any.
26
+	 */
27
+	public ArrayList<ArrayList<Node>> getComponents() { return components; }
28
+
29
+}

+ 155
- 0
src/main/org/insa/algo/strongconnectivity/TarjanAlgorithm.java View File

@@ -0,0 +1,155 @@
1
+package org.insa.algo.strongconnectivity;
2
+
3
+import java.time.Duration;
4
+import java.time.Instant;
5
+import java.util.ArrayList;
6
+import java.util.Arrays;
7
+import java.util.Stack;
8
+
9
+import org.insa.algo.AbstractSolution;
10
+import org.insa.algo.AbstractSolution.Status;
11
+import org.insa.graph.Arc;
12
+import org.insa.graph.Graph;
13
+import org.insa.graph.Node;
14
+
15
+public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
16
+	
17
+	private final static int UNDEFINED = -1;
18
+
19
+	// Stack of nodes and flags.
20
+	private Stack<Node> stack;
21
+	private boolean[] inStack;
22
+	
23
+	// Current index.
24
+	private int index;
25
+	
26
+	// Information of nodes
27
+	private int[] indexes;
28
+	private int[] lowlink;	
29
+	
30
+	// Array of strongly connected components
31
+	ArrayList<ArrayList<Node>> components;
32
+
33
+	public TarjanAlgorithm(StronglyConnectedComponentsInstance instance) {
34
+		super(instance);
35
+	}
36
+	
37
+	/**
38
+	 * Push the given node to the stack.
39
+	 * 
40
+	 * @param node
41
+	 */
42
+	protected void pushNode(Node node) {
43
+		stack.push(node);
44
+		inStack[node.getId()] = true;
45
+	}
46
+	
47
+	/**
48
+	 * Pop and return a node from the stack.
49
+	 * 
50
+	 * @return Node popped from the stack
51
+	 */
52
+	protected Node popNode() {
53
+		Node top = stack.pop();
54
+		inStack[top.getId()] = false;
55
+		return top;
56
+	}
57
+	
58
+	/**
59
+	 * Check if the given node is in the stack.
60
+	 * 
61
+	 * @param node
62
+	 * 
63
+	 * @return true if the given node is in the stack, false otherwize.
64
+	 */
65
+	protected boolean isInStack(Node node) {
66
+		return inStack[node.getId()];
67
+	}
68
+	
69
+	/**
70
+	 * Find the strong component containing the given node.
71
+	 * 
72
+	 * @param node 
73
+	 * 
74
+	 * @return The strong component containing the given node.
75
+	 */
76
+	protected void findAndAddStrongComponent(Node v) {
77
+		Graph graph = getInstance().getGraph();
78
+		
79
+		// Update node info, index and push the node.
80
+		indexes[v.getId()] = index;
81
+		lowlink[v.getId()] = index;
82
+		index += 1;
83
+		pushNode(v);
84
+		
85
+		for (Arc a: v.getSuccessors()) {
86
+			Node w = a.getDestination();
87
+			if (!hasBeenVisited(w)) {
88
+				findAndAddStrongComponent(w);
89
+				lowlink[v.getId()] = Math.min(lowlink[v.getId()], lowlink[w.getId()]);
90
+			}
91
+			else if (isInStack(w)) {
92
+				lowlink[v.getId()] = Math.min(lowlink[v.getId()], indexes[w.getId()]);
93
+			}
94
+		}
95
+		
96
+		// Compute the component (if any)
97
+		if (lowlink[v.getId()] == indexes[v.getId()]) {
98
+			ArrayList<Node> component = new ArrayList<Node>();
99
+			Node w;
100
+			do {
101
+				w = popNode();
102
+				component.add(w);
103
+			} while (!w.equals(v));
104
+			components.add(component);
105
+			System.out.println("Size of the stack: " + stack.size());
106
+		}
107
+				
108
+	}
109
+	
110
+	/**
111
+	 * Check if the given node has not been visited yet.
112
+	 * 
113
+	 * @return true if the node has been visited.
114
+	 */
115
+	protected boolean hasBeenVisited(Node node) { 
116
+		return this.indexes[node.getId()] != UNDEFINED;
117
+	}
118
+
119
+	@Override
120
+	protected AbstractSolution doRun() {
121
+		Graph graph = getInstance().getGraph();
122
+		
123
+		components = new ArrayList<ArrayList<Node>>();
124
+		
125
+		// Starting time...
126
+		Instant start = Instant.now();
127
+		
128
+		// Initialize everything
129
+		final int nbNodes = graph.getNodes().size();
130
+		stack = new Stack<Node>();
131
+		inStack = new boolean[nbNodes];
132
+		
133
+		// Current index.
134
+		index = 0;
135
+		
136
+		// Information of nodes
137
+		indexes = new int[nbNodes];
138
+		Arrays.fill(indexes, UNDEFINED);
139
+		lowlink = new int[nbNodes];
140
+		
141
+		// Find components
142
+		for (Node node: graph.getNodes()) {
143
+			if (!hasBeenVisited(node)) {
144
+				findAndAddStrongComponent(node);
145
+			}
146
+		}
147
+
148
+		// Duration...
149
+		Duration solvingTime = Duration.between(start, Instant.now());
150
+		
151
+		return new StronglyConnectedComponentsSolution((StronglyConnectedComponentsInstance)getInstance(),
152
+					   solvingTime, Status.OPTIMAL, components);
153
+	}
154
+
155
+}

+ 46
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java View File

@@ -0,0 +1,46 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import java.awt.Color;
4
+import java.util.ArrayList;
5
+
6
+import org.insa.drawing.Drawing;
7
+import org.insa.drawing.graph.GraphDrawing;
8
+import org.insa.graph.Node;
9
+
10
+public class WeaklyConnectedComponentGraphicObserver extends WeaklyConnectedComponentObserver {
11
+	
12
+	private static final Color[] COLORS = {
13
+		Color.BLUE, Color.ORANGE, Color.GREEN, Color.YELLOW, Color.RED
14
+	};
15
+
16
+	// Drawing + Graph drawing
17
+	private Drawing drawing;
18
+	private GraphDrawing gdrawing;
19
+	
20
+	// Current index color
21
+	private int cindex = 0;
22
+	
23
+	public WeaklyConnectedComponentGraphicObserver(Drawing drawing) {
24
+		super(true);
25
+		this.drawing = drawing;
26
+		this.gdrawing = new GraphDrawing(drawing);
27
+		this.drawing.setAutoRepaint(true);
28
+	}
29
+
30
+	@Override
31
+	public void notifyStartComponent(Node curNode) {
32
+		this.drawing.setColor(COLORS[cindex]);
33
+		cindex = (cindex + 1) % COLORS.length;
34
+	}
35
+
36
+	@Override
37
+	public void notifyNewNodeInComponent(Node node) {
38
+		this.gdrawing.drawPoint(node.getPoint(), 5);
39
+		this.drawing.repaint();
40
+	}
41
+
42
+	@Override
43
+	public void notifyEndComponent(ArrayList<Node> nodes) {
44
+	}
45
+
46
+}

+ 38
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentObserver.java View File

@@ -0,0 +1,38 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import java.util.ArrayList;
4
+
5
+import org.insa.algo.AbstractObserver;
6
+import org.insa.graph.Node;
7
+
8
+public abstract class WeaklyConnectedComponentObserver extends AbstractObserver {
9
+
10
+	/**
11
+	 * {@inheritDoc}
12
+	 */
13
+	protected WeaklyConnectedComponentObserver(boolean isGraphic) {
14
+		super(isGraphic);
15
+	}
16
+	
17
+	/**
18
+	 * Notify that the algorithm is entering a new component.
19
+	 * 
20
+	 * @param curNode Starting node for the component.
21
+	 */
22
+	public abstract void notifyStartComponent(Node curNode);
23
+	
24
+	/**
25
+	 * Notify that a new node has been found for the current component.
26
+	 * 
27
+	 * @param node New node found for the current component.
28
+	 */
29
+	public abstract void notifyNewNodeInComponent(Node node);
30
+	
31
+	/**
32
+	 * Notify that the algorithm has computed a new component.
33
+	 * 
34
+	 * @param nodes List of nodes in the component.
35
+	 */
36
+	public abstract void notifyEndComponent(ArrayList<Node> nodes);
37
+
38
+}

+ 37
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentTextObserver.java View File

@@ -0,0 +1,37 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import java.io.PrintStream;
4
+import java.util.ArrayList;
5
+
6
+import org.insa.graph.Node;
7
+
8
+public class WeaklyConnectedComponentTextObserver extends WeaklyConnectedComponentObserver {
9
+	
10
+	// Number of the current component.
11
+	private int numComponent = 1;
12
+	
13
+	// Output stream
14
+	PrintStream stream;
15
+
16
+	public WeaklyConnectedComponentTextObserver(PrintStream stream) {
17
+		super(false);
18
+		this.stream = stream;
19
+	}
20
+
21
+	@Override
22
+	public void notifyStartComponent(Node curNode) {
23
+		stream.print("Entering component #" + numComponent + " from node #" + curNode.getId() + "... ");
24
+	}
25
+
26
+	@Override
27
+	public void notifyNewNodeInComponent(Node node) {
28
+	}
29
+
30
+	@Override
31
+	public void notifyEndComponent(ArrayList<Node> nodes) {
32
+		stream.println(nodes.size() + " nodes found.");
33
+		stream.flush();
34
+		numComponent += 1;
35
+	}
36
+
37
+}

+ 127
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java View File

@@ -0,0 +1,127 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import java.time.Duration;
4
+import java.time.Instant;
5
+import java.util.ArrayList;
6
+import java.util.Arrays;
7
+import java.util.Collections;
8
+import java.util.LinkedList;
9
+import java.util.Queue;
10
+import java.util.HashSet;
11
+
12
+import org.insa.algo.AbstractAlgorithm;
13
+import org.insa.algo.AbstractObserver;
14
+import org.insa.algo.AbstractSolution;
15
+import org.insa.algo.AbstractSolution.Status;
16
+import org.insa.graph.Arc;
17
+import org.insa.graph.Graph;
18
+import org.insa.graph.Node;
19
+
20
+public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
21
+
22
+	/**
23
+	 * 
24
+	 * @param instance
25
+	 * @param logOutput
26
+	 */
27
+	public WeaklyConnectedComponentsAlgorithm(WeaklyConnectedComponentsInstance instance) {
28
+		super(instance);
29
+	}
30
+	
31
+	/**
32
+	 * @return An adjacency list for the undirected graph equivalent to the stored graph.
33
+	 */
34
+	protected ArrayList<HashSet<Integer>> createUndirectedGraph() {
35
+		int nNodes = getInstance().getGraph().getNodes().size();
36
+		ArrayList<HashSet<Integer>> res = new ArrayList<HashSet<Integer>>(nNodes);
37
+		for (int i = 0; i < nNodes; ++i) {
38
+			res.add(new HashSet<Integer>());
39
+		}		
40
+		
41
+		for (Node node: getInstance().getGraph().getNodes()) {
42
+			for (Arc arc: node.getSuccessors()) {
43
+				res.get(node.getId()).add(arc.getDestination().getId());
44
+				if (arc.getInfo().isOneWay()) {
45
+					res.get(arc.getDestination().getId()).add(node.getId());
46
+				}
47
+			}
48
+		}
49
+		
50
+		return res;
51
+	}
52
+	
53
+	/**
54
+	 * Apply a breadth first search algorithm on the given undirected graph (adjacency list),
55
+	 * starting at node cur, and marking nodes in marked.
56
+	 * 
57
+	 * @param marked
58
+	 * @param cur
59
+	 * 
60
+	 * @return
61
+	 */
62
+	protected ArrayList<Node> bfs(ArrayList<HashSet<Integer>> ugraph, boolean[] marked, int cur) {
63
+		ArrayList<Node> nodes = getInstance().getGraph().getNodes();
64
+		ArrayList<Node> component = new ArrayList<Node>();
65
+		
66
+		// Using a queue because we are doing a BFS
67
+		Queue<Integer> queue = new LinkedList<Integer>();
68
+
69
+		for (AbstractObserver obs: getObservers()) {
70
+			((WeaklyConnectedComponentObserver)obs).notifyStartComponent(nodes.get(cur));
71
+		}
72
+		
73
+		// Add original node and loop until the queue is empty.
74
+		queue.add(cur);
75
+		marked[cur] = true;
76
+		while (!queue.isEmpty()) {
77
+			Node node = nodes.get(queue.remove());
78
+			component.add(node);
79
+			
80
+			// notify observers
81
+			for (AbstractObserver obs: getObservers()) ((WeaklyConnectedComponentObserver)obs).notifyNewNodeInComponent(node);
82
+			
83
+			for (Integer destId: ugraph.get(node.getId())) {
84
+				Node dest = nodes.get(destId);
85
+				if (!marked[dest.getId()]) {
86
+					queue.add(destId);
87
+					marked[destId] = true;
88
+				}
89
+			}
90
+		}
91
+		
92
+		for (AbstractObserver obs: getObservers()) {
93
+			((WeaklyConnectedComponentObserver)obs).notifyEndComponent(component);
94
+		}
95
+		
96
+		return component;
97
+	}
98
+
99
+	@Override
100
+	protected AbstractSolution doRun() {
101
+		
102
+		Instant start = Instant.now();
103
+
104
+		Graph graph = getInstance().getGraph();
105
+		ArrayList<HashSet<Integer>> ugraph = createUndirectedGraph();
106
+		boolean[] marked = new boolean[graph.getNodes().size()];
107
+		Arrays.fill(marked, false);
108
+		
109
+		ArrayList<ArrayList<Node>> components = new ArrayList<ArrayList<Node>>();
110
+		
111
+		// perform algorithm
112
+		int cur = 0;
113
+		while (cur < marked.length) {
114
+			// Apply BFS
115
+			components.add(this.bfs(ugraph, marked, cur));
116
+			
117
+			// Find next non-marked
118
+			for (; cur < marked.length && marked[cur]; ++cur);
119
+		}
120
+		
121
+		Duration solvingTime = Duration.between(start, Instant.now());
122
+		
123
+		return new WeaklyConnectedComponentsSolution((WeaklyConnectedComponentsInstance)getInstance(), 
124
+				solvingTime, Status.OPTIMAL, components);
125
+	}
126
+
127
+}

+ 16
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsInstance.java View File

@@ -0,0 +1,16 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import org.insa.algo.AbstractInstance;
4
+import org.insa.graph.Graph;
5
+
6
+public class WeaklyConnectedComponentsInstance extends AbstractInstance {
7
+
8
+	/**
9
+	 * 
10
+	 * @param graph
11
+	 */
12
+	public WeaklyConnectedComponentsInstance(Graph graph) {
13
+		super(graph);
14
+	}
15
+	
16
+}

+ 29
- 0
src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsSolution.java View File

@@ -0,0 +1,29 @@
1
+package org.insa.algo.weakconnectivity;
2
+
3
+import java.time.Duration;
4
+import java.util.ArrayList;
5
+
6
+import org.insa.algo.AbstractSolution;
7
+import org.insa.graph.Node;
8
+
9
+public class WeaklyConnectedComponentsSolution extends AbstractSolution {
10
+	
11
+	// Components
12
+	private ArrayList<ArrayList<Node>> components;
13
+
14
+	protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsInstance instance) {
15
+		super(instance);
16
+	}
17
+	
18
+	protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsInstance instance, 
19
+					   Duration solvingTime, Status status, ArrayList<ArrayList<Node>> components) {
20
+		super(instance, solvingTime, status);
21
+		this.components = components;
22
+	}
23
+	
24
+	/**
25
+	 * @return Components of the solution, if any.
26
+	 */
27
+	public ArrayList<ArrayList<Node>> getComponents() { return components; }
28
+
29
+}

+ 0
- 58
src/main/org/insa/base/Couleur.java View File

@@ -1,58 +0,0 @@
1
-package org.insa.base ;
2
-
3
-/**
4
- *   Choix des couleurs pour l'affichage.
5
- */
6
-
7
-import java.awt.* ;
8
-
9
-import org.insa.drawing.Drawing;
10
-
11
-public class Couleur {
12
-
13
-    static final Color autoroute = Color.red ;
14
-    static final Color bigroute = new Color(255, 105, 0) ;
15
-    static final Color tiroute = new Color(255, 234, 0) ;
16
-    static final Color cote = Color.blue ;
17
-
18
-    public static void set(Drawing d, char type) {
19
-
20
-	// Voir le fichier Descripteur.java pour le type des routes.
21
-	switch (type) {
22
-	case 'a':
23
-	    d.setWidth(2) ;
24
-	    d.setColor(Color.red) ;
25
-	    break ;
26
-
27
-	case 'b':
28
-	case 'c':
29
-	case 'd':
30
-	case 'e':
31
-	case 'f':
32
-	case 'g':
33
-	    d.setWidth(1) ;
34
-	    d.setColor(bigroute) ;
35
-	    break ;
36
-	case 'h':
37
-	case 'i':
38
-	case 'j':
39
-	case 'k':
40
-	case 'l':
41
-	case 'm':
42
-	case 'n':
43
-	case 'o':
44
-	    d.setWidth(1) ;
45
-	    d.setColor(tiroute) ;
46
-	    break ;
47
-	    
48
-	case 'z':
49
-	    d.setWidth(4) ;
50
-	    d.setColor(cote) ;
51
-	    break ;
52
-	    
53
-	default:
54
-	    d.setWidth(1) ;
55
-	    d.setColor(Color.black) ;
56
-	}
57
-    }
58
-}

+ 340
- 0
src/main/org/insa/base/MainWindow.java View File

@@ -0,0 +1,340 @@
1
+package org.insa.base;
2
+
3
+import java.awt.BorderLayout;
4
+import java.awt.Color;
5
+import java.awt.Dimension;
6
+import java.awt.event.ActionEvent;
7
+import java.awt.event.ActionListener;
8
+import java.awt.event.WindowAdapter;
9
+import java.awt.event.WindowEvent;
10
+import java.io.File;
11
+import java.io.IOException;
12
+import java.io.OutputStream;
13
+import java.io.PrintStream;
14
+import java.util.ArrayList;
15
+
16
+import javax.swing.BorderFactory;
17
+import javax.swing.BoxLayout;
18
+import javax.swing.JFileChooser;
19
+import javax.swing.JFrame;
20
+import javax.swing.JLabel;
21
+import javax.swing.JMenu;
22
+import javax.swing.JMenuBar;
23
+import javax.swing.JMenuItem;
24
+import javax.swing.JOptionPane;
25
+import javax.swing.JPanel;
26
+import javax.swing.JScrollPane;
27
+import javax.swing.JSplitPane;
28
+import javax.swing.JTextArea;
29
+import javax.swing.KeyStroke;
30
+import javax.swing.SwingConstants;
31
+import javax.swing.filechooser.FileNameExtensionFilter;
32
+
33
+import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
34
+import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver;
35
+import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
36
+import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsInstance;
37
+import org.insa.drawing.DrawingVisible;
38
+import org.insa.drawing.graph.BlackAndWhiteGraphPalette;
39
+import org.insa.drawing.graph.GraphDrawing;
40
+import org.insa.drawing.graph.PathDrawing;
41
+import org.insa.graph.Graph;
42
+import org.insa.graph.Path;
43
+import org.insa.graph.io.BinaryGraphReader;
44
+import org.insa.graph.io.BinaryPathReader;
45
+import org.insa.graph.io.MapMismatchException;
46
+import org.insa.graph.io.Openfile;
47
+
48
+import com.sun.glass.events.KeyEvent;
49
+
50
+public class MainWindow extends JFrame {
51
+	
52
+	public class JOutputStream extends OutputStream {
53
+	    private JTextArea textArea;
54
+
55
+	    public JOutputStream(JTextArea textArea) {
56
+	        this.textArea = textArea;
57
+	    }
58
+
59
+	    @Override
60
+	    public void write(int b) throws IOException {
61
+	        // redirects data to the text area
62
+	    		textArea.setText(textArea.getText() + String.valueOf((char)b));
63
+	        // scrolls the text area to the end of data
64
+	        textArea.setCaretPosition(textArea.getDocument().getLength());
65
+	        // keeps the textArea up to date
66
+	        textArea.update(textArea.getGraphics());
67
+	    }
68
+	}
69
+
70
+	/**
71
+	 * 
72
+	 */
73
+	private static final long serialVersionUID = -527660583705140687L;
74
+	
75
+	/**
76
+	 * 
77
+	 */
78
+	private static final String WINDOW_TITLE = "BE Graphes INSA";
79
+	
80
+	/**
81
+	 * 
82
+	 */
83
+	private static final Dimension DEFAULT_DIMENSION = new Dimension(800, 600);
84
+	
85
+	// Current graph.
86
+	private Graph graph;
87
+	
88
+	// Current loaded path.
89
+	private Path currentPath;
90
+	
91
+	// List of item for the top menus.
92
+	private JMenuItem openMapItem;
93
+	
94
+	// List of items that cannot be used without a graph
95
+	private ArrayList<JMenuItem> graphItems = new ArrayList<JMenuItem>();
96
+	
97
+	// Label containing the map ID of the current graph.
98
+	private JLabel mapIdPanel;
99
+	
100
+	// Log stream and print stream
101
+	private JOutputStream logStream;
102
+	private PrintStream printStream;
103
+	
104
+	/**
105
+	 * 
106
+	 */
107
+	private DrawingVisible drawing;
108
+	
109
+	public MainWindow() {
110
+		super(WINDOW_TITLE);
111
+		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
112
+		setLayout(new BorderLayout());
113
+		setSize(DEFAULT_DIMENSION);
114
+		setJMenuBar(createMenuBar());
115
+		
116
+		addWindowListener(new WindowAdapter() {
117
+			public void windowClosing(WindowEvent e) {
118
+				int confirmed = JOptionPane.showConfirmDialog(null, 
119
+						"Are you sure you want to close the application?", "Exit Confirmation",
120
+						JOptionPane.YES_NO_OPTION);
121
+
122
+				if (confirmed == JOptionPane.YES_OPTION) {
123
+					dispose();
124
+					System.exit(0);
125
+				}
126
+			}
127
+		});
128
+		
129
+		// Create graph area
130
+		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
131
+				
132
+		drawing = new DrawingVisible();
133
+		drawing.setBackground(Color.WHITE);
134
+		
135
+		JTextArea infoPanel = new JTextArea();
136
+		infoPanel.setMinimumSize(new Dimension(200, 50));
137
+		// infoPanel.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.GRAY));
138
+		infoPanel.setBackground(Color.WHITE);
139
+		infoPanel.setLineWrap(true);
140
+		infoPanel.setEditable(false);
141
+		this.logStream = new JOutputStream(infoPanel);
142
+		this.printStream = new PrintStream(this.logStream);
143
+		
144
+        sp.setResizeWeight(0.8);
145
+        // sp.setEnabled(false);
146
+        sp.setDividerSize(5);
147
+        
148
+        sp.setBackground(Color.WHITE);
149
+		sp.add(drawing);
150
+		sp.add(new JScrollPane(infoPanel));		
151
+		this.add(sp, BorderLayout.CENTER);
152
+				
153
+		this.add(createStatusBar(), BorderLayout.SOUTH);
154
+	}
155
+	
156
+	private JMenuBar createMenuBar() {
157
+
158
+		// Open Map item...
159
+		openMapItem = new JMenuItem("Open Map... ",
160
+		                         KeyEvent.VK_O);
161
+		openMapItem.setAccelerator(KeyStroke.getKeyStroke(
162
+		        KeyEvent.VK_O, ActionEvent.ALT_MASK));
163
+		openMapItem.addActionListener(new ActionListener() {
164
+			@Override
165
+			public void actionPerformed(ActionEvent e) {
166
+				JFileChooser chooser = new JFileChooser();
167
+			    FileNameExtensionFilter filter = new FileNameExtensionFilter(
168
+			        "Map & compressed map files", "map", "map.gz");
169
+			    chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
170
+			    chooser.setFileFilter(filter);
171
+			    if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
172
+			    		BinaryGraphReader reader;
173
+					try {
174
+						reader = new BinaryGraphReader(
175
+								Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
176
+					} catch (IOException e1) {
177
+						JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
178
+						return ;
179
+					}
180
+			    		try {
181
+			    			graph = reader.read();
182
+			    		}
183
+			    		catch (Exception exception) {
184
+						JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file.");
185
+						return ;
186
+			    		}
187
+			    		drawing.clear();
188
+			    		new GraphDrawing(drawing).drawGraph(graph);
189
+			    		
190
+			    		for (JMenuItem item: graphItems) {
191
+			    			item.setEnabled(true);
192
+			    		}
193
+			    		mapIdPanel.setText("Map ID: 0x" + Integer.toHexString(graph.getMapId()));
194
+			    }
195
+			}
196
+		});
197
+		
198
+		// Open Path item...
199
+		JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P);
200
+		openPathItem.setAccelerator(KeyStroke.getKeyStroke(
201
+		        KeyEvent.VK_P, ActionEvent.ALT_MASK));
202
+		openPathItem.addActionListener(new ActionListener() {
203
+			@Override
204
+			public void actionPerformed(ActionEvent e) {
205
+				JFileChooser chooser = new JFileChooser();
206
+			    FileNameExtensionFilter filter = new FileNameExtensionFilter(
207
+			        "Path & compressed path files", "path", "path.gz");
208
+			    chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
209
+			    chooser.setFileFilter(filter);
210
+			    if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
211
+			    		BinaryPathReader reader;
212
+					try {
213
+						reader = new BinaryPathReader(
214
+								Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
215
+					} catch (IOException e1) {
216
+						JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
217
+						return ;
218
+					}
219
+			    		try {
220
+			    			currentPath = reader.readPath(graph);
221
+			    		}
222
+			    		catch (MapMismatchException exception) {
223
+			    			JOptionPane.showMessageDialog(MainWindow.this, "The selected file does not contain a path for the current graph.");
224
+			    			return;
225
+			    		}
226
+			    		catch (Exception exception) {
227
+						JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file.");
228
+						return ;
229
+			    		}
230
+			    		new PathDrawing(drawing).drawPath(currentPath);
231
+			    }
232
+			}
233
+		});
234
+		graphItems.add(openPathItem);
235
+		
236
+		// Close item
237
+		JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q);
238
+		closeItem.setAccelerator(KeyStroke.getKeyStroke(
239
+				KeyEvent.VK_Q, ActionEvent.ALT_MASK));
240
+		closeItem.addActionListener(new ActionListener() {
241
+			@Override
242
+			public void actionPerformed(ActionEvent e) {
243
+				MainWindow.this.dispatchEvent(new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING));
244
+			}
245
+		});
246
+
247
+		//Build the first menu.
248
+		JMenu fileMenu = new JMenu("File");
249
+		fileMenu.add(openMapItem);
250
+		fileMenu.add(openPathItem);
251
+		fileMenu.addSeparator();
252
+		fileMenu.add(closeItem);
253
+		
254
+		// Second menu
255
+		JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R);
256
+		drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(
257
+				KeyEvent.VK_R, ActionEvent.ALT_MASK));
258
+		drawGraphItem.addActionListener(new ActionListener() {		
259
+			@Override
260
+			public void actionPerformed(ActionEvent e) {
261
+				drawing.clear();
262
+				drawing.setAutoRepaint(true);
263
+				new GraphDrawing(drawing).drawGraph(graph);
264
+				drawing.setAutoRepaint(false);
265
+			}
266
+		});
267
+		graphItems.add(drawGraphItem);
268
+		JMenuItem drawGraphBWItem = new JMenuItem("Redraw (B&W)", KeyEvent.VK_B);
269
+		drawGraphBWItem.setAccelerator(KeyStroke.getKeyStroke(
270
+				KeyEvent.VK_B, ActionEvent.ALT_MASK));
271
+		drawGraphBWItem.addActionListener(new ActionListener() {		
272
+			@Override
273
+			public void actionPerformed(ActionEvent e) {
274
+				drawing.clear();
275
+				drawing.setAutoRepaint(true);
276
+				new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph);
277
+				drawing.setAutoRepaint(false);
278
+			}
279
+		});
280
+		graphItems.add(drawGraphBWItem);
281
+		
282
+		JMenu graphMenu = new JMenu("Graph");
283
+		graphMenu.add(drawGraphItem);
284
+		graphMenu.add(drawGraphBWItem);
285
+		
286
+		// Algo menu
287
+		JMenu algoMenu = new JMenu("Algorithms");
288
+		
289
+		JMenuItem wccItem = new JMenuItem("Weakly Connected Components");
290
+		wccItem.addActionListener(new ActionListener() {
291
+			@Override
292
+			public void actionPerformed(ActionEvent e) {
293
+
294
+				WeaklyConnectedComponentsInstance instance = new WeaklyConnectedComponentsInstance(graph);
295
+				WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(instance);
296
+				algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
297
+				
298
+				(new Thread(algo)).start();
299
+			}
300
+		});
301
+		graphItems.add(wccItem);
302
+		
303
+		algoMenu.add(wccItem);
304
+		
305
+		// Create the menu bar.
306
+		JMenuBar menuBar = new JMenuBar();
307
+		
308
+		menuBar.add(fileMenu);
309
+		menuBar.add(graphMenu);
310
+		menuBar.add(algoMenu);
311
+
312
+		for (JMenuItem item: graphItems) {
313
+			item.setEnabled(false);
314
+		}
315
+		
316
+		return menuBar;
317
+	}
318
+	
319
+	private JPanel createStatusBar() {
320
+		// create the status bar panel and shove it down the bottom of the frame
321
+		JPanel statusPanel = new JPanel();
322
+		statusPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY));
323
+		statusPanel.setPreferredSize(new Dimension(getWidth(), 20));
324
+		statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
325
+		
326
+		mapIdPanel = new JLabel();
327
+		mapIdPanel.setHorizontalAlignment(SwingConstants.LEFT);
328
+		statusPanel.add(mapIdPanel);
329
+
330
+		return statusPanel;
331
+	}
332
+	
333
+	public static void main(final String[] args) {
334
+		MainWindow w = new MainWindow();
335
+		w.setExtendedState(JFrame.MAXIMIZED_BOTH);
336
+		w.setVisible(true);
337
+	}
338
+	
339
+
340
+}

+ 0
- 115
src/main/org/insa/base/Openfile.java View File

@@ -1,115 +0,0 @@
1
-package org.insa.base ;
2
-
3
-import java.io.* ;
4
-import java.util.zip.* ;
5
-
6
-/* Ne lisez pas cette classe. Lancez javadoc et lisez la doc generee plutot. */
7
-
8
-/**
9
- *  La classe Openfile permet de lire les fichiers contenant les cartes :
10
- *   <ul>
11
- *    <li> en trouvant le bon dossier parmi les dossiers pre-configures </li>
12
- *    <li> en dezippant automatiquement si besoin </li>
13
- *   </ul>
14
- *
15
- */
16
-public class Openfile {
17
-
18
-    // Le programme examine chaque dossier dans l'ordre jusqu'a trouver celui qui contient la carte voulue
19
-    private static final String[] datadirs = 
20
-    {  	// NE MODIFIEZ PAS CELUI-CI
21
-	// car il permet de tester en etant a l'INSA.
22
-	"/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps",
23
-
24
-	// Celui-ci pour les chemins
25
-	"/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/",
26
-
27
-        // On cherche aussi dans le sous-repertoire local "Maps" (s'il existe)
28
-	"Maps", 
29
-
30
-	// et dans le repertoire courant (Unix uniquement)
31
-	".",
32
-
33
-	// Si vous utilisez votre propre dossier pour les donnees, mettez-le ici.
34
-	"/home/votrepropredossier/a/vous",
35
-    } ;
36
-
37
-    // Extension testees. Garder l'extension vide dans la liste.
38
-    private static final String[] extensions = { ".map", ".gz", ".map.gz", ".path", ".path.gz", "" } ;
39
-
40
-    /** 
41
-     * Ouvre le fichier indiqué et renvoie un DataInputStream sur ce fichier.
42
-     * Le fichier ne sera pas ferme avant la fin de l'application.
43
-     * @param filename  Nom du fichier a ouvrir (sans chemin)
44
-     */
45
-    public static DataInputStream open (String filename) {
46
-
47
-	if (!filename.equals (new File(filename).getName())) {
48
-	    System.out.println("Le nom du fichier ne doit pas contenir un chemin (ni absolu, ni relatif).") ;
49
-	    System.out.println("Il doit juste contenir le nom du fichier contenant la carte.") ;
50
-	    System.out.println("Si vous voulez utiliser un dossier specifique, configurez base/Openfile.java") ;
51
-	    System.exit(1) ;
52
-	}
53
-
54
-	boolean trouve = false ;
55
-	InputStream fileinput = null ;
56
-	String fname = null ;
57
-	String fullpath = null ;
58
-
59
-	for (int extn = 0 ; !trouve && extn < extensions.length ; extn++) {
60
-	    fname = filename + extensions[extn] ;
61
-	    for (int index = 0 ; !trouve && index < datadirs.length ; index++) {
62
-		fullpath = datadirs[index] + File.separator + fname ;
63
-		File file = new File(fullpath) ;
64
-		if (file.canRead()) {
65
-		    trouve = true ;
66
-		    try {
67
-			fileinput = new FileInputStream(file) ;
68
-		    } catch (IOException e) {
69
-			e.printStackTrace() ;
70
-			System.exit(1) ;
71
-		    }
72
-		}
73
-	    }
74
-	}
75
-
76
-	if (!trouve) {
77
-	    // Pas trouve
78
-	    System.out.println("Impossible de trouver le fichier " + filename) ;
79
-	    System.out.println("  pourtant j'ai cherche dans les dossiers : ") ;
80
-	    int existepas = 0 ;
81
-	    for (int i = 0 ; i < datadirs.length ; i++) {
82
-		System.out.println("     - " + datadirs[i]) ;
83
-		if (!new File(datadirs[i]).isDirectory()) {
84
-		    switch (existepas) {
85
-		    case 0:  System.out.println("       (Ce dossier n'existe pas d'ailleurs)") ; break;
86
-		    case 1:  System.out.println("       (Ce dossier n'existe pas non plus)") ; break;
87
-		    default: System.out.println("       (Celui-la non plus)") ; break;
88
-		    }
89
-		    existepas++ ;
90
-		}
91
-		System.out.println() ;
92
-	    }
93
-	    System.exit(1) ;
94
-	}
95
-
96
-	System.out.println("Fichier utilisee : " + fullpath) ;
97
-	System.out.println() ;
98
-
99
-	if (fname.endsWith(".gz")) {
100
-	    // The file is gzipped.
101
-	    try {
102
-		fileinput = new GZIPInputStream(fileinput) ;
103
-	    } catch (IOException e) {
104
-		e.printStackTrace() ;
105
-		System.exit(1) ;		
106
-	    }
107
-	}
108
-	else {
109
-	    fileinput = new BufferedInputStream(fileinput) ;
110
-	}
111
-
112
-	return new DataInputStream(fileinput) ;
113
-    }
114
-
115
-}

+ 0
- 86
src/main/org/insa/base/Readarg.java View File

@@ -1,86 +0,0 @@
1
-package org.insa.base ;
2
-
3
-import java.io.* ;
4
-
5
-/* Ne lisez pas cette classe. Lancez javadoc et lisez la doc generee plutot. */
6
-
7
-/**
8
- *  La classe Readarg facilite la lecture de donnees depuis le clavier ou depuis la ligne de commande.
9
- *
10
- */
11
-public class Readarg {
12
-
13
-    private final String[] args ;
14
-    private int next ;
15
-
16
-    // Le Java est le langage prefere des Shadoks.
17
-    private final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
18
-
19
-    public Readarg(String[] argz) {
20
-	this.args = argz ;
21
-	this.next = 0 ;
22
-    }
23
-
24
-    /** 
25
-     * Obtient une chaine, ou bien depuis la ligne de commande, ou depuis l'entree standard.
26
-     * @param msg  Message affiche avant de demander la chaine
27
-     */
28
-    public String lireString (String msg) {
29
-	
30
-	String resultat = "" ;
31
-
32
-	System.out.print(msg) ;
33
-	
34
-	if (this.next >= this.args.length) {
35
-	    try {
36
-		resultat = br.readLine () ;
37
-	    } catch (Exception e) {
38
-		System.err.println ("Erreur de lecture de l'entree standard.") ;
39
-		System.exit(1) ;
40
-	    }
41
-	}
42
-	else {
43
-	    resultat = this.args[this.next] ;
44
-	    this.next++ ;
45
-	    System.out.println (resultat) ;
46
-	}
47
-
48
-	return resultat ;
49
-    }
50
-
51
-
52
-    /** 
53
-     * Obtient un entier, ou bien depuis la ligne de commande, ou depuis l'entree standard.
54
-     * @param msg  Message affiche avant de demander l'entier
55
-     */
56
-    public int lireInt (String msg) {
57
-	String lu = lireString (msg) ;
58
-	int result = 0 ;
59
-	try {
60
-	    result = Integer.parseInt(lu) ;
61
-	}
62
-	catch (Exception e) {
63
-	    System.err.println ("Un entier est attendu mais je lis " + lu) ;
64
-	    System.exit(1) ;
65
-	}
66
-	return result ;
67
-    }
68
-
69
-    /** 
70
-     * Obtient un float, ou bien depuis la ligne de commande, ou depuis l'entree standard.
71
-     * @param msg  Message affiche avant de demander le float.
72
-     */
73
-    public float lireFloat (String msg) {
74
-	String lu = lireString (msg) ;
75
-	float result = 0 ;
76
-	try {
77
-	    result = Float.parseFloat(lu) ;
78
-	}
79
-	catch (Exception e) {
80
-	    System.err.println ("Un reel est attendu mais je lis " + lu) ;
81
-	    System.exit(1) ;
82
-	}
83
-	
84
-	return result ;
85
-    }
86
-}

+ 0
- 57
src/main/org/insa/base/Utils.java View File

@@ -1,57 +0,0 @@
1
-package org.insa.base ;
2
-
3
-import java.io.* ;
4
-
5
-import org.insa.drawing.Drawing;
6
-
7
-/**
8
- *   Fonctions accessoires dont vous n'avez pas a vous servir directement.
9
- */
10
-public class Utils {
11
-
12
-
13
-	// Calibrer la sortie graphique en fonction de la carte
14
-	// Vous pouvez modifier les coordonnees pour ameliorer le rendu.
15
-	public static void calibrer(String nomCarte, Drawing dessin) {
16
-
17
-		if (nomCarte.startsWith("insa")) {
18
-			// L'INSA
19
-			dessin.setBB (1.462, 1.473, 43.567, 43.5744) ;
20
-		}
21
-		else if (nomCarte.startsWith("paris")) {
22
-			// Ile de la Cité, Paris
23
-			dessin.setBB (2.329, 2.372, 48.839, 48.867) ;
24
-		}
25
-		else if (nomCarte.startsWith("mayot")) {
26
-			// Mayotte
27
-			dessin.setBB (44.5, 45.5, -13.25, -12.25) ;
28
-		}
29
-		else if (nomCarte.startsWith("reuni")) {
30
-			// La Réunion
31
-			dessin.setBB (55.0, 56.0, -21.5, -20.5) ;
32
-		}
33
-		else if (nomCarte.startsWith("midip")) {
34
-			dessin.setBB (-0.6, 3.8, 42.2, 45.3) ;
35
-		}
36
-		else if (nomCarte.startsWith("franc")) {
37
-			dessin.setBB (-5.2, 10.0, 41.0, 51.5) ;
38
-		}
39
-		else if (nomCarte.startsWith("pfranc")) {
40
-			dessin.setBB (-5.2, 10.0, 41.0, 51.5) ;
41
-		}
42
-		else if (nomCarte.startsWith("morbihan")) {
43
-			dessin.setBB (-3.53, -2.452, 47.27, 47.665) ;
44
-		}
45
-		else if (nomCarte.startsWith("newzealand")) {
46
-			dessin.setBB (153.415, 179.912, -47.931, -33.980) ;
47
-		}
48
-		else if (nomCarte.startsWith("fract") || nomCarte.startsWith("carr")) {
49
-			dessin.setBB (-0.05, 1.05, -0.05, 1.05) ;
50
-		}
51
-		else {
52
-			dessin.setBB (-20.0, 50.0, 20.0, 70.0) ;
53
-		}
54
-	}
55
-
56
-
57
-}

+ 6
- 1
src/main/org/insa/drawing/Drawing.java View File

@@ -37,10 +37,15 @@ public interface Drawing {
37 37
     /**
38 38
      * Set the pencil color.
39 39
      * 
40
-     * param color Color for the pencil.
40
+     * @param color Color for the pencil.
41 41
      * 
42 42
      */
43 43
     public void setColor(Color col);
44
+    
45
+    /**
46
+     * Clear the drawing.
47
+     */
48
+	public void clear();
44 49
 
45 50
     /**
46 51
      *  Indique les bornes de la fenetre graphique.

+ 6
- 0
src/main/org/insa/drawing/DrawingInvisible.java View File

@@ -34,5 +34,11 @@ public class DrawingInvisible implements Drawing {
34 34
 
35 35
 	@Override
36 36
 	public void repaint() { }
37
+
38
+	@Override
39
+	public void clear() {
40
+		// TODO Auto-generated method stub
41
+		
42
+	}
37 43
     
38 44
 }

+ 53
- 66
src/main/org/insa/drawing/DrawingVisible.java View File

@@ -1,28 +1,35 @@
1 1
 package org.insa.drawing;
2 2
 
3
-import java.awt.*;
3
+import java.awt.BasicStroke;
4
+import java.awt.Color;
5
+import java.awt.Graphics;
6
+import java.awt.Graphics2D;
7
+import java.awt.Image;
4 8
 import java.awt.image.*;
5 9
 
10
+import javax.swing.JPanel;
11
+
6 12
 /**
7 13
  *   Cette implementation de la classe Dessin produit vraiment un affichage
8 14
  *   (au contraire de la classe DessinInvisible).
9 15
  */
10 16
 
11
-public class DrawingVisible extends Canvas implements Drawing {
17
+public class DrawingVisible extends JPanel implements Drawing {
12 18
 
13 19
 	/**
14 20
 	 * 
15 21
 	 */
16 22
 	private static final long serialVersionUID = 96779785877771827L;
17
-
23
+	
18 24
 	private final Graphics2D gr;
19 25
 
20 26
 	private float long1;
21 27
 	private float long2;
22 28
 	private float lat1;
23 29
 	private float lat2;
24
-	private final float width;
25
-	private final float height;
30
+	
31
+	// Width and height of the image
32
+	private final int width, height;
26 33
 
27 34
 	private boolean bb_is_set ;
28 35
 	
@@ -34,15 +41,18 @@ public class DrawingVisible extends Canvas implements Drawing {
34 41
 	/**
35 42
 	 *  Cree et affiche une nouvelle fenetre de dessin.
36 43
 	 */
37
-	public DrawingVisible (int largeur, int hauteur) {
44
+	public DrawingVisible() {
38 45
 		super();
39 46
 		
40
-		this.zoomAndPanListener = new ZoomAndPanListener(this, 0, ZoomAndPanListener.DEFAULT_MAX_ZOOM_LEVEL, 1.2);
47
+		this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
41 48
 		this.addMouseListener(zoomAndPanListener);
42 49
 		this.addMouseMotionListener(zoomAndPanListener);
43 50
 		this.addMouseWheelListener(zoomAndPanListener);
44 51
 		
45
-		BufferedImage img = new BufferedImage (largeur, hauteur, BufferedImage.TYPE_3BYTE_BGR);
52
+		this.width = 2000;
53
+		this.height = 1600;
54
+		
55
+		BufferedImage img = new BufferedImage (this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
46 56
 		
47 57
 		this.image = img;
48 58
 		this.gr = img.createGraphics();
@@ -51,40 +61,24 @@ public class DrawingVisible extends Canvas implements Drawing {
51 61
 		
52 62
 		this.bb_is_set = false;
53 63
 
54
-		this.width = largeur;
55
-		this.height = hauteur;
56 64
 
57
-		this.long1 = (float)0.0;
58
-		this.long2 = (float)largeur;
59
-		this.lat1  = (float)0.0;
60
-		this.lat2  = (float)hauteur;
65
+		this.long1 = 0.0f;
66
+		this.long2 = this.width;
67
+		this.lat1  = 0.0f;
68
+		this.lat2  = this.height;
61 69
 
62
-		this.setColor(Color.white);
63
-		gr.fillRect(0,0, largeur, hauteur);
70
+		this.clear();
64 71
 		this.repaint();
65 72
 
66 73
 	}
67 74
 
68 75
 	@Override
69
-	public void paint(Graphics g1) {
76
+	public void paintComponent(Graphics g1) {
70 77
 		Graphics2D g = (Graphics2D)g1;
71 78
 		g.setTransform(zoomAndPanListener.getCoordTransform());
72 79
 		g.drawImage(image, 0, 0, this);
73 80
 	}
74 81
 	
75
-
76
-	@Override
77
-	public Dimension getPreferredSize() {
78
-		Dimension size = new Dimension(0, 0);
79
-
80
-		if (image != null) {
81
-			int w = image.getWidth(null);
82
-			int h = image.getHeight(null);
83
-			size = new Dimension(w > 0 ? w : 0, h > 0 ? h : 0);
84
-		}
85
-		return size;
86
-	}
87
-	
88 82
 	@Override
89 83
 	public void setAutoRepaint(boolean autoRepaint) {
90 84
 		this.autoRepaint = autoRepaint;
@@ -96,48 +90,41 @@ public class DrawingVisible extends Canvas implements Drawing {
96 90
 		}
97 91
 	}
98 92
 	
99
-	public void setWidth (int width) {
93
+	public void setWidth(int width) {
100 94
 		this.gr.setStroke(new BasicStroke(width));
101 95
 	}
102 96
 
103
-	public void setColor (Color col) {
104
-		this.gr.setColor (col);
97
+	public void setColor(Color col) {
98
+		this.gr.setColor(col);
99
+	}
100
+
101
+	public void clear() {
102
+		this.gr.setColor(Color.WHITE);
103
+		this.gr.fillRect(0, 0, this.width, this.height);
105 104
 	}
106 105
 
107
-	public void setBB (double long1, double long2, double lat1, double lat2) {	
106
+	public void setBB(double long1, double long2, double lat1, double lat2) {	
108 107
 
109 108
 		if (long1 > long2 || lat1 > lat2) {
110 109
 			throw new Error("DessinVisible.setBB : mauvaises coordonnees.");
111 110
 		}
112
-
113
-		/* Adapte la BB en fonction de la taille du dessin, pour préserver le ratio largeur/hauteur */
114
-		double deltalong = long2 - long1 ;
115
-		double deltalat = lat2 - lat1 ;
116
-		double ratiobb = deltalong / deltalat ;
117
-		double ratiogr = width / height ;
118
-
119
-		/* On ne peut qu'agrandir la BB, pour ne rien perdre. 
120
-		 * Si le ratiobb est trop petit, il faut agrandir deltalong 
121
-		 * s'il est trop grand, il faut agrandir deltalat. */
122
-		if (ratiobb < ratiogr) {
123
-			/* De combien faut-il agrandir ? */
124
-			double delta = (ratiogr - ratiobb) * deltalat ;
125
-
126
-			this.long1 = (float)(long1 - 0.5*delta) ;
127
-			this.long2 = (float)(long2 + 0.5*delta) ;
128
-			this.lat1 = (float)lat1 ;
129
-			this.lat2 = (float)lat2 ;
130
-		}
131
-		else {
132
-			double delta = (deltalong / ratiogr) - deltalat ;
133
-
134
-			this.long1 = (float)long1 ;
135
-			this.long2 = (float)long2 ;
136
-			this.lat1 = (float)(lat1 - 0.5*delta);
137
-			this.lat2 = (float)(lat2 + 0.5*delta);
138
-		}
139
-
140
-		this.bb_is_set = true ;
111
+		
112
+		this.long1 = (float)long1;
113
+		this.long2 = (float)long2;
114
+		this.lat1= (float)lat1;
115
+		this.lat2 = (float)lat2;
116
+		
117
+		this.bb_is_set = true;
118
+		
119
+		double scale = 1 / Math.max(this.width / (double)this.getWidth(),  this.height / (double)this.getHeight());
120
+		
121
+		this.zoomAndPanListener.getCoordTransform().setToIdentity();
122
+		this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2, 
123
+				(this.getHeight() - this.height * scale) / 2);
124
+		this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
125
+		this.zoomAndPanListener.setZoomLevel(0);
126
+		this.repaint();
127
+		
141 128
 	}
142 129
 
143 130
 	private int projx(float lon) {
@@ -154,7 +141,7 @@ public class DrawingVisible extends Canvas implements Drawing {
154 141
 		}
155 142
 	}
156 143
 
157
-	public void drawLine (float long1, float lat1, float long2, float lat2) {
144
+	public void drawLine(float long1, float lat1, float long2, float lat2) {
158 145
 		this.checkBB() ;
159 146
 		int x1 = this.projx(long1) ;
160 147
 		int x2 = this.projx(long2) ;
@@ -165,7 +152,7 @@ public class DrawingVisible extends Canvas implements Drawing {
165 152
 		this.doAutoPaint();
166 153
 	}
167 154
 
168
-	public void drawPoint (float lon, float lat, int width) {
155
+	public void drawPoint(float lon, float lat, int width) {
169 156
 		this.checkBB() ;
170 157
 		int x = this.projx(lon) - width / 2 ;
171 158
 		int y = this.projy(lat) - width / 2 ;
@@ -173,7 +160,7 @@ public class DrawingVisible extends Canvas implements Drawing {
173 160
 		this.doAutoPaint();
174 161
 	}
175 162
 
176
-	public void putText (float lon, float lat, String txt) {
163
+	public void putText(float lon, float lat, String txt) {
177 164
 		this.checkBB() ;
178 165
 		int x = this.projx(lon) ;
179 166
 		int y = this.projy(lat) ;

+ 6
- 0
src/main/org/insa/drawing/ZoomAndPanListener.java View File

@@ -1,4 +1,5 @@
1 1
 package org.insa.drawing;
2
+
2 3
 import java.awt.*;
3 4
 import java.awt.event.*;
4 5
 import java.awt.geom.AffineTransform;
@@ -31,6 +32,11 @@ public class ZoomAndPanListener implements MouseListener, MouseMotionListener, M
31 32
 		this.maxZoomLevel = maxZoomLevel;
32 33
 		this.zoomMultiplicationFactor = zoomMultiplicationFactor;
33 34
 	}
35
+	
36
+	public void translate(double dx, double dy) {
37
+		coordTransform.translate(dx, dy);
38
+		targetComponent.repaint();
39
+	}
34 40
 
35 41
 
36 42
 	public void mouseClicked(MouseEvent e) {

+ 97
- 0
src/main/org/insa/drawing/graph/BasicGraphPalette.java View File

@@ -0,0 +1,97 @@
1
+package org.insa.drawing.graph;
2
+
3
+import java.awt.Color;
4
+
5
+import org.insa.graph.RoadInformation.RoadType;
6
+
7
+public class BasicGraphPalette implements GraphPalette {
8
+	
9
+	// Color types for arc.
10
+    static final Color motorway = Color.RED;
11
+    static final Color bigroad = new Color(255, 105, 0);
12
+    static final Color smallroad = new Color(255, 234, 0);
13
+    static final Color coastline = Color.BLUE;
14
+    
15
+    // Default point width
16
+    static final int DEFAULT_POINT_WIDTH = 1;
17
+    
18
+    /**
19
+     * 
20
+     */
21
+    public BasicGraphPalette() { }
22
+    
23
+	@Override
24
+	public int getDefaultPointWidth() {
25
+		return 2;
26
+	}
27
+
28
+	@Override
29
+	public Color getDefaultPointColor() {
30
+		return Color.GREEN;
31
+	}
32
+
33
+	@Override
34
+	public Color getColorForType(RoadType type) {
35
+		Color color = Color.BLACK;
36
+		switch (type) {
37
+			case MOTORWAY: 
38
+				color = motorway;
39
+				break;
40
+			case TRUNK:
41
+			case PRIMARY:
42
+			case SECONDARY:
43
+			case MOTORWAY_LINK:
44
+			case TRUNK_LINK:
45
+			case PRIMARY_LINK:
46
+				color = bigroad;
47
+				break;
48
+			case SECONDARY_LINK:
49
+			case TERTIARY:
50
+			case RESIDENTIAL:
51
+			case UNCLASSIFIED:
52
+			case ROAD:
53
+			case LIVING_STREET:
54
+			case SERVICE:
55
+			case ROUNDABOUT:
56
+				color = smallroad;
57
+				break;
58
+			case COASTLINE:
59
+				color = coastline;
60
+				break;
61
+		}
62
+		return color;
63
+	}
64
+
65
+	@Override
66
+	public int getWidthForType(RoadType type) {
67
+		int width = 1;
68
+		switch (type) {
69
+			case MOTORWAY: 
70
+				width = 2;
71
+				break;
72
+			case TRUNK:
73
+			case PRIMARY:
74
+			case SECONDARY:
75
+			case MOTORWAY_LINK:
76
+			case TRUNK_LINK:
77
+			case PRIMARY_LINK:
78
+				width = 1;
79
+				break;
80
+			case SECONDARY_LINK:
81
+			case TERTIARY:
82
+			case RESIDENTIAL:
83
+			case UNCLASSIFIED:
84
+			case ROAD:
85
+			case LIVING_STREET:
86
+			case SERVICE:
87
+			case ROUNDABOUT:
88
+				width = 1;
89
+				break;
90
+			case COASTLINE:
91
+				width = 4;
92
+				break;
93
+		}
94
+		return width;
95
+	}
96
+	
97
+}

+ 25
- 0
src/main/org/insa/drawing/graph/BlackAndWhiteGraphPalette.java View File

@@ -0,0 +1,25 @@
1
+package org.insa.drawing.graph;
2
+
3
+import java.awt.Color;
4
+
5
+import org.insa.graph.RoadInformation.RoadType;
6
+
7
+public class BlackAndWhiteGraphPalette extends BasicGraphPalette {
8
+	
9
+	// Road colors (index
10
+	private final static Color[] ROAD_COLOR_FROM_WIDTH = {
11
+		null, new Color(140, 140, 140), new Color(80, 80, 80), new Color(40, 40, 40), new Color(30, 30, 30)
12
+	};
13
+
14
+	@Override
15
+	public Color getDefaultPointColor() {
16
+		return Color.BLACK;
17
+	}
18
+
19
+	@Override
20
+	public Color getColorForType(RoadType type) {
21
+		int width = getWidthForType(type);
22
+		return ROAD_COLOR_FROM_WIDTH[width];
23
+	}
24
+
25
+}

+ 134
- 0
src/main/org/insa/drawing/graph/GraphDrawing.java View File

@@ -0,0 +1,134 @@
1
+package org.insa.drawing.graph;
2
+
3
+import java.awt.Color;
4
+import java.util.ArrayList;
5
+import java.util.Iterator;
6
+
7
+import org.insa.drawing.Drawing;
8
+import org.insa.graph.Arc;
9
+import org.insa.graph.Graph;
10
+import org.insa.graph.Node;
11
+import org.insa.graph.Point;
12
+import org.insa.graph.RoadInformation.RoadType;
13
+
14
+public class GraphDrawing {
15
+
16
+	// Drawing
17
+	private Drawing drawing;
18
+
19
+	// Palette
20
+	private GraphPalette palette;
21
+	
22
+	public GraphDrawing(Drawing drawing) {
23
+		this.drawing = drawing;
24
+		this.palette = new BasicGraphPalette();
25
+	}
26
+	
27
+	public GraphDrawing(Drawing drawing, GraphPalette palette) {
28
+		this.drawing = drawing;
29
+		this.palette = palette;
30
+	}
31
+
32
+	public void drawLine(Point p1, Point p2) {
33
+		drawing.drawLine(p1.getLongitude(), p1.getLatitude(), 
34
+				p2.getLongitude(), p2.getLatitude());
35
+	}
36
+	
37
+	public void drawPoint(Point p) {
38
+		drawPoint(p, palette.getDefaultPointWidth());
39
+	}
40
+	
41
+	public void drawPoint(Point p, int width) {
42
+		drawing.drawPoint(p.getLongitude(), p.getLatitude(), width);
43
+	}
44
+	
45
+	public void drawPoint(Point p, int width, Color c) {
46
+		drawing.setColor(c);
47
+		drawing.drawPoint(p.getLongitude(), p.getLatitude(), width);
48
+	}
49
+
50
+	/**
51
+	 * Draw the given arc with automatic color and width depending
52
+	 * on the road type.
53
+	 * 
54
+	 * @param arc Arc to draw.
55
+	 */
56
+	public void drawArc(Arc arc) {
57
+		drawArc(arc, true);
58
+	}
59
+	
60
+	/**
61
+	 * Draw the given arc.
62
+	 * 
63
+	 * @param arc Arc to draw.
64
+	 * @param autoColorAndWidth Set to true to set color and width based
65
+	 * on the road type of the arc.
66
+	 */
67
+	public void drawArc(Arc arc, boolean autoColorAndWidth) {
68
+		ArrayList<Point> pts = arc.getPoints();
69
+		if (!pts.isEmpty()) {
70
+			if (autoColorAndWidth) {
71
+				drawing.setColor(palette.getColorForType(arc.getInfo().getType()));
72
+				drawing.setWidth(palette.getWidthForType(arc.getInfo().getType()));
73
+			}
74
+			Iterator<Point> it1 = pts.iterator();
75
+			Point prev = it1.next();
76
+			while (it1.hasNext()) {
77
+				Point curr = it1.next();
78
+				drawLine(prev, curr);
79
+				prev = curr;
80
+			}
81
+		}
82
+	}
83
+	
84
+	/**
85
+	 * Initialize the drawing for the given graph.
86
+	 * 
87
+	 * @param graph
88
+	 */
89
+	public void initialize(Graph graph) {
90
+		double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, 
91
+				maxLon = Double.NEGATIVE_INFINITY, maxLat = Double.NEGATIVE_INFINITY;
92
+		for (Node node: graph.getNodes()) {
93
+			Point pt = node.getPoint();
94
+			if (pt.getLatitude() < minLat) {
95
+				minLat = pt.getLatitude();
96
+			}
97
+			if (pt.getLatitude() > maxLat) {
98
+				maxLat = pt.getLatitude();
99
+			}
100
+			if (pt.getLongitude() < minLon) {
101
+				minLon = pt.getLongitude();
102
+			}
103
+			if (pt.getLongitude() > maxLon) {
104
+				maxLon = pt.getLongitude();
105
+			}
106
+		}
107
+		
108
+		double deltaLon = 0.02 * (maxLon - minLon),
109
+				deltaLat = 0.02 * (maxLat - minLat);
110
+
111
+		drawing.setBB(minLon - deltaLon, maxLon + deltaLon, 
112
+				minLat - deltaLat, maxLat + deltaLat);
113
+	}
114
+
115
+	
116
+	/**
117
+	 * Clear the drawing and draw the given graph on the drawing.
118
+	 * 
119
+	 * @param graph Graph to draw.
120
+	 */
121
+	public void drawGraph(Graph graph) {
122
+
123
+		drawing.clear();
124
+		
125
+		initialize(graph);
126
+
127
+		for (Node node: graph.getNodes()) {
128
+			for (Arc arc: node.getSuccessors()) {
129
+				drawArc(arc);
130
+			}
131
+		}
132
+	}
133
+
134
+}

+ 33
- 0
src/main/org/insa/drawing/graph/GraphPalette.java View File

@@ -0,0 +1,33 @@
1
+package org.insa.drawing.graph;
2
+
3
+import java.awt.Color;
4
+
5
+import org.insa.graph.RoadInformation.RoadType;
6
+
7
+public interface GraphPalette {
8
+	
9
+	/**
10
+	 * @return The default point width for this palette.
11
+	 */
12
+	public int getDefaultPointWidth();
13
+	
14
+	/**
15
+	 * @return The default point color for this palette.
16
+	 */
17
+	public Color getDefaultPointColor();
18
+	
19
+	/**
20
+	 * @param type Type of the road.
21
+	 * 
22
+	 * @return Color associated to the given type of road.
23
+	 */
24
+	public Color getColorForType(RoadType type);
25
+
26
+	/**
27
+	 * @param type Type of the road.
28
+	 * 
29
+	 * @return Width associated to the given type of road.
30
+	 */
31
+	public int getWidthForType(RoadType type);
32
+
33
+}

+ 52
- 0
src/main/org/insa/drawing/graph/PathDrawing.java View File

@@ -0,0 +1,52 @@
1
+package org.insa.drawing.graph;
2
+
3
+import java.awt.Color;
4
+
5
+import org.insa.drawing.Drawing;
6
+import org.insa.graph.Arc;
7
+import org.insa.graph.Path;
8
+
9
+public class PathDrawing {
10
+	
11
+	// Default color
12
+	public static final Color DEFAULT_PATH_COLOR = new Color(255, 0, 255);
13
+	
14
+	// Drawing
15
+	private Drawing drawing;
16
+	private GraphDrawing graphDrawing;
17
+	
18
+	/**
19
+	 * @param drawing
20
+	 */
21
+	public PathDrawing(Drawing drawing) {
22
+		this.drawing = drawing;
23
+		this.graphDrawing = new GraphDrawing(drawing);
24
+	}
25
+	
26
+	/**
27
+	 * Draw the given path with the given color.
28
+	 * 
29
+	 * @param path
30
+	 * @param color
31
+	 */
32
+	public void drawPath(Path path, Color color) {
33
+		this.graphDrawing.drawPoint(path.getFirstNode().getPoint(), 4, color);
34
+		this.drawing.setColor(color);
35
+		this.drawing.setWidth(2);
36
+		for (Arc arc: path.getArcs()) {
37
+			this.graphDrawing.drawArc(arc, false);
38
+		}
39
+		this.graphDrawing.drawPoint(path.getLastNode().getPoint(), 4, color);
40
+	}
41
+	
42
+	/**
43
+	 * Draw the given path with default color.
44
+	 * 
45
+	 * @param path
46
+	 */
47
+	public void drawPath(Path path) {
48
+		drawPath(path, DEFAULT_PATH_COLOR);
49
+		drawing.repaint();
50
+	}
51
+
52
+}

+ 1
- 1
src/main/org/insa/graph/Arc.java View File

@@ -45,7 +45,7 @@ public class Arc {
45 45
 	/**
46 46
 	 * @return Destination node of this arc.
47 47
 	 */
48
-	public Node getDest() {
48
+	public Node getDestination() {
49 49
 		return dest;
50 50
 	}
51 51
 

+ 12
- 0
src/main/org/insa/graph/Graph.java View File

@@ -10,6 +10,10 @@ public class Graph {
10 10
 	// Nodes of the graph.
11 11
 	private ArrayList<Node> nodes;
12 12
 
13
+	/**
14
+	 * @param mapId
15
+	 * @param nodes
16
+	 */
13 17
 	public Graph(int mapId, ArrayList<Node> nodes) {
14 18
 		this.mapId = mapId;
15 19
 		this.nodes = nodes;
@@ -24,5 +28,13 @@ public class Graph {
24 28
 	 * @return Map ID of this graph.
25 29
 	 */
26 30
 	public int getMapId() { return mapId; }
31
+	
32
+	/**
33
+	 * @return Return the transpose graph of this graph.
34
+	 */
35
+	public Graph transpose() {
36
+		// TODO: 
37
+		return null;
38
+	}
27 39
 
28 40
 }

+ 14
- 1
src/main/org/insa/graph/Node.java View File

@@ -2,7 +2,7 @@ package org.insa.graph;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 
5
-public class Node {
5
+public class Node implements Comparable<Node> {
6 6
 
7 7
 	// ID of the node.
8 8
 	private int id;
@@ -49,4 +49,17 @@ public class Node {
49 49
 	 */
50 50
 	public Point getPoint() { return point; }
51 51
 	
52
+	@Override
53
+	public boolean equals(Object other) {
54
+		if (other instanceof Node) {
55
+			return getId() == ((Node) other).getId();
56
+		}
57
+		return false;
58
+	}
59
+
60
+	@Override
61
+	public int compareTo(Node other) {
62
+		return Integer.compare(getId(), other.getId());
63
+	}
64
+	
52 65
 }

+ 6
- 1
src/main/org/insa/graph/io/BinaryGraphReader.java View File

@@ -3,6 +3,9 @@ package org.insa.graph.io;
3 3
 import java.io.DataInputStream;
4 4
 import java.io.IOException;
5 5
 import java.util.ArrayList;
6
+import java.util.Collections;
7
+
8
+import javax.sound.midi.ControllerEventListener;
6 9
 
7 10
 import org.insa.graph.Arc;
8 11
 import org.insa.graph.Graph;
@@ -149,7 +152,9 @@ public class BinaryGraphReader extends BinaryReader implements AbstractGraphRead
149 152
 					// And reverse arc if its a two-way road.
150 153
 					if (!info.isOneWay()) {
151 154
 						// Add without segments.
152
-						dest.addSuccessor(new Arc(orig, length, info));
155
+						ArrayList<Point> rPoints = new ArrayList<Point>(points);
156
+						Collections.reverse(rPoints);
157
+						dest.addSuccessor(new Arc(orig, length, info, rPoints));
153 158
 					}
154 159
 					
155 160
 				}

+ 24
- 10
src/main/org/insa/graph/io/BinaryPathReader.java View File

@@ -4,6 +4,7 @@ import java.io.DataInputStream;
4 4
 import java.io.IOException;
5 5
 import java.util.ArrayList;
6 6
 
7
+import org.insa.graph.Arc;
7 8
 import org.insa.graph.Graph;
8 9
 import org.insa.graph.Node;
9 10
 import org.insa.graph.Path;
@@ -35,23 +36,36 @@ public class BinaryPathReader extends BinaryReader implements AbstractPathReader
35 36
 		// Number of nodes in the path (without first and last).
36 37
 		int nbNodes = dis.readInt();
37 38
 		
38
-		ArrayList<Node> nodes = new ArrayList<Node>(nbNodes + 2);
39
+		ArrayList<Arc> arcs = new ArrayList<Arc>();
39 40
 		
40
-		// Read first node
41
-		nodes.add(readNode(graph));
42
-		
43
-		// Read last node
44
-		Node lastNode = readNode(graph);
41
+		// Skip (duplicate) first and last node
42
+		readNode(graph);
43
+		readNode(graph);
45 44
 		
46 45
 		// Read intermediate nodes:
47
-		for (int node = 0; node < nbNodes; ++node) {
46
+		ArrayList<Node> nodes = new ArrayList<Node>();
47
+		for (int i = 0; i < nbNodes; ++i) {
48 48
 			nodes.add(readNode(graph));
49 49
 		}
50 50
 		
51
-		// Add last node
52
-		nodes.add(lastNode);
51
+		Node current = nodes.get(0);
52
+		for (int i = 1; i < nodes.size(); ++i) {
53
+			Node node = nodes.get(i);
54
+			Arc minArc = null;
55
+			for (Arc arc: current.getSuccessors()) {
56
+				if (arc.getDestination().equals(node)
57
+					&& (minArc == null || arc.getMinimumTravelTime() < minArc.getMinimumTravelTime())) {
58
+					minArc = arc;
59
+				}
60
+			}
61
+			arcs.add(minArc);
62
+			if (minArc == null) {
63
+				System.out.println("No arc found between nodes " + current.getId() + " and " + node.getId() + "\n");
64
+			}
65
+			current = node;
66
+		}
53 67
 		
54
-		return new Path(graph, nodes);
68
+		return new Path(graph, nodes.get(0), arcs);
55 69
 	}
56 70
 
57 71
 	/**

+ 83
- 0
src/main/org/insa/graph/io/Openfile.java View File

@@ -0,0 +1,83 @@
1
+package org.insa.graph.io ;
2
+
3
+import java.io.* ;
4
+import java.util.zip.* ;
5
+
6
+/**
7
+ *  Class that can be used to open (compressed) files from a specified
8
+ *  set of folders or for a full path.
9
+ *  
10
+ */
11
+public class Openfile {
12
+
13
+	/**
14
+	 * These folders will be looked up for the files.
15
+	 * 
16
+	 */
17
+	private static final String[] datadirs = {
18
+			
19
+		// INSA folder containing maps.
20
+		"/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps",
21
+
22
+		// INSA folder containing paths.
23
+		"/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/",
24
+
25
+		// Maps sub-folder.
26
+		"Maps", 
27
+		
28
+		// Current folder.
29
+		"."
30
+	};
31
+
32
+	/**
33
+	 * Available extensions.
34
+	 * 
35
+	 */
36
+	private static final String[] extensions = { ".map", ".gz", ".map.gz", ".path", ".path.gz", "" };
37
+
38
+	/** 
39
+	 * Open the given file and return a corresponding DataInputStream.
40
+	 * 
41
+	 * @param filename Name of the file to open (without extension) or full path to the given file.
42
+	 * @throws IOException 
43
+	 */
44
+	public static DataInputStream open(String filename) throws IOException {
45
+
46
+		File file = null;
47
+		String fullpath = null;
48
+		
49
+		// If the filename containing only a name (not a path):
50
+		if (filename.equals (new File(filename).getName())) {
51
+
52
+	
53
+			for (String ext: extensions) {
54
+				String fname = filename + ext;
55
+				for (int index = 0; file == null && index < datadirs.length; ++index) {
56
+					fullpath = datadirs[index] + File.separator + fname;
57
+					file = new File(fullpath);
58
+					if (!file.exists()) {
59
+						file = null;
60
+					}
61
+				}
62
+			}
63
+			
64
+		}
65
+		else {
66
+			fullpath = filename;
67
+			file = new File(filename);
68
+		}
69
+			
70
+		InputStream fileInput = new FileInputStream(new File(fullpath));
71
+
72
+		// If the file is compressed.
73
+		if (fullpath.endsWith(".gz")) {
74
+			fileInput = new GZIPInputStream(fileInput) ;
75
+		}
76
+		else {
77
+			fileInput = new BufferedInputStream(fileInput) ;
78
+		}
79
+
80
+		return new DataInputStream(fileInput) ;
81
+	}
82
+
83
+}

+ 60
- 0
src/test/org/insa/graph/io/BinaryGraphReaderTest.java View File

@@ -0,0 +1,60 @@
1
+package org.insa.graph.io;
2
+
3
+import static org.junit.jupiter.api.Assertions.assertEquals;
4
+import static org.junit.jupiter.api.Assertions.fail;
5
+
6
+import java.io.IOException;
7
+import java.util.ArrayList;
8
+
9
+import org.insa.graph.Graph;
10
+import org.insa.graph.Node;
11
+import org.insa.graph.Point;
12
+import org.junit.jupiter.api.AfterAll;
13
+import org.junit.jupiter.api.AfterEach;
14
+import org.junit.jupiter.api.BeforeAll;
15
+import org.junit.jupiter.api.BeforeEach;
16
+import org.junit.jupiter.api.Disabled;
17
+import org.junit.jupiter.api.Test;
18
+import org.junit.jupiter.params.ParameterizedTest;
19
+import org.junit.jupiter.params.provider.MethodSource;
20
+
21
+public class BinaryGraphReaderTest {
22
+	
23
+	// Epsilon for latitude and longitude.
24
+	private static final double EPS = 1e-5;
25
+	
26
+	private static Graph midip;
27
+
28
+	@BeforeAll
29
+    static void initAll() throws IOException {
30
+		BinaryGraphReader reader = new BinaryGraphReader(Openfile.open("midip"));
31
+		midip = reader.read();
32
+    }
33
+	
34
+	void assertPointAt(Point p1, double longitude, double latitude) {
35
+		assertEquals(p1.getLongitude(), longitude, EPS);
36
+		assertEquals(p1.getLatitude(), latitude, EPS);
37
+	}
38
+
39
+    @Test
40
+    void testMidipNodes() {
41
+    		ArrayList<Node> nodes = midip.getNodes();
42
+    	
43
+    		assertEquals(nodes.size(), 150827);
44
+    		
45
+    		// Check the locations of some nodes.
46
+    		assertPointAt(nodes.get(58411).getPoint(), 1.799864, 43.92864);
47
+    		assertPointAt(nodes.get(133312).getPoint(), 0.539752, 43.317505);
48
+    		assertPointAt(nodes.get(113688).getPoint(), 1.682739, 44.799774);
49
+    		assertPointAt(nodes.get(118141).getPoint(), 0.274857, 43.47475);
50
+    		assertPointAt(nodes.get(146918).getPoint(), 0.116148, 43.811386);
51
+
52
+    }
53
+    
54
+    @Test
55
+    void testMidipArcs() {
56
+    		// TODO: Check the number of edges.
57
+    		// TODO: Check information for some edges.
58
+    }
59
+    
60
+}

Loading…
Cancel
Save