CustomMapClickListener.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package de.tu_darmstadt.informatik.tk.scopviz.ui.mapView;
  2. import java.awt.geom.Line2D;
  3. import java.awt.geom.Point2D;
  4. import java.util.HashSet;
  5. import org.jxmapviewer.JXMapViewer;
  6. import org.jxmapviewer.input.MapClickListener;
  7. import org.jxmapviewer.viewer.GeoPosition;
  8. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge;
  9. import de.tu_darmstadt.informatik.tk.scopviz.main.EdgeSelectionHelper;
  10. import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
  11. import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
  12. import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
  13. public class CustomMapClickListener extends MapClickListener {
  14. /*
  15. * World view viewer
  16. */
  17. private static JXMapViewer viewer;
  18. /*
  19. * selected waypoint
  20. */
  21. public static CustomWaypoint selectedNode;
  22. /*
  23. * selected edge
  24. */
  25. public static MyEdge selectedEdge;
  26. /*
  27. * all edges of the graph
  28. */
  29. private final static HashSet<MyEdge> edges = WorldView.edges;
  30. /*
  31. * all waypoints of the graph
  32. */
  33. private final static HashSet<CustomWaypoint> waypoints = WorldView.waypoints;
  34. /**
  35. * Constructor sets viewer
  36. *
  37. * @param viewer
  38. */
  39. public CustomMapClickListener(JXMapViewer viewer) {
  40. super(viewer);
  41. CustomMapClickListener.viewer = viewer;
  42. }
  43. @Override
  44. public void mapClicked(GeoPosition arg0) {
  45. Point2D clickedPoint = CustomMapClickListener.viewer.getTileFactory().geoToPixel(arg0,
  46. CustomMapClickListener.viewer.getZoom());
  47. // a waypoint was clicked
  48. Boolean wayPointSelected = false;
  49. wayPointSelected = checkWaypointClicked(clickedPoint, wayPointSelected);
  50. // no node selected so check if edge selected
  51. if (!wayPointSelected) {
  52. checkEdgeClicked(clickedPoint);
  53. }
  54. }
  55. /**
  56. * check if waypoint was clicked in symbolLayer
  57. *
  58. * @param clickedPoint
  59. * on map
  60. * @param wayPointSelected
  61. * @return
  62. */
  63. public Boolean checkWaypointClicked(Point2D clickedPoint, Boolean wayPointSelected) {
  64. Point2D nodePoint;
  65. int pictureSize = CustomWaypointRenderer.SCALEWIDTH;
  66. for (CustomWaypoint nodeWaypoint : CustomMapClickListener.waypoints) {
  67. // transform GeoPosition to point on screen
  68. nodePoint = CustomMapClickListener.viewer.getTileFactory().geoToPixel(nodeWaypoint.getPosition(),
  69. CustomMapClickListener.viewer.getZoom());
  70. boolean yChecked = false;
  71. // clicked position is in range of 50 pixel above the waypoint
  72. // position
  73. double deltaY = clickedPoint.getY() - nodePoint.getY();
  74. if (deltaY > -pictureSize && deltaY < 0) {
  75. yChecked = true;
  76. }
  77. // clicked Position is in x- and y-range of wapoint position (in
  78. // range of 50 pixels)
  79. if (Math.abs(clickedPoint.getX() - nodePoint.getX()) < (pictureSize / 2) && yChecked) {
  80. wayPointSelected = true;
  81. selectWaypoint(nodeWaypoint);
  82. break;
  83. }
  84. }
  85. return wayPointSelected;
  86. }
  87. /**
  88. * check if edge was clicked in symbolLayer
  89. *
  90. * @param clickedPoint
  91. */
  92. public void checkEdgeClicked(Point2D clickedPoint) {
  93. // max distance between clicked point and edge to select edge
  94. double maxDistance = 10.0;
  95. MyEdge result = null;
  96. for (MyEdge edge : CustomMapClickListener.edges) {
  97. // Get geo Positions of the two nodes that define the edge
  98. GeoPosition startPos = new GeoPosition(edge.getNode0().getAttribute("lat"),
  99. edge.getNode0().getAttribute("long"));
  100. GeoPosition endPos = new GeoPosition(edge.getNode1().getAttribute("lat"),
  101. edge.getNode1().getAttribute("long"));
  102. // convert geo-coordinate to world bitmap pixel
  103. Point2D startPoint = viewer.getTileFactory().geoToPixel(startPos, viewer.getZoom());
  104. Point2D endPoint = viewer.getTileFactory().geoToPixel(endPos, viewer.getZoom());
  105. // the actual edge between the points
  106. Line2D.Double line = new Line2D.Double(startPoint.getX(), startPoint.getY(), endPoint.getX(),
  107. endPoint.getY());
  108. // distance between nodes
  109. double distanceBetweenNodes = EdgeSelectionHelper.distance(startPoint.getX(), startPoint.getY(),
  110. endPoint.getX(), endPoint.getY());
  111. // distance between clicked point and edge
  112. double distanceClickedAndEdge = line.ptLineDist(clickedPoint);
  113. // half pi
  114. double HALF_PI = Math.PI / 2;
  115. // distance of clicked point is in range of edge selection (or is
  116. // nearer then to previous selected edge)
  117. if (distanceClickedAndEdge < maxDistance) {
  118. // distance start point to clicked point
  119. double distanceStartToClicked = EdgeSelectionHelper.distance(startPoint.getX(), startPoint.getY(),
  120. clickedPoint.getX(), clickedPoint.getY());
  121. // distance end point to clicked point
  122. double distanceEndToClicked = EdgeSelectionHelper.distance(endPoint.getX(), endPoint.getY(),
  123. clickedPoint.getX(), clickedPoint.getY());
  124. // square distances
  125. double a2 = distanceStartToClicked * distanceStartToClicked;
  126. double b2 = distanceEndToClicked * distanceEndToClicked;
  127. double c2 = distanceBetweenNodes * distanceBetweenNodes;
  128. // Calculates the inner angles off the triangle
  129. double alpha = Math.acos((b2 + c2 - a2) / (2 * distanceEndToClicked * distanceBetweenNodes));
  130. double beta = Math.acos((a2 + c2 - b2) / (2 * distanceStartToClicked * distanceBetweenNodes));
  131. // Check if the point is actually visually next to the edge by
  132. // checking if both inner angles are less than 90°
  133. if (alpha <= HALF_PI && beta <= HALF_PI) {
  134. maxDistance = distanceClickedAndEdge;
  135. result = edge;
  136. }
  137. }
  138. }
  139. // Clicked point is in range of edge selection
  140. if (result != null) {
  141. selectEdge(result);
  142. }
  143. }
  144. /**
  145. * select the given edge (calls deselctAll() before selecting)
  146. *
  147. * @param edge
  148. */
  149. public static void selectEdge(MyEdge edge) {
  150. PropertiesManager.showNewDataSet(edge);
  151. deselectAll();
  152. if (!edge.hasAttribute("ui.map.selected"))
  153. edge.addAttribute("ui.map.selected", true);
  154. else
  155. edge.changeAttribute("ui.map.selected", true);
  156. selectedEdge = edge;
  157. viewer.repaint();
  158. }
  159. /**
  160. * select the given waypoint (calls deselctAll() before selecting)
  161. *
  162. * @param nodeWaypoint
  163. */
  164. public static void selectWaypoint(CustomWaypoint nodeWaypoint) {
  165. PropertiesManager.showNewDataSet(
  166. GraphDisplayManager.getGraphManager(Layer.UNDERLAY).getGraph().getNode(nodeWaypoint.getNodeID()));
  167. // deselect old waypoint and select new clicked waypoint
  168. deselectAll();
  169. nodeWaypoint.select();
  170. selectedNode = nodeWaypoint;
  171. viewer.repaint();
  172. }
  173. /**
  174. * deselect all edges and the selected node
  175. */
  176. public static void deselectAll() {
  177. if (selectedNode != null) {
  178. selectedNode.deselect();
  179. selectedNode = null;
  180. }
  181. if (selectedEdge != null) {
  182. selectedEdge.changeAttribute("ui.map.selected", false);
  183. selectedEdge = null;
  184. }
  185. viewer.repaint();
  186. }
  187. }