Ticket #4190: follow-way.diff
| File follow-way.diff, 9.2 KB (added by , 16 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
diff --git a/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java b/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java index f09724b..cf84939 100644
a b public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 87 87 private Color selectedColor; 88 88 89 89 private Node currentBaseNode; 90 private Node currentMouseNode; 90 91 private EastNorth currentMouseEastNorth; 91 92 92 93 public DrawAction(MapFrame mapFrame) { … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 331 332 ArrayList<Way> reuseWays = new ArrayList<Way>(), 332 333 replacedWays = new ArrayList<Way>(); 333 334 boolean newNode = false; 335 int numNodes = 0; // only for shift click on a node 334 336 Node n = null; 335 337 336 338 if (!ctrl) { … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 432 434 boolean wayIsFinishedTemp = wayIsFinished; 433 435 wayIsFinished = false; 434 436 435 // don't draw lines if shift is held 436 if (selection.size() > 0 && !shift) {437 // don't draw lines if shift is held, except when a node was clicked 438 if (selection.size() > 0 && (!shift || !newNode)) { 437 439 Node selectedNode = null; 438 440 Way selectedWay = null; 439 441 … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 515 517 } 516 518 517 519 // Add new node to way 518 if (way.getNode(way.getNodesCount() - 1) == n0) { 519 way.addNode(n); 520 if (shift) { 521 boolean end = (way.getNode(way.getNodesCount() - 1) == n0); 522 for (Node node : getFollowWayNodes(n0, n)) { 523 if (end) { 524 way.addNode(node); 525 } else { 526 way.addNode(0, node); 527 } 528 numNodes++; 529 } 520 530 } else { 521 way.addNode(0, n); 531 if (way.getNode(way.getNodesCount() - 1) == n0) { 532 way.addNode(n); 533 } else { 534 way.addNode(0, n); 535 } 522 536 } 523 537 524 538 extendedWay = true; … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 542 556 newSelection.clear(); 543 557 newSelection.add(n); 544 558 } else if (!newNode) { 545 title = tr("Connect existing way to node"); 559 if (numNodes <= 1) { 560 title = tr("Connect existing way to node"); 561 } else { 562 title = tr("Connect existing way to {0} nodes", numNodes); 563 } 546 564 } else if (reuseWays.isEmpty()) { 547 565 title = tr("Add a new node to an existing way"); 548 566 } else { … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 671 689 672 690 Node selectedNode = null; 673 691 Way selectedWay = null; 674 Node currentMouseNode = null;675 692 mouseOnExistingNode = null; 676 693 mouseOnExistingWays = new HashSet<Way>(); 677 694 … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 681 698 682 699 if (!ctrl && mousePos != null) { 683 700 currentMouseNode = mv.getNearestNode(mousePos); 701 } else { 702 currentMouseNode = null; 684 703 } 685 704 686 705 // We need this for highlighting and we'll only do so if we actually want to re-use … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 786 805 return way; 787 806 } 788 807 808 private List<Node> getFollowWayNodes(Node startNode, Node endNode) { 809 // get list of ways that have both the start node and the end node 810 Collection<Way> allWays = getCurrentDataSet().getWays(); 811 Collection<Way> sourceWays = new LinkedList<Way>(); 812 for (Way way : allWays) { 813 Collection<Node> wayNodes = way.getNodes(); 814 if(wayNodes.contains(startNode) && wayNodes.contains(endNode)) 815 sourceWays.add(way); 816 } 817 818 // if no ways are found, we'll just link directly to the end node 819 if (sourceWays.size() == 0) { 820 List<Node> nodes = new LinkedList<Node>(); 821 nodes.add(endNode); 822 return nodes; 823 } 824 825 // create a list of possible routes between the nodes 826 Collection<List<Node>> routes = new LinkedList<List<Node>>(); 827 828 for (Way way : sourceWays) { 829 // find the node indexes in the way 830 List<Node> wayNodes = way.getNodes(); 831 int startIndex = wayNodes.indexOf(startNode); 832 int endIndex = wayNodes.indexOf(endNode); 833 834 if (startIndex > endIndex) { 835 int tmp = startIndex; 836 startIndex = endIndex; 837 endIndex = tmp; 838 } 839 840 routes.add(wayNodes.subList(startIndex, endIndex + 1)); 841 842 if (way.isClosed()) { 843 List<Node> route = new LinkedList<Node>(); 844 route.addAll(wayNodes.subList(endIndex, wayNodes.size())); 845 route.addAll(wayNodes.subList(1, startIndex + 1)); 846 routes.add(route); 847 } 848 } 849 850 // find the shortest route 851 List<Node> bestRoute = null; 852 double shortestDistance = -1; 853 854 for (List<Node> route : routes) { 855 double distance = 0; 856 Node previous = route.get(0); 857 for (Node node : route) { 858 distance += previous.getEastNorth().distance(node.getEastNorth()); 859 previous = node; 860 } 861 if (bestRoute == null || distance < shortestDistance) { 862 bestRoute = route; 863 shortestDistance = distance; 864 } 865 } 866 867 if (bestRoute.get(0) != startNode) 868 Collections.reverse(bestRoute); 869 870 return bestRoute.subList(1, bestRoute.size()); 871 } 872 789 873 private static void pruneSuccsAndReverse(List<Integer> is) { 790 874 //if (is.size() < 2) return; 791 875 … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 877 961 return a * d - b * c; 878 962 } 879 963 880 public void paint(Graphics2D g, MapView mv, Bounds box) { 881 if (!drawHelperLine || wayIsFinished || shift) return; 882 883 // sanity checks 884 if (Main.map.mapView == null) return; 885 if (mousePos == null) return; 886 887 // don't draw line if we don't know where from or where to 888 if (currentBaseNode == null || currentMouseEastNorth == null) return; 889 890 // don't draw line if mouse is outside window 891 if (!Main.map.mapView.getBounds().contains(mousePos)) return; 892 964 private void drawHelperLine(Graphics2D g, MapView mv, Point p1, Point p2, boolean startline) { 893 965 Graphics2D g2 = g; 894 966 g2.setColor(selectedColor); 895 967 g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 896 968 GeneralPath b = new GeneralPath(); 897 Point p1=mv.getPoint(currentBaseNode);898 Point p2=mv.getPoint(currentMouseEastNorth);899 969 900 970 double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI; 901 971 902 972 b.moveTo(p1.x,p1.y); b.lineTo(p2.x, p2.y); 903 973 904 974 // if alt key is held ("start new way"), draw a little perpendicular line 905 if ( alt) {975 if (startline) { 906 976 b.moveTo((int)(p1.x + 8*Math.cos(t+PHI)), (int)(p1.y + 8*Math.sin(t+PHI))); 907 977 b.lineTo((int)(p1.x + 8*Math.cos(t-PHI)), (int)(p1.y + 8*Math.sin(t-PHI))); 908 978 } … … public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh 911 981 g2.setStroke(new BasicStroke(1)); 912 982 } 913 983 984 public void paint(Graphics2D g, MapView mv, Bounds box) { 985 if (!drawHelperLine || wayIsFinished || (shift && (ctrl || Main.map.mapView.getNearestNode(mousePos) == null))) return; 986 987 // sanity checks 988 if (Main.map.mapView == null) return; 989 if (mousePos == null) return; 990 991 // don't draw line if we don't know where from or where to 992 if (currentBaseNode == null || currentMouseEastNorth == null) return; 993 994 // don't draw line if mouse is outside window 995 if (!Main.map.mapView.getBounds().contains(mousePos)) return; 996 997 if (shift && currentBaseNode != currentMouseNode) { 998 List<Node> nodes = getFollowWayNodes(currentBaseNode, currentMouseNode); 999 drawHelperLine(g, mv, mv.getPoint(currentBaseNode), mv.getPoint(nodes.get(0)), alt); 1000 1001 Node previousNode = null; 1002 for (Node node : nodes) { 1003 if (previousNode != null) 1004 drawHelperLine(g, mv, mv.getPoint(previousNode), mv.getPoint(node), false); 1005 previousNode = node; 1006 } 1007 } else { 1008 drawHelperLine(g, mv, mv.getPoint(currentBaseNode), mv.getPoint(currentMouseEastNorth), alt); 1009 } 1010 } 1011 914 1012 @Override public String getModeHelpText() { 915 1013 String rv = ""; 916 1014 /*
