source: josm/trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java@ 4086

Last change on this file since 4086 was 4086, checked in by bastiK, 13 years ago

new follow line action (author: Germán Márquez Mejía) fixes #4190

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.util.Collection;
9import java.util.Iterator;
10import java.util.List;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.actions.mapmode.DrawAction;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.gui.layer.OsmDataLayer;
19import org.openstreetmap.josm.tools.Shortcut;
20
21/**
22 * Follow line action - Makes easier to draw a line that shares points with another line
23 *
24 * Aimed at those who want to draw two or more lines related with
25 * each other, but carry different information (i.e. a river acts as boundary at
26 * some part of its course. It preferable to have a separated boundary line than to
27 * mix totally different kind of features in one single way).
28 *
29 * @author Germán Márquez Mejía
30 */
31public class FollowLineAction extends JosmAction {
32
33 public FollowLineAction() {
34 super(
35 tr("Follow line"),
36 "followline.png",
37 tr("Continues drawing a line that shares nodes with another line."),
38 Shortcut.registerShortcut("tools:followline", tr(
39 "Tool: {0}", tr("Follow")),
40 KeyEvent.VK_F, Shortcut.GROUP_EDIT), true);
41 }
42
43 @Override
44 protected void updateEnabledState() {
45 if (getCurrentDataSet() == null) {
46 setEnabled(false);
47 } else {
48 updateEnabledState(getCurrentDataSet().getSelected());
49 }
50 }
51
52 @Override
53 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
54 setEnabled(selection != null && !selection.isEmpty());
55 }
56
57 @Override
58 public void actionPerformed(ActionEvent evt) {
59 OsmDataLayer osmLayer = Main.main.getEditLayer();
60 if (osmLayer == null)
61 return;
62 if (!(Main.map.mapMode instanceof DrawAction)) return; // We are not on draw mode
63
64 Collection<Node> selectedPoints = osmLayer.data.getSelectedNodes();
65 Collection<Way> selectedLines = osmLayer.data.getSelectedWays();
66 if ((selectedPoints.size() > 1) || (selectedLines.size() != 1)) // Unsuitable selection
67 return;
68
69 Node last = ((DrawAction) Main.map.mapMode).getCurrentBaseNode();
70 Way follower = selectedLines.iterator().next();
71 Node prev = follower.getNode(1);
72 boolean reversed = true;
73 if (follower.lastNode().equals(last)) {
74 prev = follower.getNode(follower.getNodesCount() - 2);
75 reversed = false;
76 }
77 List<OsmPrimitive> referrers = last.getReferrers();
78 if (referrers.size() < 2) return; // There's nothing to follow
79
80 Iterator<OsmPrimitive> i = referrers.iterator();
81 while (i.hasNext()) {
82 OsmPrimitive referrer = i.next();
83 if (!referrer.getType().equals(OsmPrimitiveType.WAY)) { // Can't follow points or relations
84 continue;
85 }
86 Way toFollow = (Way) referrer;
87 if (toFollow.equals(follower)) {
88 continue;
89 }
90 List<Node> points = toFollow.getNodes();
91 int indexOfLast = points.indexOf(last);
92 int indexOfPrev = points.indexOf(prev);
93 if ((indexOfLast == -1) || (indexOfPrev == -1)) { // Both points must belong to both lines
94 continue;
95 }
96 if (Math.abs(indexOfPrev - indexOfLast) != 1) { // ...and be consecutive
97 continue;
98 }
99 Node newPoint = null;
100 if (indexOfPrev == (indexOfLast - 1)) {
101 if ((indexOfLast + 1) < points.size()) {
102 newPoint = points.get(indexOfLast + 1);
103 }
104 } else {
105 if ((indexOfLast - 1) >= 0) {
106 newPoint = points.get(indexOfLast - 1);
107 }
108 }
109 if (newPoint != null) {
110 if (reversed) {
111 follower.addNode(0, newPoint);
112 } else {
113 follower.addNode(newPoint);
114 }
115 osmLayer.data.clearSelection();
116 osmLayer.data.addSelected(follower);
117 osmLayer.data.addSelected(newPoint);
118 return;
119 }
120 }
121 }
122}
Note: See TracBrowser for help on using the repository browser.