[466] | 1 | //License: GPL. Copyright 2007 by Immanuel Scholz and others
|
---|
| 2 | package org.openstreetmap.josm.actions;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
[582] | 6 | import java.awt.event.ActionEvent;
|
---|
| 7 | import java.awt.event.KeyEvent;
|
---|
[466] | 8 | import java.util.ArrayList;
|
---|
| 9 | import java.util.Collection;
|
---|
| 10 | import java.util.Collections;
|
---|
| 11 | import java.util.HashMap;
|
---|
| 12 | import java.util.HashSet;
|
---|
[582] | 13 | import java.util.LinkedList;
|
---|
| 14 | import java.util.List;
|
---|
[466] | 15 | import java.util.Map;
|
---|
| 16 |
|
---|
| 17 | import org.openstreetmap.josm.Main;
|
---|
[582] | 18 | import org.openstreetmap.josm.command.ChangeCommand;
|
---|
[466] | 19 | import org.openstreetmap.josm.command.Command;
|
---|
| 20 | import org.openstreetmap.josm.command.SequenceCommand;
|
---|
[582] | 21 | import org.openstreetmap.josm.data.osm.Node;
|
---|
[466] | 22 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
[582] | 23 | import org.openstreetmap.josm.data.osm.Way;
|
---|
| 24 | import org.openstreetmap.josm.data.osm.WaySegment;
|
---|
[1084] | 25 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
[466] | 26 |
|
---|
| 27 | public class JoinNodeWayAction extends JosmAction {
|
---|
| 28 | public JoinNodeWayAction() {
|
---|
[1023] | 29 | super(tr("Join node to way"), "joinnodeway", tr("Join a node into the nearest way segments"),
|
---|
[1084] | 30 | Shortcut.registerShortcut("tools:joinnodeway", tr("Tool: {0}", tr("Join node to way")), KeyEvent.VK_J, Shortcut.GROUP_EDIT), true);
|
---|
[466] | 31 | }
|
---|
| 32 |
|
---|
| 33 | public void actionPerformed(ActionEvent e) {
|
---|
| 34 | Collection<OsmPrimitive> sel = Main.ds.getSelected();
|
---|
| 35 | if (sel.size() != 1 || !(sel.iterator().next() instanceof Node)) return;
|
---|
| 36 | Node node = (Node) sel.iterator().next();
|
---|
| 37 |
|
---|
| 38 | List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(
|
---|
| 39 | Main.map.mapView.getPoint(node.eastNorth));
|
---|
| 40 | HashMap<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
|
---|
| 41 | for (WaySegment ws : wss) {
|
---|
| 42 | List<Integer> is;
|
---|
| 43 | if (insertPoints.containsKey(ws.way)) {
|
---|
| 44 | is = insertPoints.get(ws.way);
|
---|
| 45 | } else {
|
---|
| 46 | is = new ArrayList<Integer>();
|
---|
| 47 | insertPoints.put(ws.way, is);
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | if (ws.way.nodes.get(ws.lowerIndex) != node
|
---|
| 51 | && ws.way.nodes.get(ws.lowerIndex+1) != node) {
|
---|
| 52 | is.add(ws.lowerIndex);
|
---|
| 53 | }
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | Collection<Command> cmds = new LinkedList<Command>();
|
---|
| 57 | for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
|
---|
| 58 | Way w = insertPoint.getKey();
|
---|
| 59 | Way wnew = new Way(w);
|
---|
| 60 | List<Integer> is = insertPoint.getValue();
|
---|
| 61 | pruneSuccsAndReverse(is);
|
---|
| 62 | for (int i : is) wnew.nodes.add(i+1, node);
|
---|
| 63 | cmds.add(new ChangeCommand(w, wnew));
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | Main.main.undoRedo.add(new SequenceCommand(tr("Join Node and Line"), cmds));
|
---|
| 67 | Main.map.repaint();
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | private static void pruneSuccsAndReverse(List<Integer> is) {
|
---|
| 71 | //if (is.size() < 2) return;
|
---|
| 72 |
|
---|
| 73 | HashSet<Integer> is2 = new HashSet<Integer>();
|
---|
| 74 | for (int i : is) {
|
---|
| 75 | if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
|
---|
| 76 | is2.add(i);
|
---|
| 77 | }
|
---|
| 78 | }
|
---|
| 79 | is.clear();
|
---|
| 80 | is.addAll(is2);
|
---|
| 81 | Collections.sort(is);
|
---|
| 82 | Collections.reverse(is);
|
---|
| 83 | }
|
---|
| 84 | }
|
---|