Changeset 12778 in osm for applications/editors/josm/plugins/duplicateway/src
- Timestamp:
- 2009-01-01T18:28:53+01:00 (17 years ago)
- Location:
- applications/editors/josm/plugins/duplicateway/src/org/openstreetmap/josm/plugins/duplicateway
- Files:
-
- 2 edited
-
DuplicateWayAction.java (modified) (1 diff)
-
DuplicateWayPlugin.java (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/duplicateway/src/org/openstreetmap/josm/plugins/duplicateway/DuplicateWayAction.java
r12694 r12778 34 34 /** 35 35 * Duplicate an existing set of ordered ways, offset by a specified distance. 36 * 36 * 37 37 * This basic version just creates a completely seperate way and makes no 38 38 * attempt to attach it to any other ways. 39 * 39 * 40 40 * Planned Improvements: 41 * 41 * 42 42 * 1. After creation of the duplicate way and while it is still selected allow 43 43 * the Mouse wheel, or the up and down arrow (probably in association with the 44 44 * shift key) to increase/decrease the offset distance. Clicking anywhere, or 45 45 * moving the mouse out of the view window should finish this mode. 46 * 46 * 47 47 * 2. Locate points close to the end points and pop up a dialog asking of these 48 48 * should be joined. 49 * 49 * 50 50 * 3. Handle intersecting ways. Pop up a dialog for each asking if the 51 51 * intersecting way should be carried accross to intersect the newly created 52 52 * way. Handle multiple intersecting ways at a point. 53 * 54 * 53 * 54 * 55 55 * @author Brent Easton 56 * 56 * 57 57 */ 58 58 public class DuplicateWayAction extends MapMode implements 59 59 SelectionChangedListener, MouseListener { 60 60 61 private static final long serialVersionUID = 1L;62 63 protected Cursor oldCursor;64 65 protected List<Way> selectedWays;66 67 protected MapMode previousMode;68 69 /**70 * Create new DuplicateWay Action71 * 72 * @param name73 */74 public DuplicateWayAction() {75 super(tr("Duplicate Way"), "duplicateway",76 tr("Duplicate selected ways."), KeyEvent.VK_W, null,77 ImageProvider.getCursor("crosshair", "duplicate"));78 setEnabled(false);79 DataSet.listeners.add(this);80 }81 82 @Override public void enterMode() {83 super.enterMode();84 Main.map.mapView.addMouseListener(this);85 }86 87 @Override public void exitMode() {88 super.exitMode();89 Main.map.mapView.removeMouseListener(this);90 }91 92 /**93 * The Duplicate Way button has been clicked94 * 95 * @param e96 * Action Event97 */98 @Override public void actionPerformed(ActionEvent e) {99 100 selectedWays = new ArrayList<Way>();101 for (OsmPrimitive osm : Main.ds.getSelected()) {102 if (osm instanceof Way) {103 Way way = (Way)osm;104 EastNorth last = null;105 for (Segment seg : way.segments) {106 if (last != null) {107 if (!seg.from.eastNorth.equals(last)) {108 JOptionPane.showMessageDialog(Main.parent,109 tr("Can't duplicate unordered way."));110 return;111 }112 }113 last = seg.to.eastNorth;114 }115 selectedWays.add(way);116 }117 }118 119 if (Main.map == null) {120 JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));121 return;122 }123 124 if (selectedWays.isEmpty()) {125 JOptionPane.showMessageDialog(Main.parent,126 tr("You must select at least one way."));127 return;128 }129 previousMode = Main.map.mapMode;130 super.actionPerformed(e);131 }132 133 /**134 * Create a new Node object at a specified Easting/Northing location135 * 136 * @param east137 * Easting of new Node138 * @param north139 * Northing of new node140 * @return new Node141 */142 public static Node createNode(double east, double north) {143 return new Node(Main.proj.eastNorth2latlon(new EastNorth(east, north)));144 }145 146 /**147 * Duplicate the selected ways. The distance to be offset is determined by148 * finding the distance of the 'offset' point from the nearest segment.149 * 150 * @param clickPoint151 * The point in screen co-ordinates used to calculate the offset152 * distance153 */154 protected void duplicate(Point clickPoint) {155 156 EastNorth clickEN = Main.map.mapView.getEastNorth(clickPoint.x,157 clickPoint.y);158 159 /*160 * First, find the nearest Segment belonging to a selected way161 */162 Segment cs = null;163 for (Way way : selectedWays) {164 double minDistance = Double.MAX_VALUE;165 // segments166 for (Segment ls : way.segments) {167 if (ls.deleted || ls.incomplete)168 continue;169 double perDist = JVector.perpDistance(ls, clickEN);170 if (perDist < minDistance) {171 minDistance = perDist;172 cs = ls;173 }174 }175 }176 177 if (cs == null) {178 return;179 }180 181 /*182 * Find the distance we need to offset the new way +ve offset is to the183 * right of the initial way, -ve to the left184 */185 JVector closestSegment = new JVector(cs);186 double offset = closestSegment.calculateOffset(clickEN);187 188 Collection<Command> commands = new LinkedList<Command>();189 Collection<Way> ways = new LinkedList<Way>();190 191 /*192 * First new node is offset 90 degrees from the first point193 */194 for (Way way : selectedWays) {195 Way newWay = new Way();196 197 Node lastNode = null;198 JVector lastLine = null;199 200 for (Segment seg : way.segments) {201 JVector currentLine = new JVector(seg);202 Node newNode = null;203 204 if (lastNode == null) {205 JVector perpVector = new JVector(currentLine);206 perpVector.rotate90(offset);207 newNode = createNode(perpVector.getP2().getX(), perpVector208 .getP2().getY());209 commands.add(new AddCommand(newNode));210 } else {211 JVector bisector = lastLine.bisector(currentLine, offset);212 newNode = createNode(bisector.getP2().getX(), bisector213 .getP2().getY());214 commands.add(new AddCommand(newNode));215 Segment s = new Segment(newNode, lastNode);216 commands.add(new AddCommand(s));217 newWay.segments.add(0, s);218 }219 220 lastLine = currentLine;221 lastNode = newNode;222 223 }224 lastLine.reverse();225 lastLine.rotate90(-offset);226 Node newNode = createNode(lastLine.getP2().getX(), lastLine.getP2()227 .getY());228 commands.add(new AddCommand(newNode));229 Segment s = new Segment(newNode, lastNode);230 commands.add(new AddCommand(s));231 newWay.segments.add(0, s);232 233 for (String key : way.keySet()) {234 newWay.put(key, way.get(key));235 }236 commands.add(new AddCommand(newWay));237 ways.add(newWay);238 }239 240 Main.main.undoRedo.add(new SequenceCommand(tr("Create duplicate way"),241 commands));242 Main.ds.setSelected(ways);243 }244 245 /**246 * Enable the "Duplicate way" menu option if at least one way is selected247 * 248 * @param newSelection249 */250 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {251 for (OsmPrimitive osm : newSelection) {252 if (osm instanceof Way) {253 setEnabled(true);254 return;255 }256 }257 setEnabled(false);258 }259 260 /**261 * User has clicked on map to indicate the offset. Create the262 * duplicate way and exit duplicate mode263 * 264 * @param e265 */266 public void mouseClicked(MouseEvent e) {267 duplicate(e.getPoint());268 exitMode();269 Main.map.selectMapMode(previousMode);270 }61 private static final long serialVersionUID = 1L; 62 63 protected Cursor oldCursor; 64 65 protected List<Way> selectedWays; 66 67 protected MapMode previousMode; 68 69 /** 70 * Create new DuplicateWay Action 71 * 72 * @param name 73 */ 74 public DuplicateWayAction() { 75 super(tr("Duplicate Way"), "duplicateway", 76 tr("Duplicate selected ways."), KeyEvent.VK_W, null, 77 ImageProvider.getCursor("crosshair", "duplicate")); 78 setEnabled(false); 79 DataSet.listeners.add(this); 80 } 81 82 @Override public void enterMode() { 83 super.enterMode(); 84 Main.map.mapView.addMouseListener(this); 85 } 86 87 @Override public void exitMode() { 88 super.exitMode(); 89 Main.map.mapView.removeMouseListener(this); 90 } 91 92 /** 93 * The Duplicate Way button has been clicked 94 * 95 * @param e 96 * Action Event 97 */ 98 @Override public void actionPerformed(ActionEvent e) { 99 100 selectedWays = new ArrayList<Way>(); 101 for (OsmPrimitive osm : Main.ds.getSelected()) { 102 if (osm instanceof Way) { 103 Way way = (Way)osm; 104 EastNorth last = null; 105 for (Segment seg : way.segments) { 106 if (last != null) { 107 if (!seg.from.eastNorth.equals(last)) { 108 JOptionPane.showMessageDialog(Main.parent, 109 tr("Can't duplicate unordered way.")); 110 return; 111 } 112 } 113 last = seg.to.eastNorth; 114 } 115 selectedWays.add(way); 116 } 117 } 118 119 if (Main.map == null) { 120 JOptionPane.showMessageDialog(Main.parent, tr("No data loaded.")); 121 return; 122 } 123 124 if (selectedWays.isEmpty()) { 125 JOptionPane.showMessageDialog(Main.parent, 126 tr("You must select at least one way.")); 127 return; 128 } 129 previousMode = Main.map.mapMode; 130 super.actionPerformed(e); 131 } 132 133 /** 134 * Create a new Node object at a specified Easting/Northing location 135 * 136 * @param east 137 * Easting of new Node 138 * @param north 139 * Northing of new node 140 * @return new Node 141 */ 142 public static Node createNode(double east, double north) { 143 return new Node(Main.proj.eastNorth2latlon(new EastNorth(east, north))); 144 } 145 146 /** 147 * Duplicate the selected ways. The distance to be offset is determined by 148 * finding the distance of the 'offset' point from the nearest segment. 149 * 150 * @param clickPoint 151 * The point in screen co-ordinates used to calculate the offset 152 * distance 153 */ 154 protected void duplicate(Point clickPoint) { 155 156 EastNorth clickEN = Main.map.mapView.getEastNorth(clickPoint.x, 157 clickPoint.y); 158 159 /* 160 * First, find the nearest Segment belonging to a selected way 161 */ 162 Segment cs = null; 163 for (Way way : selectedWays) { 164 double minDistance = Double.MAX_VALUE; 165 // segments 166 for (Segment ls : way.segments) { 167 if (ls.deleted || ls.incomplete) 168 continue; 169 double perDist = JVector.perpDistance(ls, clickEN); 170 if (perDist < minDistance) { 171 minDistance = perDist; 172 cs = ls; 173 } 174 } 175 } 176 177 if (cs == null) { 178 return; 179 } 180 181 /* 182 * Find the distance we need to offset the new way +ve offset is to the 183 * right of the initial way, -ve to the left 184 */ 185 JVector closestSegment = new JVector(cs); 186 double offset = closestSegment.calculateOffset(clickEN); 187 188 Collection<Command> commands = new LinkedList<Command>(); 189 Collection<Way> ways = new LinkedList<Way>(); 190 191 /* 192 * First new node is offset 90 degrees from the first point 193 */ 194 for (Way way : selectedWays) { 195 Way newWay = new Way(); 196 197 Node lastNode = null; 198 JVector lastLine = null; 199 200 for (Segment seg : way.segments) { 201 JVector currentLine = new JVector(seg); 202 Node newNode = null; 203 204 if (lastNode == null) { 205 JVector perpVector = new JVector(currentLine); 206 perpVector.rotate90(offset); 207 newNode = createNode(perpVector.getP2().getX(), perpVector 208 .getP2().getY()); 209 commands.add(new AddCommand(newNode)); 210 } else { 211 JVector bisector = lastLine.bisector(currentLine, offset); 212 newNode = createNode(bisector.getP2().getX(), bisector 213 .getP2().getY()); 214 commands.add(new AddCommand(newNode)); 215 Segment s = new Segment(newNode, lastNode); 216 commands.add(new AddCommand(s)); 217 newWay.segments.add(0, s); 218 } 219 220 lastLine = currentLine; 221 lastNode = newNode; 222 223 } 224 lastLine.reverse(); 225 lastLine.rotate90(-offset); 226 Node newNode = createNode(lastLine.getP2().getX(), lastLine.getP2() 227 .getY()); 228 commands.add(new AddCommand(newNode)); 229 Segment s = new Segment(newNode, lastNode); 230 commands.add(new AddCommand(s)); 231 newWay.segments.add(0, s); 232 233 for (String key : way.keySet()) { 234 newWay.put(key, way.get(key)); 235 } 236 commands.add(new AddCommand(newWay)); 237 ways.add(newWay); 238 } 239 240 Main.main.undoRedo.add(new SequenceCommand(tr("Create duplicate way"), 241 commands)); 242 Main.ds.setSelected(ways); 243 } 244 245 /** 246 * Enable the "Duplicate way" menu option if at least one way is selected 247 * 248 * @param newSelection 249 */ 250 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 251 for (OsmPrimitive osm : newSelection) { 252 if (osm instanceof Way) { 253 setEnabled(true); 254 return; 255 } 256 } 257 setEnabled(false); 258 } 259 260 /** 261 * User has clicked on map to indicate the offset. Create the 262 * duplicate way and exit duplicate mode 263 * 264 * @param e 265 */ 266 public void mouseClicked(MouseEvent e) { 267 duplicate(e.getPoint()); 268 exitMode(); 269 Main.map.selectMapMode(previousMode); 270 } 271 271 } -
applications/editors/josm/plugins/duplicateway/src/org/openstreetmap/josm/plugins/duplicateway/DuplicateWayPlugin.java
r4651 r12778 11 11 /** 12 12 * A plugin to add a duplicate way option to assist with creating divided roads 13 * 13 * 14 14 * @author Brent Easton 15 15 */ … … 38 38 toolsMenu.add(new JMenuItem(new DuplicateWayAction())); 39 39 } 40 40 41 41 } 42 42
Note:
See TracChangeset
for help on using the changeset viewer.
