Преглед изворни кода

Merged dominik into jascha

dominik пре 8 година
родитељ
комит
49e911bc6a

+ 8 - 1
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/main/MainWindow.fxml

@@ -130,8 +130,15 @@
                                           <SwingNode fx:id="swingNode" />
                                        </children>
                                     </Pane>
-                                    <Button fx:id="zoomIn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="+" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="45.0" AnchorPane.rightAnchor="10.0" />
+                                     <Button fx:id="zoomIn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="+" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="45.0" AnchorPane.rightAnchor="10.0" />
                                     <Button fx:id="zoomOut" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="-" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0" />
+                                    <Button fx:id="centerMap" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="O" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="45.0" />
+                                    <Button fx:id="defaultMapView" layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="D" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" />
+                                    <Button fx:id="roadMapView" layoutX="20.0" layoutY="20.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="R" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="45.0" />
+                                    <Button fx:id="satelliteMapView" layoutX="30.0" layoutY="30.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="S" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="80.0" />
+                                    <Button fx:id="hybridMapView" layoutX="40.0" layoutY="40.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="H" textAlignment="JUSTIFY" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="115.0" />
+                                    <Button fx:id="nextWaypoint" layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="&gt;" textAlignment="JUSTIFY" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" />
+                                    <Button fx:id="previousWaypoint" layoutX="20.0" layoutY="20.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="&lt;" textAlignment="JUSTIFY" AnchorPane.rightAnchor="45.0" AnchorPane.topAnchor="10.0" />
                                  </children>
                               </AnchorPane>
                             <AnchorPane SplitPane.resizableWithParent="false">

+ 68 - 20
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/ButtonManager.java

@@ -2,13 +2,16 @@ package de.tu_darmstadt.informatik.tk.scopviz.ui;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashSet;
 
 import org.graphstream.graph.implementations.Graphs;
+import org.jxmapviewer.viewer.GeoPosition;
 import org.jxmapviewer.viewer.WaypointPainter;
 
 import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.CustomMapClickListener;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.CustomWaypoint;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.CustomWaypointRenderer;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.MapViewFunctions;
@@ -83,6 +86,18 @@ public final class ButtonManager {
 			Main.getInstance().getGraphManager().zoomOut();
 		}
 	}
+	
+	/**
+	 * Handler for center map Button
+	 * @param event
+	 */
+	public static void centerMapAction(ActionEvent event) {
+		HashSet<GeoPosition> positions = new HashSet<GeoPosition>(WorldView.waypoints.size());
+		WorldView.waypoints.forEach((w) -> positions.add(w.getPosition()));
+		
+		WorldView.showAllWaypoints(positions);
+		
+	}
 
 	/**
 	 * After switching from symbol-layer to other layer show toolbox and make
@@ -116,10 +131,22 @@ public final class ButtonManager {
 			// make graph non mouse transparent
 			controller.pane.setMouseTransparent(false);
 			controller.swingNode.setMouseTransparent(false);
-
-			// deselect graph element
+			
+			// dont show symbol layer Button
+			controller.centerMap.setVisible(false);
+			controller.defaultMapView.setVisible(false);
+			controller.roadMapView.setVisible(false);
+			controller.satelliteMapView.setVisible(false);
+			controller.hybridMapView.setVisible(false);
+			controller.previousWaypoint.setVisible(false);
+			controller.nextWaypoint.setVisible(false);
+			
+			// dont show properties of selected node or edge
 			PropertiesManager.showNewDataSet(null);
 
+			// deselect current selected node or edge
+			CustomMapClickListener.deselectAll();
+			
 			// reset loaded images
 			MapViewFunctions.resetImageMap();
 
@@ -226,30 +253,21 @@ public final class ButtonManager {
 		Main.getInstance().getGraphManager().deselectEdgeCreationNodes();
 		
 		if (!(GraphDisplayManager.getCurrentLayer().equals(Layer.SYMBOL))) {
-
+			//TODO check if needed
+/*
 			// add a copy of the underlay graph to the the symbol layer
 			MyGraph gClone = (MyGraph) Graphs.clone(GraphDisplayManager.getGraphManager(Layer.UNDERLAY).getGraph());
 			gClone.removeAttribute("layer");
 			GraphDisplayManager.setCurrentLayer(Layer.SYMBOL);
 			GraphDisplayManager.addGraph(gClone, true);
+*/
 			controller.topLeftAPane.getChildren().add(controller.symbolToolVBox);
 		}
 
