Changeset 12778 in osm for applications/editors/josm/plugins/duplicateway/src/org
- Timestamp:
- 2009-01-01T18:28:53+01:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/duplicateway/src/org/openstreetmap/josm/plugins/duplicateway
- Files:
-
- 2 edited
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 62 63 64 65 66 67 68 69 70 71 * 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 * 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 * 136 137 138 139 140 141 142 143 144 145 146 147 148 149 * 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 * 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 * 264 265 266 267 268 269 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.