source: josm/trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java@ 4077

Last change on this file since 4077 was 3713, checked in by jttt, 13 years ago

Fix #5724 Merge node to the nearest one

  • Property svn:eol-style set to native
File size: 4.0 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.LinkedList;
15import java.util.List;
16import java.util.Map;
17
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.command.ChangeCommand;
20import org.openstreetmap.josm.command.Command;
21import org.openstreetmap.josm.command.SequenceCommand;
22import org.openstreetmap.josm.data.osm.Node;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.Way;
25import org.openstreetmap.josm.data.osm.WaySegment;
26import org.openstreetmap.josm.tools.Shortcut;
27
28public class JoinNodeWayAction extends JosmAction {
29 public JoinNodeWayAction() {
30 super(tr("Join Node to Way"), "joinnodeway", tr("Join a node into the nearest way segments"),
31 Shortcut.registerShortcut("tools:joinnodeway", tr("Tool: {0}", tr("Join Node to Way")), KeyEvent.VK_J, Shortcut.GROUP_EDIT), true);
32 putValue("help", ht("/Action/JoinNodeWay"));
33 }
34
35 public void actionPerformed(ActionEvent e) {
36 if (!isEnabled())
37 return;
38 Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected();
39 if (sel.size() < 1) return;
40
41 Collection<Command> cmds = new LinkedList<Command>();
42
43 for (OsmPrimitive osm : sel) {
44 if (!(osm instanceof Node)) {
45 continue;
46 }
47 Node node = (Node) osm;
48
49 List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(
50 Main.map.mapView.getPoint(node), OsmPrimitive.isSelectablePredicate);
51 HashMap<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
52 for (WaySegment ws : wss) {
53 List<Integer> is;
54 if (insertPoints.containsKey(ws.way)) {
55 is = insertPoints.get(ws.way);
56 } else {
57 is = new ArrayList<Integer>();
58 insertPoints.put(ws.way, is);
59 }
60
61 if (ws.way.getNode(ws.lowerIndex) != node
62 && ws.way.getNode(ws.lowerIndex+1) != node) {
63 is.add(ws.lowerIndex);
64 }
65 }
66
67 for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
68 List<Integer> is = insertPoint.getValue();
69 if (is.size() == 0) {
70 continue;
71 }
72
73 Way w = insertPoint.getKey();
74 List<Node> nodesToAdd = w.getNodes();
75 pruneSuccsAndReverse(is);
76 for (int i : is) {
77 nodesToAdd.add(i+1, node);
78 }
79 Way wnew = new Way(w);
80 wnew.setNodes(nodesToAdd);
81 cmds.add(new ChangeCommand(w, wnew));
82 }
83 }
84 if (cmds.size() == 0) return;
85 Main.main.undoRedo.add(new SequenceCommand(tr("Join Node and Line"), cmds));
86 Main.map.repaint();
87 }
88
89 private static void pruneSuccsAndReverse(List<Integer> is) {
90 //if (is.size() < 2) return;
91
92 HashSet<Integer> is2 = new HashSet<Integer>();
93 for (int i : is) {
94 if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
95 is2.add(i);
96 }
97 }
98 is.clear();
99 is.addAll(is2);
100 Collections.sort(is);
101 Collections.reverse(is);
102 }
103
104 @Override
105 protected void updateEnabledState() {
106 if (getCurrentDataSet() == null) {
107 setEnabled(false);
108 } else {
109 updateEnabledState(getCurrentDataSet().getSelected());
110 }
111 }
112
113 @Override
114 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
115 setEnabled(selection != null && !selection.isEmpty());
116 }
117}
Note: See TracBrowser for help on using the repository browser.