-		try {
-			// load world view
-			activateWorldView();
-
-		} catch (IOException e) {
-
-			// problems with Internet connection, maybe host not reachable,
-			// maybe no Internet connection at all
-			GraphDisplayManager.switchActiveGraph();
-			setBorderStyle((Button) arg0.getSource());
-
-			// show "Connection Error" message
+		// load world view 
+		if(!activateWorldView()){
+			// show "Connection Error" message, because of problems during connecting attempt to server
 			showConnectionErrorMsg();
-
-			return;
 		}
 
 		// hide metricbox/update button
@@ -289,7 +307,7 @@ public final class ButtonManager {
 	 * 
 	 * @throws IOException
 	 */
-	private static void activateWorldView() throws IOException {
+	private static boolean activateWorldView() {
 
 		// dont show graph and toolbox
 		controller.toolbox.setVisible(false);
@@ -308,8 +326,27 @@ public final class ButtonManager {
 
 		// show VBox for map options
 		controller.symbolToolVBox.setVisible(true);
-
-		WorldView.loadWorldView();
+		
+		// show symbol layer Button
+		controller.centerMap.setVisible(true);
+		controller.defaultMapView.setVisible(true);
+		controller.roadMapView.setVisible(true);
+		controller.satelliteMapView.setVisible(true);
+		controller.hybridMapView.setVisible(true);
+		controller.previousWaypoint.setVisible(true);
+		controller.nextWaypoint.setVisible(true);
+
+		// standard server connection status is true
+		Boolean serverConnection = true;
+		
+		try {
+			
+			WorldView.loadWorldView();
+		} catch (IOException e) {
+			// problems with server connection -> show error message
+			serverConnection = false;
+		}
+		
 
 		MapViewFunctions.checkVBoxChanged();
 
@@ -318,6 +355,8 @@ public final class ButtonManager {
 		// set content to UI Element
 		controller.swingNodeWorldView.setContent(WorldView.internMapViewer);
 		controller.swingNodeWorldView.setVisible(true);
+		
+		return serverConnection;
 	}
 
 	/**
@@ -428,4 +467,13 @@ public final class ButtonManager {
 		MapViewFunctions.changeMapView();
 	}
 
+	/**
+	 * select the given MapType in the ChoiceBox and change Map View
+	 * @param mapType
+	 */
+	public static void switchToMap(String mapType) {
+		controller.mapViewChoiceBox.getSelectionModel().select(mapType);
+		MapViewFunctions.changeMapView();
+	}
+
 }

+ 61 - 1
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/GUIController.java

@@ -16,6 +16,7 @@ import org.jxmapviewer.input.ZoomMouseWheelListenerCursor;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.handlers.KeyboardShortcuts;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.handlers.ResizeListener;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.MapViewFunctions;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.WorldView;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
@@ -69,6 +70,22 @@ public class GUIController implements Initializable {
 	public Button zoomIn;
 	@FXML
 	public Button zoomOut;
+	@FXML
+	public Button centerMap;
+
+	@FXML
+	public Button defaultMapView;
+	@FXML
+	public Button roadMapView;
+	@FXML
+	public Button satelliteMapView;
+	@FXML
+	public Button hybridMapView;
+
+	@FXML
+	public Button previousWaypoint;
+	@FXML
+	public Button nextWaypoint;
 
 	@FXML
 	public Button underlayButton;
@@ -192,6 +209,7 @@ public class GUIController implements Initializable {
 
 		// Bind all the handlers to their corresponding UI elements
 		initializeZoomButtons();
+		initializeSymbolLayerButtons();
 		initializeLayerButton();
 		initializeMenuBar();
 		initializeSymbolRepToolbox();
@@ -229,6 +247,10 @@ public class GUIController implements Initializable {
 		stackPane.widthProperty().addListener(new ResizeListener(swingNode, stackPane));
 
 		swingNodeWorldView.setVisible(false);
+
+		// bind a context menu to the swing node
+		swingNodeWorldView.setOnContextMenuRequested((event) -> MapViewFunctions.contextMenuRequest(event));
+
 	}
 
 	/**
@@ -260,6 +282,32 @@ public class GUIController implements Initializable {
 		zoomOut.setOnAction((event) -> ButtonManager.zoomOutAction(event));
 	}
 
+	/**
+	 * Sets the handlers for the Button that are shown in the symbol layer
+	 */
+	private void initializeSymbolLayerButtons() {
+
+		centerMap.setOnAction((event) -> ButtonManager.centerMapAction(event));
+
+		defaultMapView.setOnAction((event) -> ButtonManager.switchToMap("Default"));
+		roadMapView.setOnAction((event) -> ButtonManager.switchToMap("Road"));
+		satelliteMapView.setOnAction((event) -> ButtonManager.switchToMap("Satellite"));
+		hybridMapView.setOnAction((event) -> ButtonManager.switchToMap("Hybrid"));
+
+		previousWaypoint.setOnAction((event) -> MapViewFunctions.switchToPreviousWaypoint());
+		nextWaypoint.setOnAction((event) -> MapViewFunctions.switchToNextWaypoint());
+
+		centerMap.setVisible(false);
+
+		defaultMapView.setVisible(false);
+		roadMapView.setVisible(false);
+		satelliteMapView.setVisible(false);
+		hybridMapView.setVisible(false);
+
+		previousWaypoint.setVisible(false);
+		nextWaypoint.setVisible(false);
+	}
+
 	/**
 	 * Initializes the special Toolbox for the Symbol Representation Layer.
 	 */
@@ -340,10 +388,13 @@ public class GUIController implements Initializable {
 
 		toolbox.getColumns().setAll(toolboxObjectColumn, toolboxStringColumn);
 
+		toolbox.getSelectionModel().selectedItemProperty()
+				.addListener((ov, oldVal, newVal) -> ToolboxManager.selectedItemChanged(ov, oldVal, newVal));
+
 		// Click event for TableView row
 		toolbox.setRowFactory(tv -> {
 			TableRow<Pair<Object, String>> row = new TableRow<>();
-			row.setOnMouseClicked(ToolboxManager.rowClickedHandler);
+			row.setOnMouseClicked((event) -> ToolboxManager.rowClickedHandler(event));
 			return row;
 		});
 
@@ -450,6 +501,15 @@ public class GUIController implements Initializable {
 
 		assert zoomIn != null : "fx:id=\"zoomIn\" was not injected: check your FXML file 'MainWindow.fxml'.";
 		assert zoomOut != null : "fx:id=\"zoomOut\" was not injected: check your FXML file 'MainWindow.fxml'.";
+		assert centerMap != null : "fx:id=\"centerMap\" was not injected: check your FXML file 'MainWindow.fxml'.";
+
+		assert defaultMapView != null : "fx:id=\"defaultMapView\" was not injected: check your FXML file 'MainWindow.fxml'.";
+		assert roadMapView != null : "fx:id=\"roadMapView\" was not injected: check your FXML file 'MainWindow.fxml'.";
+		assert satelliteMapView != null : "fx:id=\"satelliteMapView\" was not injected: check your FXML file 'MainWindow.fxml'.";
+		assert hybridMapView != null : "fx:id=\"hybridMapView\" was not injected: check your FXML file 'MainWindow.fxml'.";
+
+		assert previousWaypoint != null : "fx:id=\"previousWaypoint\" was not injected: check your FXML file 'MainWindow.fxml'.";
+		assert nextWaypoint != null : "fx:id=\"nextWaypoint\" was not injected: check your FXML file 'MainWindow.fxml'.";
 
 		assert underlayButton != null : "fx:id=\"underlayButton\" was not injected: check your FXML file 'MainWindow.fxml'.";
 		assert operatorButton != null : "fx:id=\"operatorButton\" was not injected: check your FXML file 'MainWindow.fxml'.";

+ 75 - 0
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/OptionsManager.java

@@ -3,6 +3,10 @@ package de.tu_darmstadt.informatik.tk.scopviz.ui;
 import java.util.ArrayList;
 import java.util.Arrays;
 
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.CustomWaypointRenderer;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.EdgePainter;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.MapViewFunctions;
+import de.tu_darmstadt.informatik.tk.scopviz.ui.mapView.WorldView;
 import javafx.application.Platform;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
@@ -73,6 +77,32 @@ public final class OptionsManager {
 
 		TextField defaultLatitudeField = new TextField(Double.toString(defaultLat));
 		TextField defaultLongitudeField = new TextField(Double.toString(defaultLong));
+		
+		
+		// Symbol Layer options
+		ChoiceBox<String> edgeSelectedColorSymbolLayer = new ChoiceBox<String>();
+		edgeSelectedColorSymbolLayer.setItems(FXCollections.observableArrayList("Red", "Black", "Blue", "Green", "Yellow", "Orange", "Gray"));
+		edgeSelectedColorSymbolLayer.getSelectionModel().select(EdgePainter.getClickedColor());
+		
+		ChoiceBox<String> edgePlacementColorSymbolLayer = new ChoiceBox<String>();
+		edgePlacementColorSymbolLayer.setItems(FXCollections.observableArrayList("Blue", "Black", "Red", "Green", "Yellow", "Orange", "Gray"));
+		edgePlacementColorSymbolLayer.getSelectionModel().select(EdgePainter.getPlacementColor());
+		
+		ChoiceBox<String> edgeStandardColorSymbolLayer = new ChoiceBox<String>();
+		edgeStandardColorSymbolLayer.setItems(FXCollections.observableArrayList("Black", "Red", "Blue", "Green", "Yellow", "Orange", "Gray"));
+		edgeStandardColorSymbolLayer.getSelectionModel().select(EdgePainter.getStandardColor());
+		
+		ChoiceBox<String> waypointStandardColorSymbolLayer = new ChoiceBox<String>();
+		waypointStandardColorSymbolLayer.setItems(FXCollections.observableArrayList("Black", "Red", "Blue", "Green", "Yellow", "Orange", "Gray"));
+		waypointStandardColorSymbolLayer.getSelectionModel().select(CustomWaypointRenderer.getStandardColor());
+		
+		ChoiceBox<String> waypointSelectedColorSymbolLayer = new ChoiceBox<String>();
+		waypointSelectedColorSymbolLayer.setItems(FXCollections.observableArrayList("Red", "Black", "Blue", "Green", "Yellow", "Orange", "Gray"));
+		waypointSelectedColorSymbolLayer.getSelectionModel().select(CustomWaypointRenderer.getClickedColor());
+		
+		TextField edgeThickness = new TextField(Integer.toString(EdgePainter.getThickness()));
+		
+		TextField waypointSize = new TextField(Integer.toString(CustomWaypointRenderer.getWaypointSize()));
 
 		// position elements on grid
 		int row = 0;
@@ -97,6 +127,32 @@ public final class OptionsManager {
 		grid.add(new Label("Longitude:"), 0, row);
 		grid.add(defaultLongitudeField, 1, row);
 		row++;
+		
+		// symbol layer stuff
+		grid.add(new Label(""), 1, row); row++;
+		grid.add(new Label("Symbol-Layer Options"), 1, row); row++;
+		grid.add(new Label("Waypoint Size (int):"), 0, row);
+		grid.add(waypointSize, 1, row); row++;
+		
+		grid.add(new Label("Edge thickness (int):"), 0, row);
+		grid.add(edgeThickness, 1, row); row++;
+		
+		grid.add(new Label("Edge Colors"), 1, row); row++;
+		grid.add(new Label("Standard Edge Color"), 0, row);
+		grid.add(edgeStandardColorSymbolLayer, 1, row); row++;
+		
+		grid.add(new Label("Clicked Edge Color"), 0, row);
+		grid.add(edgeSelectedColorSymbolLayer, 1, row); row++;
+		
+		grid.add(new Label("Placement Edge Color"), 0, row);
+		grid.add(edgePlacementColorSymbolLayer, 1, row); row++;
+		
+		grid.add(new Label("Waypoint Colors"), 1, row); row++;
+		grid.add(new Label("Standard Waypoint Color"), 0, row);
+		grid.add(waypointStandardColorSymbolLayer, 1, row); row++;
+		
+		grid.add(new Label("Clicked Waypoint Color"), 0, row);
+		grid.add(waypointSelectedColorSymbolLayer, 1, row);
 
 		// set dialog
 		addPropDialog.getDialogPane().setContent(grid);
@@ -114,10 +170,29 @@ public final class OptionsManager {
 						defaultLat = Double.parseDouble(defaultLatitudeField.getText());
 						defaultLong = Double.parseDouble(defaultLongitudeField.getText());
 					}
+					
+					// symbol layer edge thickness
+					if(Integer.parseInt(edgeThickness.getText()) != EdgePainter.getThickness()) {
+						EdgePainter.setEdgeThickness(Integer.parseInt(edgeThickness.getText()));
+					}
+					// symbol layer waypoint size
+					if(Integer.parseInt(waypointSize.getText()) != CustomWaypointRenderer.getWaypointSize()) {
+						CustomWaypointRenderer.setScaleSize(Integer.parseInt(waypointSize.getText()));
+						MapViewFunctions.resetImageMap();
+						MapViewFunctions.initializeWaypointImages();
+					}
+					
 				} catch (NumberFormatException e) {
 				}
 				showWeight = showWeightButton.isSelected();
 				StylesheetManager.adjustNodeGraphics(nodeGraphicsSelector.getValue());
+				
+				// color types of waypoints and edges
+				EdgePainter.setColor(edgeStandardColorSymbolLayer.getValue(), edgePlacementColorSymbolLayer.getValue(), edgeSelectedColorSymbolLayer.getValue());
+				CustomWaypointRenderer.setColor(waypointStandardColorSymbolLayer.getValue(), waypointSelectedColorSymbolLayer.getValue());
+				
+				WorldView.internMapViewer.repaint();
+				
 				return null;
 			} else
 				return null;

+ 85 - 44
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/ToolboxManager.java

@@ -40,6 +40,12 @@ public final class ToolboxManager {
 	 */
 	private static GUIController controller;
 
+	/**
+	 * needed, so that MouseClickedEvent is not fired, when SelectionProperty
+	 * was changed
+	 */
+	private static boolean selectedPropertyChanged = false;
+
 	/**
 	 * private constructor to prevent Instantiation.
 	 */
@@ -128,69 +134,104 @@ public final class ToolboxManager {
 		controller.toolbox.getItems().setAll(data);
 
 	}
-
+	
 	/**
-	 * Handler for TableRows
+	 * fired when the selected item in the Toolbox was changed
+	 * 
+	 * @param ov
+	 * @param oldVal
+	 *            the previous selected item
+	 * @param newVal
+	 *            the new selected item
 	 */
-	public static final EventHandler<MouseEvent> rowClickedHandler = new EventHandler<MouseEvent>() {
+	public static void selectedItemChanged(ObservableValue<? extends Pair<Object, String>> ov,
+			Pair<Object, String> oldVal, Pair<Object, String> newVal) {
 
-		@SuppressWarnings("unchecked")
-		@Override
-		public void handle(MouseEvent event) {
+		if (newVal != null) {
 
-			// Get the clicked TableRow
-			Node node = ((Node) event.getTarget()).getParent();
-			TableRow<Pair<Object, String>> row;
+			// change creation mode based on selected item
+			String rowString = newVal.getValue();
 
-			if (node instanceof TableRow) {
-				row = (TableRow<Pair<Object, String>>) node;
-			} else if (node.getParent() instanceof TableRow) {
-				// clicking on text part
-				row = (TableRow<Pair<Object, String>>) node.getParent();
-			} else {
-				Debug.out("You managed to click on Something that is neither a TableColumn nor a Tablerow");
-				return;
-			}
+			if (rowString.equals("Standard")) {
+				changeCreationMode(CreationMode.CREATE_STANDARD_NODE);
+
+			} else if (rowString.equals("Source")) {
+				changeCreationMode(CreationMode.CREATE_SOURCE_NODE);
+
+			} else if (rowString.equals("Sink")) {
+				changeCreationMode(CreationMode.CREATE_SINK_NODE);
+
+			} else if (rowString.equals("EnProc")) {
+				changeCreationMode(CreationMode.CREATE_PROC_NODE);
+
+			} else if (rowString.equals("operator")) {
+				changeCreationMode(CreationMode.CREATE_OPERATOR_NODE);
 
-			// Set CreateModus based on pressed TableRow
-			if (!row.isEmpty()) {
+			} else if (rowString.equals("Directed")) {
+				changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
 
-				String rowString = row.getItem().getValue();
+			} else if (rowString.equals("Undirected")) {
+				changeCreationMode(CreationMode.CREATE_UNDIRECTED_EDGE);
+				
+			} else if (rowString.equals("Mapping Edge")) {
+				changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
+			}
 
-				if (rowString.equals("Standard")) {
-					changeCreationMode(CreationMode.CREATE_STANDARD_NODE);
+		} else {
+			// selected item was an empty row
+			Main.getInstance().setCreationMode(CreationMode.CREATE_NONE);
+		}
 
-				} else if (rowString.equals("Source")) {
-					changeCreationMode(CreationMode.CREATE_SOURCE_NODE);
+		// Unselecet Rows if Creation Mode is None
+		if (Main.getInstance().getCreationMode().equals(CreationMode.CREATE_NONE)) {
+			controller.toolbox.getSelectionModel().clearSelection();
+		}
 
-				} else if (rowString.equals("Sink")) {
-					changeCreationMode(CreationMode.CREATE_SINK_NODE);
+		// set this property to true, so the MouseClickedHandler doesn't also
+		// fire its event
+		selectedPropertyChanged = true;
 
-				} else if (rowString.equals("ProcEn")) {
-					changeCreationMode(CreationMode.CREATE_PROC_NODE);
+	}
 
-				} else if (rowString.equals("Operator")) {
-					changeCreationMode(CreationMode.CREATE_OPERATOR_NODE);
+	/**
+	 * fired when a row was clicked
+	 * 
+	 * @param event
+	 */
+	@SuppressWarnings("unchecked")
+	public static void rowClickedHandler(MouseEvent event) {
 
-				} else if (rowString.equals("Directed")) {
-					changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
+		// only use the handler when the selectionProperty Listener didn't fire
+		// its event
+		if (selectedPropertyChanged) {
+			selectedPropertyChanged = false;
+			return;
+		}
 
-				} else if (rowString.equals("Undirected")) {
-					changeCreationMode(CreationMode.CREATE_UNDIRECTED_EDGE);
+		// Get the clicked TableRow
+		Node node = ((Node) event.getTarget()).getParent();
+		TableRow<Pair<Object, String>> row = null;
 
-				} else if (rowString.equals("Mapping Edge")) {
-					changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
-				}
+		if (node instanceof TableRow) {
+			row = (TableRow<Pair<Object, String>>) node;
+		} else {
+			// clicking on picture part
+			try {
+				row = (TableRow<Pair<Object, String>>) node.getParent();
 
-				// Deselect Rows if Creation Mode is None
-				if (Main.getInstance().getCreationMode().equals(CreationMode.CREATE_NONE)) {
-					controller.toolbox.getSelectionModel().clearSelection();
-					Main.getInstance().getGraphManager().deselectEdgeCreationNodes();
-				}
+			} catch (ClassCastException e) {
+				// there was a dragging move one the picture part when this
+				// exception is thrown -> cant get row from this action
+				return;
 			}
 		}
 
-	};
+		// clear selection if selected row was clicked again
+		if (row.isEmpty()
+				|| controller.toolbox.getSelectionModel().selectedItemProperty().get().equals(row.getItem())) {
+			controller.toolbox.getSelectionModel().clearSelection();
+		}
+	}
 
 	/**
 	 * If currentMode already selected then deselect, otherwise set mode on

+ 152 - 49
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/CustomMapClickListener.java

@@ -9,6 +9,7 @@ import org.jxmapviewer.JXMapViewer;
 import org.jxmapviewer.input.MapClickListener;
 import org.jxmapviewer.viewer.GeoPosition;
 
+import de.tu_darmstadt.informatik.tk.scopviz.main.EdgeSelectionHelper;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
@@ -18,12 +19,17 @@ public class CustomMapClickListener extends MapClickListener {
 	/*
 	 * World view viewer
 	 */
-	private final JXMapViewer viewer;
+	private static JXMapViewer viewer;
 
 	/*
 	 * selected waypoint
 	 */
-	public static CustomWaypoint selected;
+	public static CustomWaypoint selectedNode;
+
+	/*
+	 * selected edge
+	 */
+	public static Edge selectedEdge;
 
 	/*
 	 * all edges of the graph
@@ -43,22 +49,43 @@ public class CustomMapClickListener extends MapClickListener {
 	public CustomMapClickListener(JXMapViewer viewer) {
 		super(viewer);
 
-		this.viewer = viewer;
+		CustomMapClickListener.viewer = viewer;
 
 	}
 
 	@Override
 	public void mapClicked(GeoPosition arg0) {
 
-		Point2D clickedPoint = this.viewer.getTileFactory().geoToPixel(arg0, this.viewer.getZoom());
-		Point2D nodePoint;
+		Point2D clickedPoint = CustomMapClickListener.viewer.getTileFactory().geoToPixel(arg0,
+				CustomMapClickListener.viewer.getZoom());
 
 		// a waypoint was clicked
 		Boolean wayPointSelected = false;
 
+		wayPointSelected = checkWaypointClicked(clickedPoint, wayPointSelected);
+
+		// no node selected so check if edge selected
+		if (!wayPointSelected) {
+			checkEdgeClicked(clickedPoint);
+		}
+
+	}
+
+	/**
+	 * check if waypoint was clicked in symbolLayer
+	 * 
+	 * @param clickedPoint
+	 *            on map
+	 * @param wayPointSelected
+	 * @return
+	 */
+	public Boolean checkWaypointClicked(Point2D clickedPoint, Boolean wayPointSelected) {
+		Point2D nodePoint;
+
 		for (CustomWaypoint nodeWaypoint : CustomMapClickListener.waypoints) {
 			// transform GeoPosition to point on screen
-			nodePoint = this.viewer.getTileFactory().geoToPixel(nodeWaypoint.getPosition(), this.viewer.getZoom());
+			nodePoint = CustomMapClickListener.viewer.getTileFactory().geoToPixel(nodeWaypoint.getPosition(),
+					CustomMapClickListener.viewer.getZoom());
 
 			boolean yChecked = false;
 
@@ -75,65 +102,141 @@ public class CustomMapClickListener extends MapClickListener {
 
 				wayPointSelected = true;
 
-				PropertiesManager.showNewDataSet(GraphDisplayManager.getGraphManager(Layer.UNDERLAY).getGraph()
-						.getNode(nodeWaypoint.getNodeID()));
-
-				// deselect old waypoint and select new clicked waypoint
-				deselectAll();
-				nodeWaypoint.select();
-				selected = nodeWaypoint;
-				viewer.repaint();
+				selectWaypoint(nodeWaypoint);
 				break;
 			}
 		}
 
-		// no node selected so check if edge selected
-		if (!wayPointSelected) {
-			for (Edge edge : CustomMapClickListener.edges) {
-				// Get geo Positions of the two nodes that define the edge
-				GeoPosition startPos = new GeoPosition(edge.getNode0().getAttribute("lat"),
-						edge.getNode0().getAttribute("long"));
-				GeoPosition endPos = new GeoPosition(edge.getNode1().getAttribute("lat"),
-						edge.getNode1().getAttribute("long"));
-
-				// convert geo-coordinate to world bitmap pixel
-				Point2D startPoint = viewer.getTileFactory().geoToPixel(startPos, viewer.getZoom());
-				Point2D endPoint = viewer.getTileFactory().geoToPixel(endPos, viewer.getZoom());
-
-				Line2D.Double line = new Line2D.Double(startPoint.getX(), startPoint.getY(), endPoint.getX(),
-						endPoint.getY());
-
-				// Clicked point in 10 pixel range of line
-				if (line.ptLineDist(clickedPoint) < 10) {
-					deselectAll();
-					if (!edge.hasAttribute("ui.map.selected"))
-						edge.addAttribute("ui.map.selected", true);
-					else
-						edge.changeAttribute("ui.map.selected", true);
-
-					PropertiesManager.showNewDataSet(edge);
-
-					viewer.repaint();
-					break;
-				} else {
-					edge.changeAttribute("ui.map.selected", false);
+		return wayPointSelected;
+	}
+
+	/**
+	 * check if edge was clicked in symbolLayer
+	 * 
+	 * @param clickedPoint
+	 */
+	public void checkEdgeClicked(Point2D clickedPoint) {
+
+		// max distance between clicked point and edge to select edge
+		double maxDistance = 10.0;
+
+		Edge result = null;
+
+		for (Edge edge : CustomMapClickListener.edges) {
+			// Get geo Positions of the two nodes that define the edge
+			GeoPosition startPos = new GeoPosition(edge.getNode0().getAttribute("lat"),
+					edge.getNode0().getAttribute("long"));
+			GeoPosition endPos = new GeoPosition(edge.getNode1().getAttribute("lat"),
+					edge.getNode1().getAttribute("long"));
+
+			// convert geo-coordinate to world bitmap pixel
+			Point2D startPoint = viewer.getTileFactory().geoToPixel(startPos, viewer.getZoom());
+			Point2D endPoint = viewer.getTileFactory().geoToPixel(endPos, viewer.getZoom());
+
+			// the actual edge between the points
+			Line2D.Double line = new Line2D.Double(startPoint.getX(), startPoint.getY(), endPoint.getX(),
+					endPoint.getY());
+
+			// distance between nodes
+			double distanceBetweenNodes = EdgeSelectionHelper.distance(startPoint.getX(), startPoint.getY(),
+					endPoint.getX(), endPoint.getY());
+
+			// distance between clicked point and edge
+			double distanceClickedAndEdge = line.ptLineDist(clickedPoint);
+
+			// half pi
+			double HALF_PI = Math.PI / 2;
+
+			// distance of clicked point is in range of edge selection (or is
+			// nearer then to previous selected edge)
+			if (distanceClickedAndEdge < maxDistance) {
+
+				// distance start point to clicked point
+				double distanceStartToClicked = EdgeSelectionHelper.distance(startPoint.getX(), startPoint.getY(),
+						clickedPoint.getX(), clickedPoint.getY());
+
+				// distance end point to clicked point
+				double distanceEndToClicked = EdgeSelectionHelper.distance(endPoint.getX(), endPoint.getY(),
+						clickedPoint.getX(), clickedPoint.getY());
+
+				// square distances
+				double a2 = distanceStartToClicked * distanceStartToClicked;
+				double b2 = distanceEndToClicked * distanceEndToClicked;
+				double c2 = distanceBetweenNodes * distanceBetweenNodes;
+
+				// Calculates the inner angles off the triangle
+				double alpha = Math.acos((b2 + c2 - a2) / (2 * distanceEndToClicked * distanceBetweenNodes));
+				double beta = Math.acos((a2 + c2 - b2) / (2 * distanceStartToClicked * distanceBetweenNodes));
+
+				// Check if the point is actually visually next to the edge by
+				// checking if both inner angles are less than 90°
+				if (alpha <= HALF_PI && beta <= HALF_PI) {
+					maxDistance = distanceClickedAndEdge;
+					result = edge;
 				}
 			}
 		}
 
+		// Clicked point is in range of edge selection
+		if (result != null) {
+			selectEdge(result);
+		}
+	}
+
+	/**
+	 * select the given edge (calls deselctAll() before selecting)
+	 * 
+	 * @param edge
+	 */
+	public static void selectEdge(Edge edge) {
+
+		PropertiesManager.showNewDataSet(edge);
+
+		deselectAll();
+
+		if (!edge.hasAttribute("ui.map.selected"))
+			edge.addAttribute("ui.map.selected", true);
+		else
+			edge.changeAttribute("ui.map.selected", true);
+
+		selectedEdge = edge;
+
+		viewer.repaint();
+	}
+
+	/**
+	 * select the given waypoint (calls deselctAll() before selecting)
+	 * 
+	 * @param nodeWaypoint
+	 */
+	public static void selectWaypoint(CustomWaypoint nodeWaypoint) {
+
+		PropertiesManager.showNewDataSet(
+				GraphDisplayManager.getGraphManager(Layer.UNDERLAY).getGraph().getNode(nodeWaypoint.getNodeID()));
+
+		// deselect old waypoint and select new clicked waypoint
+		deselectAll();
+		nodeWaypoint.select();
+		selectedNode = nodeWaypoint;
+		viewer.repaint();
 	}
 
 	/**
 	 * deselect all edges and the selected node
 	 */
 	public static void deselectAll() {
-		if (selected != null) {
-			selected.deselect();
-			selected = null;
+		if (selectedNode != null) {
+
+			selectedNode.deselect();
+			selectedNode = null;
 		}
-		for (Edge edge : edges) {
-			edge.changeAttribute("ui.map.selected", false);
+		if (selectedEdge != null) {
+
+			selectedEdge.changeAttribute("ui.map.selected", false);
+			selectedEdge = null;
 		}
+
+		viewer.repaint();
 	}
 
 }

+ 55 - 4
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/CustomWaypointRenderer.java

@@ -26,12 +26,12 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 	/**
 	 * the standard background color of images
 	 */
-	public static final Color STANDARD = Color.BLACK;
+	public static Color STANDARD = Color.BLACK;
 
 	/**
 	 * the color of an image, when it was clicked
 	 */
-	public static final Color CLICKED = Color.RED;
+	public static Color CLICKED = Color.RED;
 
 	/**
 	 * an rgb alpha value for computing only
@@ -41,12 +41,12 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 	/**
 	 * the standard width of the shown images, after scaling it
 	 */
-	public static final int SCALEWIDTH = 60;
+	public static int SCALEWIDTH = 50;
 
 	/**
 	 * the standard height of the shwon images, after scaling it
 	 */
-	public static final int SCALEHEIGHT = 60;
+	public static int SCALEHEIGHT = 50;
 
 	@Override
 	public void paintWaypoint(Graphics2D g, JXMapViewer viewer, CustomWaypoint w) {
@@ -56,6 +56,13 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 		// get pre loaded image
 		BufferedImage loadedImg = MapViewFunctions.imageMap.get(w.getDeviceType());
 
+		// standard color has been changed
+		if (!getStandardColor().equals(Color.BLACK)) {
+			loadedImg = MapViewFunctions.colorImage(loadedImg, Color.BLACK, CustomWaypointRenderer.STANDARD,
+					CustomWaypointRenderer.ALPHA);
+		}
+
+		// waypoint is selected
 		if (w.getIsSelected()) {
 			loadedImg = MapViewFunctions.colorImage(loadedImg, CustomWaypointRenderer.STANDARD,
 					CustomWaypointRenderer.CLICKED, CustomWaypointRenderer.ALPHA);
@@ -98,4 +105,48 @@ public class CustomWaypointRenderer implements WaypointRenderer<CustomWaypoint>
 		this.showLabels = showLabels;
 	}
 
+	/**
+	 * sets the color types of waypoints
+	 * 
+	 * @param standard
+	 *            standard color when symbol rep. opened
+	 * @param selected
+	 *            when clicked
+	 */
+	public static void setColor(String standard, String selected) {
+		STANDARD = EdgePainter.stringToColor(standard);
+		CLICKED = EdgePainter.stringToColor(selected);
+	}
+
+	/**
+	 * sets the width and height of the scaled images
+	 * 
+	 * @param size
+	 */
+	public static void setScaleSize(int size) {
+		SCALEWIDTH = size;
+		SCALEHEIGHT = size;
+	}
+
+	/**
+	 * @return waypoint size after scaling it
+	 */
+	public static int getWaypointSize() {
+		return SCALEWIDTH;
+	}
+
+	/**
+	 * @return color when clicked
+	 */
+	public static String getClickedColor() {
+		return EdgePainter.getColorAsString(CLICKED);
+	}
+
+	/**
+	 * @return standard color
+	 */
+	public static String getStandardColor() {
+		return EdgePainter.getColorAsString(STANDARD);
+	}
+
 }

+ 132 - 27
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/EdgePainter.java

@@ -29,12 +29,22 @@ public class EdgePainter implements Painter<JXMapViewer> {
 	/**
 	 * standard color in which edges are drawn
 	 */
-	private static final Color STANDARD = Color.BLACK;
+	private static Color STANDARD = Color.BLACK;
 
 	/**
 	 * color in which edges are drawn when clicked
 	 */
-	private static final Color CLICKED = Color.RED;
+	private static Color CLICKED = Color.RED;
+
+	/**
+	 * color in which edges are drawn when they are used in a placement
+	 */
+	private static Color PLACEMENT = Color.BLUE;
+
+	/**
+	 * the thickness of edges
+	 */
+	private static int EDGE_THICKNESS = 2;
 
 	/**
 	 * anti aliasing property
@@ -74,15 +84,9 @@ public class EdgePainter implements Painter<JXMapViewer> {
 			if (antiAlias)
 				g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
-			// do the drawing
-			g.setColor(STANDARD);
-			g.setStroke(new BasicStroke(4));
-
-			drawRoute(g, mapViewer);
-
 			// do the drawing again
 			g.setColor(STANDARD);
-			g.setStroke(new BasicStroke(2));
+			g.setStroke(new BasicStroke(EDGE_THICKNESS));
 
 			drawRoute(g, mapViewer);
 
@@ -112,29 +116,21 @@ public class EdgePainter implements Painter<JXMapViewer> {
 			Point2D startPoint = mapViewer.getTileFactory().geoToPixel(startPos, mapViewer.getZoom());
 			Point2D endPoint = mapViewer.getTileFactory().geoToPixel(endPos, mapViewer.getZoom());
 
-			// if edge has attribute selected
-			if (edge.hasAttribute("ui.map.selected")) {
-
+			if (edge.hasAttribute("ui.map.selected") && (boolean) edge.getAttribute("ui.map.selected")) {
 				// draw red line if edge is selected
-				if ((boolean) edge.getAttribute("ui.map.selected")) {
-					g.setColor(CLICKED);
-					g.drawLine((int) startPoint.getX(), (int) startPoint.getY(), (int) endPoint.getX(),
-							(int) endPoint.getY());
-
-					// draw black line if not selected
-				} else {
-					g.setColor(STANDARD);
-					g.drawLine((int) startPoint.getX(), (int) startPoint.getY(), (int) endPoint.getX(),
-							(int) endPoint.getY());
-				}
-
-				// edge hasnt got selected attribute
+				g.setColor(CLICKED);
+
+			} else if (edge.hasAttribute("usedInPlacement") && (boolean) edge.getAttribute("usedInPlacement")) {
+				// draw blue line when edge used in placement
+				g.setColor(PLACEMENT);
+
 			} else {
+				// draw black line if not selected
 				g.setColor(STANDARD);
-				g.drawLine((int) startPoint.getX(), (int) startPoint.getY(), (int) endPoint.getX(),
-						(int) endPoint.getY());
 			}
 
+			g.drawLine((int) startPoint.getX(), (int) startPoint.getY(), (int) endPoint.getX(), (int) endPoint.getY());
+
 			if (showWeights) {
 				drawWeights(edge, g, startPoint, endPoint);
 			}
@@ -204,4 +200,113 @@ public class EdgePainter implements Painter<JXMapViewer> {
 		this.showWeights = showWeights;
 	}
 
+	/**
+	 * sets the thickness of the drawn edges
+	 * 
+	 * @param thickness
+	 */
+	public static void setEdgeThickness(int thickness) {
+		EDGE_THICKNESS = thickness;
+	}
+
+	/**
+	 * sets the color types of edges
+	 * 
+	 * @param standard
+	 *            standard color when symbol rep. opened
+	 * @param placement
+	 *            when used in placement
+	 * @param selected
+	 *            when clicked
+	 */
+	public static void setColor(String standard, String placement, String selected) {
+		STANDARD = stringToColor(standard);
+		PLACEMENT = stringToColor(placement);
+		CLICKED = stringToColor(selected);
+
+	}
+
+	/**
+	 * 
+	 * @param string
+	 * @return color under given string
+	 */
+	public static Color stringToColor(String color) {
+
+		switch (color) {
+
+		case "Red":
+			return Color.RED;
+		case "Black":
+			return Color.BLACK;
+		case "Blue":
+			return Color.BLUE;
+		case "Yellow":
+			return Color.YELLOW;
+		case "Green":
+			return Color.GREEN;
+		case "Orange":
+			return Color.ORANGE;
+		case "Gray":
+			return Color.GRAY;
+
+		default:
+			return Color.BLACK;
+		}
+	}
+
+	/**
+	 * @return the thickness of edges
+	 */
+	public static int getThickness() {
+		return EDGE_THICKNESS;
+	}
+
+	/**
+	 * @return color when clicked
+	 */
+	public static String getClickedColor() {
+		return getColorAsString(CLICKED);
+	}
+
+	/**
+	 * @return standard color
+	 */
+	public static String getStandardColor() {
+		return getColorAsString(STANDARD);
+	}
+
+	/**
+	 * @return placement color
+	 */
+	public static String getPlacementColor() {
+		return getColorAsString(PLACEMENT);
+	}
+
+	/**
+	 * 
+	 * @param color
+	 * @return color in specific string representation
+	 */
+	public static String getColorAsString(Color color) {
+
+		if (color.equals(Color.RED))
+			return "Red";
+		if (color.equals(Color.BLACK))
+			return "Black";
+		if (color.equals(Color.BLUE))
+			return "Blue";
+		if (color.equals(Color.GREEN))
+			return "Green";
+		if (color.equals(Color.YELLOW))
+			return "Yellow";
+		if (color.equals(Color.ORANGE))
+			return "Orange";
+		if (color.equals(Color.GRAY))
+			return "Gray";
+
+		return "Unknown";
+
+	}
+
 }

+ 124 - 7
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/MapViewFunctions.java

@@ -4,6 +4,7 @@ import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 
@@ -17,16 +18,21 @@ import org.jxmapviewer.JXMapViewer;
 import org.jxmapviewer.OSMTileFactoryInfo;
 import org.jxmapviewer.VirtualEarthTileFactoryInfo;
 import org.jxmapviewer.painter.Painter;
-import org.jxmapviewer.viewer.DefaultTileFactory;
 import org.jxmapviewer.viewer.GeoPosition;
 import org.jxmapviewer.viewer.TileFactoryInfo;
 import org.jxmapviewer.viewer.WaypointPainter;
 
 import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphManager;
 import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
+import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
 import de.tu_darmstadt.informatik.tk.scopviz.main.MainApp;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
 import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
+import javafx.beans.binding.Bindings;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.input.ContextMenuEvent;
 
 public final class MapViewFunctions {
 
@@ -38,6 +44,8 @@ public final class MapViewFunctions {
 	public static HashMap<String, BufferedImage> imageMap = new HashMap<String, BufferedImage>(
 			WorldView.waypoints.size());
 
+	private static ArrayList<CustomWaypoint> waypointsAsList = new ArrayList<CustomWaypoint>();
+
 	/**
 	 * private constructor to avoid instantiation
 	 */
@@ -172,9 +180,12 @@ public final class MapViewFunctions {
 				URL resource = getDeviceTypeURL(deviceType);
 
 				// create a new waypoint with the node information
-				waypoints.add(
-						new CustomWaypoint(node.getAttribute("ui.label"), node.getId(), resource, deviceType, geoPos));
+				CustomWaypoint waypoint = new CustomWaypoint(node.getAttribute("ui.label"), node.getId(), resource,
+						deviceType, geoPos);
+
+				waypoints.add(waypoint);
 
+				waypointsAsList.add(waypoint);
 			}
 		}
 
@@ -241,23 +252,23 @@ public final class MapViewFunctions {
 		switch (selected) {
 		case "Default":
 			TileFactoryInfo defaultTileFactoryInfo = new OSMTileFactoryInfo();
-			WorldView.internMapViewer.setTileFactory(new DefaultTileFactory(defaultTileFactoryInfo));
+			WorldView.internMapViewer.setTileFactory(new CustomTileFactory(defaultTileFactoryInfo));
 			break;
 
 		case "Road":
 			TileFactoryInfo roadTileFactoryInfo = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP);
-			WorldView.internMapViewer.setTileFactory(new DefaultTileFactory(roadTileFactoryInfo));
+			WorldView.internMapViewer.setTileFactory(new CustomTileFactory(roadTileFactoryInfo));
 			break;
 
 		case "Satellite":
 			TileFactoryInfo sateliteTileFactoryInfo = new VirtualEarthTileFactoryInfo(
 					VirtualEarthTileFactoryInfo.SATELLITE);
-			WorldView.internMapViewer.setTileFactory(new DefaultTileFactory(sateliteTileFactoryInfo));
+			WorldView.internMapViewer.setTileFactory(new CustomTileFactory(sateliteTileFactoryInfo));
 			break;
 
 		case "Hybrid":
 			TileFactoryInfo hybridTileFactoryInfo = new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.HYBRID);
-			WorldView.internMapViewer.setTileFactory(new DefaultTileFactory(hybridTileFactoryInfo));
+			WorldView.internMapViewer.setTileFactory(new CustomTileFactory(hybridTileFactoryInfo));
 			break;
 		}
 	}
@@ -289,4 +300,110 @@ public final class MapViewFunctions {
 		}
 	}
 
+	/**
+	 * Show a ContextMenu when map was right clicked to change symbol layer
+	 * checkbox properties
+	 * 
+	 * @param event
+	 *            contextMenu mouse event
+	 */
+	public static void contextMenuRequest(ContextMenuEvent event) {
+
+		// Declare context menu and items
+		final ContextMenu menu = new ContextMenu();
+		final MenuItem edgeVisible = new MenuItem("Hide Edges");
+		final MenuItem weightVisible = new MenuItem("Hide Weights");
+		final MenuItem labelVisible = new MenuItem("Hide Labels");
+
+		// the checkboxes in dhe symbol layer
+		CheckBox edgeCheckbox = WorldView.controller.edgesVisibleCheckbox;
+		CheckBox weightCheckbox = WorldView.controller.edgeWeightCheckbox;
+		CheckBox labelCheckbox = WorldView.controller.nodeLabelCheckbox;
+
+		// define the actions when clicked on menu item
+		edgeVisible.setOnAction((actionEvent) -> {
+			if (edgeCheckbox.isSelected()) {
+				edgeCheckbox.setSelected(false);
+			} else {
+				edgeCheckbox.setSelected(true);
+			}
+		});
+
+		weightVisible.setOnAction((actionEvent) -> {
+			if (weightCheckbox.isSelected()) {
+				weightCheckbox.setSelected(false);
+			} else {
+				weightCheckbox.setSelected(true);
+			}
+		});
+
+		labelVisible.setOnAction((actionEvent) -> {
+			if (labelCheckbox.isSelected()) {
+				labelCheckbox.setSelected(false);
+			} else {
+				labelCheckbox.setSelected(true);
+			}
+		});
+
+		// bind the text properties to the menu item, so that they change
+		// depending on the selection property
+		edgeVisible.textProperty()
+				.bind(Bindings.when(edgeCheckbox.selectedProperty()).then("Hide Edges").otherwise("Show Edges"));
+
+		weightVisible.textProperty()
+				.bind(Bindings.when(weightCheckbox.selectedProperty()).then("Hide Weights").otherwise("Show Weights"));
+
+		labelVisible.textProperty()
+				.bind(Bindings.when(labelCheckbox.selectedProperty()).then("Hide Labels").otherwise("Show Labels"));
+
+		menu.getItems().addAll(edgeVisible, weightVisible, labelVisible);
+
+		// show context menu at the clicked point
+		menu.show(Main.getInstance().getPrimaryStage(), event.getScreenX(), event.getScreenY());
+
+	}
+
+	/**
+	 * switch to previous Waypoint
+	 */
+	public static void switchToPreviousWaypoint() {
+
+		CustomWaypoint selectedWaypoint = CustomMapClickListener.selectedNode;
+
+		if (selectedWaypoint == null && waypointsAsList.size() > 0) {
+			CustomMapClickListener.selectWaypoint(waypointsAsList.get(0));
+
+		} else {
+			int index = waypointsAsList.indexOf(selectedWaypoint);
+
+			if (index == 0) {
+				CustomMapClickListener.selectWaypoint(waypointsAsList.get(waypointsAsList.size() - 1));
+			} else {
+				CustomMapClickListener.selectWaypoint(waypointsAsList.get(index - 1));
+			}
+		}
+	}
+
+	/**
+	 * switch to next Waypoint
+	 */
+	public static void switchToNextWaypoint() {
+
+		CustomWaypoint selectedWaypoint = CustomMapClickListener.selectedNode;
+
+		if (selectedWaypoint == null && waypointsAsList.size() > 0) {
+			CustomMapClickListener.selectWaypoint(waypointsAsList.get(0));
+
+		} else {
+			int index = waypointsAsList.indexOf(selectedWaypoint);
+
+			if (index == waypointsAsList.size() - 1) {
+				CustomMapClickListener.selectWaypoint(waypointsAsList.get(0));
+			} else {
+				CustomMapClickListener.selectWaypoint(waypointsAsList.get(index + 1));
+			}
+		}
+
+	}
+
 }

+ 95 - 20
scopviz/src/main/java/de/tu_darmstadt/informatik/tk/scopviz/ui/mapView/WorldView.java

@@ -1,5 +1,6 @@
 package de.tu_darmstadt.informatik.tk.scopviz.ui.mapView;
 
+import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -18,6 +19,7 @@ import org.jxmapviewer.viewer.TileFactoryInfo;
 import org.jxmapviewer.viewer.WaypointPainter;
 
 import de.tu_darmstadt.informatik.tk.scopviz.ui.GUIController;
+import javafx.geometry.Rectangle2D;
 
 public class WorldView {
 
@@ -36,6 +38,11 @@ public class WorldView {
 	 */
 	public static WaypointPainter<CustomWaypoint> waypointPainter;
 
+	/*
+	 * mapClickListener, used to only initialize the Listener once
+	 */
+	public static CustomMapClickListener mapClickListener;
+
 	/*
 	 * GUIController with UI elements
 	 */
@@ -51,6 +58,11 @@ public class WorldView {
 	 */
 	public static HashSet<Edge> edges;
 
+	/*
+	 * All painter in symbolLayer stored in a list
+	 */
+	public static List<Painter<JXMapViewer>> painters;
+
 	/**
 	 * private constructor to avoid instantiation
 	 */
@@ -82,24 +94,55 @@ public class WorldView {
 		// Get GeoPositions of nodes and get all waypoints created
 		MapViewFunctions.fetchGraphData(nodePositions, waypoints, edges);
 
-		// Create a line for all edges
-		edgePainter = new EdgePainter(edges);
+		if (edgePainter == null)
+			// Create a line for all edges
+			edgePainter = new EdgePainter(edges);
 
-		// Create a waypoint painter that takes all the waypoints
-		waypointPainter = new WaypointPainter<CustomWaypoint>();
-		waypointPainter.setWaypoints(waypoints);
-		waypointPainter.setRenderer(new CustomWaypointRenderer());
+		if (waypointPainter == null) {
+			// Create a waypoint painter that takes all the waypoints
+			waypointPainter = new WaypointPainter<CustomWaypoint>();
+			waypointPainter.setWaypoints(waypoints);
+			waypointPainter.setRenderer(new CustomWaypointRenderer());
+		}
 
-		// Create a compound painter that uses all painters
-		List<Painter<JXMapViewer>> painters = new ArrayList<Painter<JXMapViewer>>();
-		painters.add(edgePainter);
-		painters.add(waypointPainter);
+		if (painters == null) {
+			// Create a compound painter that uses all painters
+			painters = new ArrayList<Painter<JXMapViewer>>();
+			painters.add(edgePainter);
+			painters.add(waypointPainter);
+		}
 
 		CompoundPainter<JXMapViewer> painter = new CompoundPainter<JXMapViewer>(painters);
 
 		// Create a TileFactoryInfo for OpenStreetMap
 		TileFactoryInfo info = new OSMTileFactoryInfo();
 
+		CustomTileFactory tileFactory = new CustomTileFactory(info);
+		if (!internMapViewer.getTileFactory().equals(tileFactory)) {
+			internMapViewer.setTileFactory(tileFactory);
+		}
+
+		// Use 8 threads in parallel to load the tiles
+		tileFactory.setThreadPoolSize(8);
+
+		showAllWaypoints(nodePositions);
+
+		// set Zoom and Center to show all node positions
+		// internMapViewer.zoomToBestFit(nodePositions, 1);
+
+		if (internMapViewer.getOverlayPainter() == null) {
+			internMapViewer.setOverlayPainter(painter);
+		}
+
+		if (mapClickListener == null) {
+			mapClickListener = new CustomMapClickListener(internMapViewer);
+
+			// "click on waypoints" listener
+			internMapViewer.addMouseListener(mapClickListener);
+		}
+
+		internMapViewer.repaint();
+
 		// try to load OpenStreesMap, when errors occur, throw and handle
 		// Exceptions
 		URL osmWebPage;
@@ -114,22 +157,54 @@ public class WorldView {
 			e.printStackTrace();
 
 		}
+	}
 
-		CustomTileFactory tileFactory = new CustomTileFactory(info);
-		internMapViewer.setTileFactory(tileFactory);
+	/**
+	 * centers map, so that all waypoints are shown
+	 * 
+	 * @param positions
+	 */
+	public static void showAllWaypoints(HashSet<GeoPosition> positions) {
 
-		// Use 8 threads in parallel to load the tiles
-		tileFactory.setThreadPoolSize(8);
+		ArrayList<Point2D> points = new ArrayList<Point2D>(positions.size());
 
-		// set Zoom and Center to show all node positions
-		internMapViewer.zoomToBestFit(nodePositions, 0.7);
+		internMapViewer.setZoom(1);
 
-		internMapViewer.setOverlayPainter(painter);
+		internMapViewer.calculateZoomFrom(positions);
 
-		// "click on waypoints" listener
-		internMapViewer.addMouseListener(new CustomMapClickListener(internMapViewer));
+		positions.forEach((geoPos) -> points.add(internMapViewer.convertGeoPositionToPoint(geoPos)));
+
+		double minX = Double.MAX_VALUE;
+		double maxX = Double.MIN_VALUE;
+
+		double minY = Double.MAX_VALUE;
+		double maxY = Double.MIN_VALUE;
+
+		for (Point2D p : points) {
+			if (p.getX() < minX) {
+				minX = p.getX();
+			}
+			if (p.getX() > maxX) {
+				maxX = p.getX();
+			}
+
+			if (p.getY() < minY) {
+				minY = p.getY();
+			}
+			if (p.getY() > maxY) {
+				maxY = p.getY();
+			}
+		}
+
+		Rectangle2D rect = new Rectangle2D(minX, minY, maxY - minY, maxX - minX);
+
+		double xPos = rect.getMinX() + rect.getHeight() / 2;
+		double yPos = rect.getMinY() + rect.getWidth() / 2;
+
+		Point2D center = new Point2D.Double(xPos, yPos);
+
+		internMapViewer.setCenterPosition(internMapViewer.convertPointToGeoPosition(center));
 
-		internMapViewer.repaint();
 	}
 
 }