Changeset 23189 in osm for applications/editors/josm/plugins/alignways
- Timestamp:
- 2010-09-15T18:53:09+02:00 (15 years ago)
- Location:
- applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysAction.java
r23082 r23189 24 24 public class AlignWaysAction extends JosmAction { 25 25 26 27 28 29 26 /** 27 * 28 */ 29 private static final long serialVersionUID = -1540319652562985458L; 30 30 31 32 33 34 35 36 37 38 39 31 public AlignWaysAction() { 32 super(tr("Align Way Segments"), "alignways", 33 tr("Makes a pair of selected way segments parallel by rotating one of them " + 34 "around a chosen pivot."), 35 Shortcut.registerShortcut("tools:alignways", tr("Tool: {0}", 36 tr("Align Ways")), KeyEvent.VK_A, Shortcut.GROUP_EDIT, 37 Shortcut.SHIFT_DEFAULT), true); 38 setEnabled(false); 39 } 40 40 41 42 43 44 45 41 public void actionPerformed(ActionEvent e) { 42 if (!isEnabled()) 43 return; 44 if (getCurrentDataSet() == null) 45 return; 46 46 47 47 Collection<Node> affectedNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView).getSelectedNodes(); 48 48 49 50 51 49 Command c = !Main.main.undoRedo.commands.isEmpty() ? Main.main.undoRedo.commands 50 .getLast() 51 : null; 52 52 53 54 55 56 57 58 59 53 if (!(c instanceof AlignWaysRotateCommand && 54 affectedNodes.equals(((AlignWaysRotateCommand) c).getRotatedNodes()))) { 55 c = new AlignWaysRotateCommand(); 56 if (actionValid((AlignWaysRotateCommand)c, affectedNodes)) { 57 Main.main.undoRedo.add(c); 58 } 59 } 60 60 61 61 Main.map.mapView.repaint(); 62 62 63 64 63 return; 64 } 65 65 66 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 67 /** 68 * Validates the circumstances of the alignment (rotation) command to be executed. 69 * @param c Command to be verified. 70 * @param affectedNodes Nodes to be affected by the action. 71 * @return true if the aligning action can be done, false otherwise. 72 */ 73 private boolean actionValid(AlignWaysRotateCommand c, Collection<Node> affectedNodes) { 74 // Deny action if reference and alignee segment cannot be aligned 75 if (!c.areSegsAlignable()) { 76 JOptionPane.showMessageDialog(Main.parent, 77 tr("Please select two segments that don''t share any nodes\n" 78 + " or put the pivot on their common node.\n"), 79 tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE); 80 return false; 81 } 82 82 83 84 85 86 87 88 89 90 91 92 83 // Deny action if the nodes would end up outside world 84 for (Node n : affectedNodes) { 85 if (n.getCoor().isOutSideWorld()) { 86 // Revert move 87 (c).undoCommand(); 88 JOptionPane.showMessageDialog(Main.parent, 89 tr("Aligning would result nodes outside the world.\n"), 90 tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE); 91 return false; 92 } 93 93 94 94 } 95 95 96 97 98 96 // Action valid 97 return true; 98 } 99 99 100 100 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysAlgnSegment.java
r21613 r23189 26 26 public class AlignWaysAlgnSegment extends AlignWaysSegment { 27 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 28 private enum PivotLocations { 29 NONE, NODE1, NODE2, CENTRE 30 }; 31 32 private PivotLocations currPivot; 33 Map<PivotLocations, EastNorth> pivotList = new EnumMap<PivotLocations, EastNorth>( 34 PivotLocations.class); 35 private final Color pivotColor = Color.YELLOW; 36 private final Color crossColor = pivotColor; 37 38 public AlignWaysAlgnSegment(MapView mapview, Point p) 39 throws IllegalArgumentException { 40 super(mapview, p); 41 setSegment(getNearestWaySegment(p)); 42 segmentColor = Color.ORANGE; 43 } 44 45 /** 46 * Sets segment and initialises its pivot list and activates the centre 47 * rotation pivot. 48 */ 49 @Override 50 public void setSegment(WaySegment segment) { 51 super.setSegment(segment); 52 setPivots(); 53 } 54 55 /** 56 * Useful when segments moves (or e.g. rotates) on the map. Updates the end 57 * segment points and the pivot coordinates without changing the current 58 * pivot. 59 */ 60 public void updatePivotsEndpoints() { 61 setPivots(currPivot); 62 setSegmentEndpoints(segment); 63 } 64 65 /** 66 * Updates the segment's pivot list and sets the rotation pivot to centre. 67 */ 68 private void setPivots(PivotLocations pivotRef) { 69 if (segment != null) { 70 for (PivotLocations pl : PivotLocations.values()) { 71 pivotList.put(pl, getPivotCoord(pl)); 72 } 73 setPivotReference(pivotRef); 74 } else { 75 setPivotReference(PivotLocations.NONE); 76 } 77 } 78 79 private void setPivots() { 80 setPivots(PivotLocations.CENTRE); 81 } 82 83 private void setPivotReference(PivotLocations pp) { 84 currPivot = pp; 85 } 86 87 /** 88 * Returns the EastNorth of the specified pivot point pp. It always returns 89 * up-to-date data from dataset. Assumes segment is not null. 90 * 91 * @param pp 92 * The pivot location 93 */ 94 private EastNorth getPivotCoord(PivotLocations pp) { 95 switch (pp) { 96 case NONE: 97 return null; 98 case NODE1: 99 return segment.way.getNode(segment.lowerIndex).getEastNorth(); 100 case NODE2: 101 return segment.way.getNode(segment.lowerIndex + 1).getEastNorth(); 102 case CENTRE: 103 return getPivotCoord(PivotLocations.NODE1).getCenter( 104 getPivotCoord(PivotLocations.NODE2)); 105 default: 106 // Should never happen 107 return null; 108 } 109 } 110 111 /** 112 * @return The EastNorth of the currently selected pivot. 113 */ 114 public EastNorth getCurrPivotCoord() { 115 if (segment != null) 116 return getPivotCoord(currPivot); 117 return null; 118 } 119 120 /** 121 * @param clickedPoint 122 * Pivot may be updated in the vicinity of this point 123 * @return true if a pivot is within reach on the segment, false otherwise 124 */ 125 public boolean updatePivot(Point clickedPoint) { 126 // tHQ Done. 127 PivotLocations tmpPivot = findNearbyPivot(clickedPoint); 128 if (tmpPivot != PivotLocations.NONE) { 129 setPivotReference(tmpPivot); 130 return true; 131 } else 132 return false; 133 } 134 135 private PivotLocations findNearbyPivot(Point clickedPoint) { 136 PivotLocations nearest = PivotLocations.NONE; 137 int snapDistance = NavigatableComponent.snapDistance; 138 139 // If no alignee selected yet, there's no point to carry on 140 if (segment == null) 141 return PivotLocations.NONE; 142 143 for (PivotLocations pl : PivotLocations.values()) { 144 if (pl.equals(PivotLocations.NONE)) { 145 continue; 146 } 147 if (mapview.getPoint(pivotList.get(pl)).distance(clickedPoint) <= snapDistance) { 148 nearest = pl; 149 break; 150 } 151 } 152 return nearest; 153 } 154 155 /* 156 * (non-Javadoc) 157 * 158 * @see 159 * org.openstreetmap.josm.plugins.alignways.AlignWaysRefSegment#paint(java 160 * .awt.Graphics2D, org.openstreetmap.josm.gui.MapView, 161 * org.openstreetmap.josm.data.Bounds) 162 */ 163 @Override 164 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 165 // Note: segment should never be null here 166 super.paint(g, mv, bbox); 167 168 // Highlight potential pivot points 169 for (PivotLocations pl : PivotLocations.values()) { 170 if (pl != PivotLocations.NONE) { 171 highlightCross(g, mv, pivotList.get(pl)); 172 } 173 } 174 175 // Highlight active pivot 176 highlightPivot(g, mv, getPivotCoord(currPivot)); 177 178 } 179 180 private void highlightPivot(Graphics2D g, MapView mv, EastNorth pivot) { 181 g.setColor(pivotColor); 182 g.setStroke(new BasicStroke()); 183 184 Shape pvCentrePoint = new Ellipse2D.Double( 185 mv.getPoint(pivot).getX() - 5.0f, 186 mv.getPoint(pivot).getY() - 5.0f, 10.0f, 10.0f); 187 g.fill(pvCentrePoint); 188 Shape pvPoint = new Ellipse2D.Double(mv.getPoint(pivot).getX() - 8.0f, 189 mv.getPoint(pivot).getY() - 8.0f, 16.0f, 16.0f); 190 191 g.draw(pvCentrePoint); 192 g.draw(pvPoint); 193 } 194 195 private void highlightCross(Graphics2D g, MapView mv, EastNorth en) { 196 197 double crossX = mv.getPoint(en).getX(); 198 double crossY = mv.getPoint(en).getY(); 199 double crossSize = 10.0; 200 201 Line2D crossV = new Line2D.Double(crossX, crossY - crossSize, crossX, 202 crossY + crossSize); 203 Line2D crossH = new Line2D.Double(crossX - crossSize, crossY, crossX 204 + crossSize, crossY); 205 206 g.setColor(crossColor); 207 g.setStroke(new BasicStroke()); 208 g.draw(crossV); 209 g.draw(crossH); 210 211 } 212 212 213 213 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysPlugin.java
r21613 r23189 20 20 public class AlignWaysPlugin extends Plugin { 21 21 22 23 24 25 22 static AlignWaysMode awMode; 23 private final IconToggleButton btn; 24 static JMenuItem alignWaysMenuItem; 25 static JosmAction awAction; 26 26 27 28 29 30 31 32 33 34 35 36 37 38 27 /** 28 * 29 */ 30 public AlignWaysPlugin(PluginInformation info) { 31 super(info); 32 awMode = new AlignWaysMode(Main.map, "alignways", tr("Align Ways mode")); 33 btn = new IconToggleButton(awMode); 34 btn.setVisible(true); 35 Main.main.menu.toolsMenu.addSeparator(); 36 awAction = new AlignWaysAction(); 37 alignWaysMenuItem = MainMenu.add(Main.main.menu.toolsMenu, awAction); 38 Main.main.menu.toolsMenu.addSeparator(); 39 39 40 40 } 41 41 42 43 44 45 46 47 42 @Override 43 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 44 if (Main.map != null) { 45 Main.map.addMapMode(btn); 46 } 47 } 48 48 49 50 51 52 53 54 49 /** 50 * @return the awAction 51 */ 52 public static JosmAction getAwAction() { 53 return awAction; 54 } 55 55 56 57 58 59 60 61 56 /** 57 * @return the awMode 58 */ 59 public static AlignWaysMode getAwMode() { 60 return awMode; 61 } 62 62 63 63 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysRefSegment.java
r21613 r23189 15 15 public class AlignWaysRefSegment extends AlignWaysSegment { 16 16 17 17 // Note: segment may be null. This is normal. 18 18 19 20 21 22 23 19 public AlignWaysRefSegment(MapView mapview, Point p) 20 throws IllegalArgumentException { 21 super(mapview, p); 22 setSegment(getNearestWaySegment(p)); 23 segmentColor = Color.GREEN; 24 24 25 25 } 26 26 27 27 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysRotateCommand.java
r22758 r23189 32 32 public class AlignWaysRotateCommand extends Command { 33 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 34 private final AlignWaysAlgnSegment algnSeg; 35 36 /** 37 * The objects to rotate. 38 */ 39 private Collection<Node> nodes = new HashSet<Node>(); 40 41 /** 42 * pivot point 43 */ 44 private final EastNorth pivot; 45 46 /** 47 * Small helper for holding the interesting part of the old data state of 48 * the objects. 49 */ 50 public static class OldState { 51 LatLon latlon; 52 EastNorth eastNorth; 53 WaySegment ws; 54 boolean modified; 55 } 56 57 /** 58 * computed rotation angle to rotate the segment 59 * 60 */ 61 private final double rotationAngle; 62 63 /** 64 * List of all old states of the objects. 65 */ 66 private final Map<Node, OldState> oldState = new HashMap<Node, OldState>(); 67 private final Stack<WaySegment> oldWS = new Stack<WaySegment>(); 68 69 /** 70 * Creates an AlignWaysRotateCommand. 71 */ 72 public AlignWaysRotateCommand() { 73 74 algnSeg = AlignWaysSegmentMgr.getInstance(Main.map.mapView) 75 .getAlgnSeg(); 76 WaySegment algnWS = algnSeg.getSegment(); 77 WaySegment refWS = AlignWaysSegmentMgr.getInstance(Main.map.mapView) 78 .getRefSeg().getSegment(); 79 80 this.pivot = algnSeg.getCurrPivotCoord(); 81 this.nodes = algnSeg.getSegmentEndPoints(); 82 83 EastNorth enRefNode1 = refWS.way.getNode(refWS.lowerIndex) 84 .getEastNorth(); 85 EastNorth enRefNode2 = refWS.way.getNode(refWS.lowerIndex + 1) 86 .getEastNorth(); 87 88 EastNorth enAlgnNode1 = algnWS.way.getNode(algnWS.lowerIndex) 89 .getEastNorth(); 90 EastNorth enAlgnNode2 = algnWS.way.getNode(algnWS.lowerIndex + 1) 91 .getEastNorth(); 92 93 // Calculate the rotation angle 94 double refAngle = Math.atan2(enRefNode1.north() - enRefNode2.north(), 95 enRefNode1.east() - enRefNode2.east()); 96 double algnAngle = Math.atan2( 97 enAlgnNode1.north() - enAlgnNode2.north(), enAlgnNode1.east() 98 - enAlgnNode2.east()); 99 100 rotationAngle = normalise_angle(refAngle - algnAngle); 101 102 /* For debug only 103 String s = "Ref Angle: " + refAngle + " (" + Math.toDegrees(refAngle) 104 + ")\n"; 105 s += "Algn Angle: " + algnAngle + " (" + Math.toDegrees(algnAngle) 106 + ")\n"; 107 s += "Rotation angle: " + rotationAngle + " (" 108 + Math.toDegrees(rotationAngle) + ")"; 109 */ 110 111 // rotateNodes(true); 112 113 } 114 115 /** 116 * Helper for actually rotating the nodes. 117 * 118 * @param setModified 119 * - true if rotated nodes should be flagged "modified" 120 */ 121 private void rotateNodes(boolean setModified) { 122 123 // "Backup" state 124 WaySegment algnWS = algnSeg.getSegment(); 125 for (Node n : this.nodes) { 126 OldState os = new OldState(); 127 os.latlon = new LatLon(n.getCoor()); 128 os.eastNorth = n.getEastNorth(); 129 os.ws = algnWS; 130 os.modified = n.isModified(); 131 oldState.put(n, os); 132 } 133 oldWS.push(algnWS); 134 135 // Rotate 136 for (Node n : nodes) { 137 double cosPhi = Math.cos(rotationAngle); 138 double sinPhi = Math.sin(rotationAngle); 139 EastNorth oldEastNorth = oldState.get(n).eastNorth; 140 double x = oldEastNorth.east() - pivot.east(); 141 double y = oldEastNorth.north() - pivot.north(); 142 double nx = cosPhi * x - sinPhi * y + pivot.east(); 143 double ny = sinPhi * x + cosPhi * y + pivot.north(); 144 n.setEastNorth(new EastNorth(nx, ny)); 145 if (setModified) { 146 n.setModified(true); 147 } 148 } 149 algnSeg.updatePivotsEndpoints(); 150 } 151 152 /** 153 * Make sure angle is in interval ( -Pi/2, Pi/2 ]. 154 */ 155 private static double normalise_angle(double a) { 156 while (a > Math.PI) { 157 a -= 2 * Math.PI; 158 } 159 while (a <= -Math.PI) { 160 a += 2 * Math.PI; 161 } 162 163 if (a > Math.PI / 2) { 164 a -= Math.PI; 165 } else if (a < -Math.PI / 2) { 166 a += Math.PI; 167 } 168 return a; 169 } 170 171 @Override 172 public JLabel getDescription() { 173 return new JLabel(tr("Align way segment"), ImageProvider.get( 174 "", "alignways"), SwingConstants.HORIZONTAL); 175 } 176 177 /* 178 * (non-Javadoc) 179 * 180 * @see 181 * org.openstreetmap.josm.command.Command#fillModifiedData(java.util.Collection 182 * , java.util.Collection, java.util.Collection) 183 */ 184 @Override 185 public void fillModifiedData(Collection<OsmPrimitive> modified, 186 Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 187 for (OsmPrimitive osm : nodes) { 188 modified.add(osm); 189 } 190 } 191 192 /* 193 * (non-Javadoc) 194 * 195 * @see org.openstreetmap.josm.command.Command#executeCommand() 196 */ 197 @Override 198 public boolean executeCommand() { 199 rotateNodes(true); 200 return true; 201 } 202 203 /* 204 * (non-Javadoc) 205 * 206 * @see org.openstreetmap.josm.command.Command#undoCommand() 207 */ 208 @Override 209 public void undoCommand() { 210 for (Node n : nodes) { 211 OldState os = oldState.get(n); 212 n.setCoor(os.latlon); 213 n.setModified(os.modified); 214 } 215 algnSeg.updatePivotsEndpoints(); 216 } 217 218 public Collection<Node> getRotatedNodes() { 219 return nodes; 220 } 221 222 /** Returns true if the two selected segments are alignable. 223 * They are not if they are connected *and* the pivot is not the connection node. 224 */ 225 public boolean areSegsAlignable() { 226 Collection<Node> algnNodes = nodes; 227 Collection<Node> refNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView) 228 .getRefSeg().getSegmentEndPoints(); 229 230 // First check if the pivot node of the alignee exists in the reference: 231 // in this case the pivot is the shared node and alignment is possible 232 for (Node nR : refNodes) { 233 if (nR.getEastNorth().equals(pivot)) 234 return true; 235 } 236 237 // Otherwise if the segments are connected, alignment is not possible 238 for (Node nA : algnNodes) { 239 for (Node nR : refNodes) { 240 if (nA.equals(nR)) 241 return false; 242 } 243 } 244 245 // In all other cases alignment is possible 246 return true; 247 } 248 248 249 249 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSegment.java
r21613 r23189 27 27 public class AlignWaysSegment implements MapViewPaintable { 28 28 29 30 31 32 29 protected WaySegment segment; 30 protected MapView mapview; 31 protected Color segmentColor = Color.WHITE; 32 protected Collection<Node> segmentEndPoints; 33 33 34 35 36 37 38 39 40 41 34 public AlignWaysSegment(MapView mapview, Point p) 35 throws IllegalArgumentException { 36 if (mapview == null) 37 throw new IllegalArgumentException(tr( 38 "Parameter ''{0}'' must not be null", "mapview")); 39 if (p == null) 40 throw new IllegalArgumentException(tr( 41 "Parameter ''{0}'' must not be null", "p")); 42 42 43 44 43 this.mapview = mapview; 44 } 45 45 46 47 48 49 50 51 52 46 void setSegment(WaySegment segment) { 47 this.segment = segment; 48 if (segment != null) { 49 setSegmentEndpoints(segment); 50 mapview.addTemporaryLayer(this); 51 } 52 } 53 53 54 54 55 56 57 58 55 void setSegmentEndpoints(WaySegment segment) { 56 if (segment != null) { 57 Node node1 = segment.way.getNode(segment.lowerIndex); 58 Node node2 = segment.way.getNode(segment.lowerIndex + 1); 59 59 60 61 62 60 segmentEndPoints = new HashSet<Node>(); 61 segmentEndPoints.add(node1); 62 segmentEndPoints.add(node2); 63 63 64 65 64 } 65 } 66 66 67 67 protected WaySegment getNearestWaySegment(Point p) { 68 68 69 69 return mapview.getNearestWaySegment(p, OsmPrimitive.isUsablePredicate); 70 70 71 71 } 72 72 73 74 75 76 77 73 public void destroy() { 74 if (segment != null) { 75 mapview.removeTemporaryLayer(this); 76 } 77 } 78 78 79 80 81 79 public WaySegment getSegment() { 80 return segment; 81 } 82 82 83 84 85 83 public Collection<Node> getSegmentEndPoints() { 84 return segmentEndPoints; 85 } 86 86 87 88 89 87 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 88 highlightSegment(segmentColor, g, mv); 89 } 90 90 91 91 protected void highlightSegment(Color c, Graphics2D g, MapView mv) { 92 92 93 94 95 96 93 g.setColor(c); 94 g.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, 95 BasicStroke.JOIN_ROUND)); 96 drawSegment(g, mv); 97 97 98 98 } 99 99 100 101 102 100 protected void drawSegment(Graphics2D g, MapView mv) { 101 Node n1 = segment.way.getNode(segment.lowerIndex); 102 Node n2 = segment.way.getNode(segment.lowerIndex + 1); 103 103 104 105 106 104 Line2D newline = new Line2D.Double(mv.getPoint(n1), mv.getPoint(n2)); 105 g.draw(newline); 106 } 107 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 108 /* 109 * (non-Javadoc) 110 * 111 * @see java.lang.Object#hashCode() 112 */ 113 @Override 114 public int hashCode() { 115 final int prime = 31; 116 int result = 1; 117 result = prime * result + ((segment == null) ? 0 : segment.hashCode()); 118 result = prime * result 119 + ((segmentColor == null) ? 0 : segmentColor.hashCode()); 120 return result; 121 } 122 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 123 /* 124 * (non-Javadoc) 125 * 126 * @see java.lang.Object#equals(java.lang.Object) 127 */ 128 @Override 129 public boolean equals(Object obj) { 130 if (this == obj) 131 return true; 132 if (obj == null) 133 return false; 134 if (!(obj instanceof AlignWaysSegment)) 135 return false; 136 AlignWaysSegment other = (AlignWaysSegment) obj; 137 if (segment == null) { 138 if (other.segment != null) 139 return false; 140 } else if (!segment.equals(other.segment)) 141 return false; 142 /* Segment colour is ignored in comparison 143 if (segmentColor == null) { 144 if (other.segmentColor != null) 145 return false; 146 } else if (!segmentColor.equals(other.segmentColor)) 147 return false; 148 */ 149 return true; 150 } 151 151 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSegmentMgr.java
r21613 r23189 22 22 public class AlignWaysSegmentMgr { 23 23 24 25 26 27 24 private volatile static AlignWaysSegmentMgr singleton; 25 private AlignWaysRefSegment refSeg = null; 26 private AlignWaysAlgnSegment algnSeg = null; 27 private final MapView mv; 28 28 29 30 31 29 private AlignWaysSegmentMgr(MapView mapView) { 30 mv = mapView; 31 } 32 32 33 34 35 36 37 38 39 40 41 42 33 public static AlignWaysSegmentMgr getInstance(MapView mapView) { 34 if (singleton == null) { 35 synchronized (AlignWaysSegmentMgr.class) { 36 if (singleton == null) { 37 singleton = new AlignWaysSegmentMgr(mapView); 38 } 39 } 40 } 41 return singleton; 42 } 43 43 44 45 46 47 48 49 44 /** 45 * @param clickedPoint 46 * Point nearby where user probably clicked 47 * @return true, if alignee changed, false otherwise 48 */ 49 public boolean algnUpdate(Point clickedPoint) { 50 50 51 52 53 54 55 56 51 if (algnSeg != null) { 52 // Check first if there is a pivot point nearby that needs selection 53 if (algnSeg.updatePivot(clickedPoint)) 54 // Updated pivot, alignee reference unchanged 55 return false; 56 } 57 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 58 // Previous attempt of pivot update unsuccessful, check alignee update 59 AlignWaysAlgnSegment tmpAlgnSeg = new AlignWaysAlgnSegment(mv, 60 clickedPoint); 61 if (tmpAlgnSeg.getSegment() == null) 62 return false; 63 else { 64 // Found a segment 65 // It may happen that the new segment is identical with the already 66 // selected reference: 67 if ((refSeg != null) && (tmpAlgnSeg.equals(refSeg))) { 68 // This action is then ignored (we won't clear the reference 69 // segment) 70 JOptionPane.showMessageDialog(Main.parent, 71 tr("Segment to be aligned cannot be the same with the reference segment.\n" + 72 "Please choose a different segment to be aligned."), 73 tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE); 74 return false; 75 } 76 // This will be a new alignee, old alignee (if any) will be lost: 77 if (algnSeg != null) { 78 algnSeg.destroy(); 79 } 80 80 81 82 81 // Update alignee 82 algnSeg = tmpAlgnSeg; 83 83 84 85 84 return true; 85 } 86 86 87 87 } 88 88 89 90 91 92 93 94 89 /** 90 * @param clickedPoint 91 * Point nearby where user probably clicked 92 * @return true, if reference changed, false otherwise 93 */ 94 public boolean refUpdate(Point clickedPoint) { 95 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 96 AlignWaysRefSegment tmpRefSeg = new AlignWaysRefSegment(mv, 97 clickedPoint); 98 // TODO Have to check what happens when refSeg wasn't null previously 99 if (tmpRefSeg.getSegment() == null) 100 return false; 101 else { 102 // Found a segment 103 // It may happen that the new segment is identical with the already 104 // selected alignee: 105 if ((algnSeg != null) && (tmpRefSeg.equals(algnSeg))) { 106 // This action is then ignored (we won't clear the alignee 107 // segment) 108 JOptionPane.showMessageDialog(Main.parent, 109 tr("Reference segment cannot be the same with the segment to be aligned.\n" + 110 "Please choose a different reference segment."), 111 tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE); 112 return false; 113 } 114 // This will be a new reference, old reference (if any) will be lost: 115 if (refSeg != null) { 116 refSeg.destroy(); 117 } 118 118 119 120 121 119 // Update reference 120 refSeg = tmpRefSeg; 121 return true; 122 122 123 123 } 124 124 125 125 } 126 126 127 128 129 130 131 132 133 134 127 /** 128 * @return Collection of the nodes that belong to the selected alignee. 129 */ 130 public Collection<Node> getSelectedNodes() { 131 if (algnSeg != null) 132 return algnSeg.getSegmentEndPoints(); 133 return null; 134 } 135 135 136 137 138 139 140 141 142 143 144 145 146 147 148 136 /** 137 * Performs "clean-up" on the initialised segments 138 */ 139 public void cleanupWays() { 140 if (algnSeg != null) { 141 algnSeg.destroy(); 142 algnSeg = null; 143 } 144 if (refSeg != null) { 145 refSeg.destroy(); 146 refSeg = null; 147 } 148 } 149 149 150 151 152 150 public AlignWaysAlgnSegment getAlgnSeg() { 151 return algnSeg; 152 } 153 153 154 155 156 157 158 159 154 /** 155 * @return the refSeg 156 */ 157 public AlignWaysRefSegment getRefSeg() { 158 return refSeg; 159 } 160 160 161 161 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelAlgnState.java
r21613 r23189 12 12 public class AlignWaysSelAlgnState extends AlignWaysState { 13 13 14 15 16 17 14 @Override 15 public void leftClick(AlignWaysMode alignWaysMode) { 16 // No state change, nothing to do 17 } 18 18 19 20 21 22 19 @Override 20 public void ctrlLClick(AlignWaysMode alignWaysMode) { 21 alignWaysMode.setCurrentState(alignWaysMode.getBothSelected()); 22 } 23 23 24 25 26 27 28 24 @Override 25 public void setHelpText() { 26 Main.map.statusLine 27 .setHelpText("Ctrl-Click: select reference way segment; Alt-click: Clear selection"); 28 } 29 29 30 30 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelBothState.java
r22758 r23189 12 12 public class AlignWaysSelBothState extends AlignWaysState { 13 13 14 15 16 17 14 @Override 15 public void leftClick(AlignWaysMode alignWaysMode) { 16 // No state change, nothing to do 17 } 18 18 19 20 21 22 19 @Override 20 public void ctrlLClick(AlignWaysMode alignWaysMode) { 21 // No state change, nothing to do 22 } 23 23 24 25 26 27 28 29 24 @Override 25 public void setHelpText() { 26 Main.map.statusLine 27 .setHelpText(AlignWaysPlugin.getAwAction().getShortcut().getKeyText() + 28 ": Align segments; Alt-click: Clear selection"); 29 } 30 30 31 31 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelNoneState.java
r21613 r23189 12 12 public class AlignWaysSelNoneState extends AlignWaysState { 13 13 14 15 16 17 14 @Override 15 public void leftClick(AlignWaysMode alignWaysMode) { 16 // Reference way segment selected successfully 17 alignWaysMode.setCurrentState(alignWaysMode.getAligneeSelected()); 18 18 19 19 } 20 20 21 22 23 24 25 21 @Override 22 public void ctrlLClick(AlignWaysMode alignWaysMode) { 23 // Reference way segment selected successfully 24 alignWaysMode.setCurrentState(alignWaysMode.getReferenceSelected()); 25 } 26 26 27 28 29 30 31 27 @Override 28 public void setHelpText() { 29 Main.map.statusLine 30 .setHelpText("Ctrl-click: select reference way segment; Click: select way segment to be aligned"); 31 } 32 32 33 33 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelRefState.java
r21613 r23189 12 12 public class AlignWaysSelRefState extends AlignWaysState { 13 13 14 15 16 17 14 @Override 15 public void leftClick(AlignWaysMode alignWaysMode) { 16 alignWaysMode.setCurrentState(alignWaysMode.getBothSelected()); 17 } 18 18 19 20 21 22 19 @Override 20 public void ctrlLClick(AlignWaysMode alignWaysMode) { 21 // No state change, nothing to do 22 } 23 23 24 25 26 27 28 24 @Override 25 public void setHelpText() { 26 Main.map.statusLine 27 .setHelpText("Click: select way segment to be aligned; Alt-click: Clear selection"); 28 } 29 29 30 30 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysState.java
r21613 r23189 12 12 public abstract class AlignWaysState { 13 13 14 14 public abstract void leftClick(AlignWaysMode alignWaysMode); 15 15 16 16 public abstract void ctrlLClick(AlignWaysMode alignWaysMode); 17 17 18 18 public abstract void setHelpText(); 19 19 20 21 22 23 24 20 public void altLClick(AlignWaysMode alignWaysMode) { 21 alignWaysMode.setCurrentState(alignWaysMode.getNoneSelected()); 22 Main.map.statusLine 23 .setHelpText("Ctrl-Click: select reference way segment; Click: select way segment to be aligned"); 24 } 25 25 26 26 } -
applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysTipsPanel.java
r22842 r23189 27 27 public class AlignWaysTipsPanel extends javax.swing.JPanel { 28 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 29 private static final long serialVersionUID = -8583989497599985140L; 30 31 public AlignWaysTipsPanel() { 32 initComponents(); 33 } 34 35 private void initComponents() { 36 37 Title = new JPanel(); 38 WelcomeTo = new JLabel(); 39 Icon = new JLabel(); 40 separator = new JSeparator(); 41 Intro = new JPanel(); 42 introText = new JLabel(); 43 scrollableSteps = new JScrollPane(); 44 steps = new JPanel(); 45 step01 = new JLabel(); 46 step02 = new JLabel(); 47 step03 = new JLabel(); 48 step04 = new JLabel(); 49 lastHint = new JLabel(); 50 dontShow = new JCheckBox(); 51 52 setAutoscrolls(true); 53 54 WelcomeTo.setText(tr("<html>\n<div style=\"font-family: 'sans-serif'; font-weight: bold; font-style: italic;\">\n<span style=\"font-size: large;\">Welcome to the</span><br>\n<span style=\"font-size: xx-large;\">AlignWay<span style=\"color: rgb(204, 85, 0);\">S</span> Plugin<br>\n</span><span style=\"font-size: medium;\"><br>\n...or it rather should be called <br>\n<span style=\"font-size: large;\">AlignWayS(egments)</span> Plugin...</span>\n</div>\n</html>")); 55 56 WelcomeTo.setVerticalAlignment(SwingConstants.TOP); 57 WelcomeTo.setPreferredSize(new Dimension(400, 128)); 58 59 Icon.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/alignways128.png"))); // NOI18N 60 GroupLayout TitleLayout = new GroupLayout(Title); 61 Title.setLayout(TitleLayout); 62 TitleLayout.setHorizontalGroup( 63 TitleLayout.createParallelGroup(GroupLayout.LEADING) 64 .add(GroupLayout.TRAILING, TitleLayout.createSequentialGroup() 65 .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE) 66 .addPreferredGap(LayoutStyle.RELATED) 67 .add(Icon, GroupLayout.PREFERRED_SIZE, 132, GroupLayout.PREFERRED_SIZE)) 68 ); 69 TitleLayout.setVerticalGroup( 70 TitleLayout.createParallelGroup(GroupLayout.LEADING) 71 .add(TitleLayout.createSequentialGroup() 72 .add(Icon) 73 .addContainerGap()) 74 .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE) 75 ); 76 77 Intro.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 78 79 introText.setText(tr("<html>\n<p style=\"font-family: sans-serif; font-weight: bold;\">AlignWays will\nhelp you to align two way segments. This can be handy when for instance\nyou sketch the outlines of a building and want its side to be parallel\nwith a street or road.<br>\n<br>\nSome tips may help before you start:\n</p>\n</html>\n\n")); 80 introText.setVerticalAlignment(SwingConstants.TOP); 81 82 scrollableSteps.setBorder(null); 83 scrollableSteps.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 84 85 step01.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpRefSel.png"))); // NOI18N 86 step01.setText(tr("<html>\n<div style=\"font-family: sans-serif;\">\n<ul>\n<li><b>Select a reference segment.</b> You can do this by <b><i><span style=\"color:green\">Ctrl-click</span></i></b>ing\non a segment. The other, to be aligned segment will become parallel to\nthis one. </li>\n</ul>\n</div>\n</html>\n\n")); 87 step01.setVerticalAlignment(SwingConstants.TOP); 88 89 step02.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgSel.png"))); // NOI18N 90 step02.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n <li><b>Select the to be aligned segment.</b> You can do this by simply <b><i><span style=\"color:green\">click</span></i></b>ing on a different segment. \nThe rotation pivot will be highlighted by default in the centre of the segment.\n </li>\n</ul>\n</div>\n</html>\n\n")); 91 step02.setVerticalAlignment(SwingConstants.TOP); 92 93 step03.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpPvtSel.png"))); // NOI18N 94 step03.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n <li>Optionally <b>change the rotation pivot point</b>. In order to get parallel with the reference segment, the to be aligned segment will rotate around this point. You can choose the two extremities or the centre of the segment by <b><i><span style=\"color:green\">click</span></i></b>ing nearby. \n </li>\n</ul>\n</div>\n</html>\n\n")); 95 step03.setVerticalAlignment(SwingConstants.TOP); 96 97 step04.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgCmd.png"))); // NOI18N 98 step04.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n <li><b>Align the segments.</b> Press <b><i><span style=\"color:green\">" 99 + AlignWaysPlugin.awAction.getShortcut().getKeyText() 100 + "</span></i></b>. Alternatively you''ll find the command in the <b>Tools</b>\n menu or may want to place the action on the <b>toolbar</b>.\n </li>\n</ul>\n</div>\n</html>\n\n")); 101 step04.setVerticalAlignment(SwingConstants.TOP); 102 103 lastHint.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<b>Last hint:</b> There is an easy way to start over your selections if you want: <b><i><span style=\"color:green\">Alt-Click</span></i></b> somewhere on the map.\n</div>\n</html>\n\n")); 104 lastHint.setVerticalAlignment(SwingConstants.TOP); 105 106 GroupLayout stepsLayout = new GroupLayout(steps); 107 steps.setLayout(stepsLayout); 108 stepsLayout.setHorizontalGroup( 109 stepsLayout.createParallelGroup(GroupLayout.LEADING) 110 .add(stepsLayout.createSequentialGroup() 111 .addContainerGap() 112 .add(stepsLayout.createParallelGroup(GroupLayout.TRAILING) 113 .add(GroupLayout.LEADING, lastHint, 0, 0, Short.MAX_VALUE) 114 .add(GroupLayout.LEADING, step04, 0, 0, Short.MAX_VALUE) 115 .add(GroupLayout.LEADING, step03, 0, 0, Short.MAX_VALUE) 116 .add(GroupLayout.LEADING, step02, 0, 0, Short.MAX_VALUE) 117 .add(GroupLayout.LEADING, step01, GroupLayout.DEFAULT_SIZE, 496, Short.MAX_VALUE)) 118 .add(18, 18, 18)) 119 ); 120 stepsLayout.setVerticalGroup( 121 stepsLayout.createParallelGroup(GroupLayout.LEADING) 122 .add(stepsLayout.createSequentialGroup() 123 .add(step01, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 124 .addPreferredGap(LayoutStyle.RELATED) 125 .add(step02, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 126 .addPreferredGap(LayoutStyle.RELATED) 127 .add(step03, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 128 .addPreferredGap(LayoutStyle.RELATED) 129 .add(step04, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 130 .addPreferredGap(LayoutStyle.RELATED) 131 .add(lastHint, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 132 .addContainerGap(22, Short.MAX_VALUE)) 133 ); 134 135 scrollableSteps.setViewportView(steps); 136 137 dontShow.setText(tr("Don''t show this again")); 138 139 GroupLayout IntroLayout = new GroupLayout(Intro); 140 Intro.setLayout(IntroLayout); 141 IntroLayout.setHorizontalGroup( 142 IntroLayout.createParallelGroup(GroupLayout.LEADING) 143 .add(IntroLayout.createSequentialGroup() 144 .addContainerGap() 145 .add(dontShow, GroupLayout.PREFERRED_SIZE, 245, GroupLayout.PREFERRED_SIZE) 146 .addContainerGap(283, Short.MAX_VALUE)) 147 .add(scrollableSteps, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE) 148 .add(introText, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE) 149 ); 150 IntroLayout.setVerticalGroup( 151 IntroLayout.createParallelGroup(GroupLayout.LEADING) 152 .add(GroupLayout.TRAILING, IntroLayout.createSequentialGroup() 153 .add(introText, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 154 .addPreferredGap(LayoutStyle.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 155 .add(scrollableSteps, GroupLayout.PREFERRED_SIZE, 209, GroupLayout.PREFERRED_SIZE) 156 .addPreferredGap(LayoutStyle.UNRELATED) 157 .add(dontShow) 158 .addContainerGap()) 159 ); 160 161 GroupLayout layout = new GroupLayout(this); 162 this.setLayout(layout); 163 layout.setHorizontalGroup( 164 layout.createParallelGroup(GroupLayout.LEADING) 165 .add(GroupLayout.TRAILING, layout.createSequentialGroup() 166 .addContainerGap() 167 .add(layout.createParallelGroup(GroupLayout.TRAILING) 168 .add(GroupLayout.LEADING, separator, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE) 169 .add(Title, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 170 .add(Intro, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 171 .addContainerGap()) 172 ); 173 layout.setVerticalGroup( 174 layout.createParallelGroup(GroupLayout.LEADING) 175 .add(layout.createSequentialGroup() 176 .addContainerGap() 177 .add(Title, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 178 .addPreferredGap(LayoutStyle.UNRELATED) 179 .add(separator, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE) 180 .addPreferredGap(LayoutStyle.RELATED) 181 .add(Intro, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 182 .addContainerGap(45, Short.MAX_VALUE)) 183 ); 184 } 185 186 187 private JLabel Icon; 188 private JPanel Intro; 189 private JPanel Title; 190 private JLabel WelcomeTo; 191 private JCheckBox dontShow; 192 private JLabel introText; 193 private JLabel lastHint; 194 private JScrollPane scrollableSteps; 195 private JSeparator separator; 196 private JLabel step01; 197 private JLabel step02; 198 private JLabel step03; 199 private JLabel step04; 200 private JPanel steps; 201 202 public boolean isChkBoxSelected() { 203 return dontShow.isSelected(); 204 } 205 205 206 206 }
Note:
See TracChangeset
for help on using the changeset viewer.