Changeset 25873 in osm for applications/editors/josm
- Timestamp:
- 2011-04-20T09:57:52+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/dumbutils
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/dumbutils/README
r25855 r25873 4 4 * Copy tags from previous selected object 5 5 * Replace geometry for existing way 6 * Remember and paste source tag 7 * Align nodes in a way 8 * Paste relations from objects in the paste buffer 6 9 7 10 As for icons, sorry: this is quick&dirty plugin, and I'm no artist. -
applications/editors/josm/plugins/dumbutils/src/dumbutils/AlignWayNodesAction.java
r25870 r25873 1 1 package dumbutils; 2 2 3 import org.openstreetmap.josm.data.osm.Way; 4 import org.openstreetmap.josm.data.osm.Node; 5 import org.openstreetmap.josm.data.osm.RelationMember; 6 import org.openstreetmap.josm.data.osm.RelationData; 7 import org.openstreetmap.josm.data.osm.PrimitiveData; 8 import org.openstreetmap.josm.data.osm.Relation; 3 import org.openstreetmap.josm.data.osm.*; 9 4 import org.openstreetmap.josm.Main; 10 5 import org.openstreetmap.josm.command.*; 11 6 import java.util.*; 12 import java.awt.event.KeyEvent;13 import org.openstreetmap.josm.tools.Shortcut;14 7 import java.awt.event.ActionEvent; 8 import javax.swing.JOptionPane; 15 9 import org.openstreetmap.josm.actions.JosmAction; 16 import org.openstreetmap.josm.data.osm.OsmPrimitive;17 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;18 10 import static org.openstreetmap.josm.tools.I18n.tr; 19 11 … … 25 17 class AlignWayNodesAction extends JosmAction { 26 18 private static final String TITLE = "Align way nodes"; 19 private static final double MOVE_THRESHOLD = 1e-9; 27 20 28 21 public AlignWayNodesAction() { … … 33 26 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected(); 34 27 Set<Node> selectedNodes = filterNodes(selection); 28 int selectedNodesCount = selectedNodes.size(); 35 29 Set<Way> ways = findCommonWays(selectedNodes); 36 if( ways == null || ways.size() != 1 )30 if( ways == null || ways.size() != 1 || selectedNodesCount == 0 ) 37 31 return; 38 32 Way way = ways.iterator().next(); 33 if( way.getNodesCount() < (way.isClosed() ? 4 : 3) ) { 34 JOptionPane.showMessageDialog(Main.parent, tr("The way with selected nodes can not be straightened."), tr(TITLE), JOptionPane.ERROR_MESSAGE); 35 return; 36 } 39 37 40 38 // Prepare a list of nodes to align 39 int firstNodePos = findFirstNode(way, selectedNodes); 40 int lastNodePos = way.isClosed() ? firstNodePos : way.getNodesCount(); 41 41 List<Node> nodes = new ArrayList<Node>(); 42 for( int i = 0; i < way.getNodesCount(); i++ ) { 42 int i = firstNodePos; 43 boolean iterated = false; 44 while( !iterated || i != lastNodePos ) { 43 45 Node node = way.getNode(i); 44 46 if( selectedNodes.contains(node) ) { 45 47 nodes.add(node); 46 48 selectedNodes.remove(node); 47 } 48 // todo: 1 node - add adjacent; 2 nodes - add all between them 49 if( selectedNodesCount == 1 ) { 50 nodes.add(0, way.getNode( i > 0 ? i - 1 : way.isClosed() ? way.getNodesCount() - 2 : i + 2 )); 51 nodes.add(way.getNode( i + 1 < way.getNodesCount() ? i + 1 : way.isClosed() ? 1 : i - 2 )); 52 } 53 if( selectedNodes.isEmpty() ) 54 break; 55 } else if( selectedNodesCount == 2 && selectedNodes.size() == 1 ) 56 nodes.add(node); 57 i++; 58 if( i >= way.getNodesCount() && way.isClosed() ) 59 i = 0; 60 iterated = true; 49 61 } 50 62 63 if( nodes.size() < 3 ) { 64 JOptionPane.showMessageDialog(Main.parent, "Internal error: number of nodes is " + nodes.size(), 65 tr(TITLE), JOptionPane.ERROR_MESSAGE); 66 return; 67 } 68 69 // Now, we have an ordered list of nodes, of which idx 0 and N-1 serve as guides 70 // and 1..N-2 should be aligned with them 51 71 List<Command> commands = new ArrayList<Command>(); 72 double ax = nodes.get(0).getEastNorth().east(); 73 double ay = nodes.get(0).getEastNorth().north(); 74 double bx = nodes.get(nodes.size() - 1).getEastNorth().east(); 75 double by = nodes.get(nodes.size() - 1).getEastNorth().north(); 76 77 for( i = 1; i + 1 < nodes.size(); i++ ) { 78 Node n = nodes.get(i); 79 80 // Algorithm is copied from org.openstreetmap.josm.actions.AlignInLineAction 81 double nx = n.getEastNorth().east(); 82 double ny = n.getEastNorth().north(); 83 84 if( ax == bx ) { 85 // Special case if AB is vertical... 86 nx = ax; 87 } else if( ay == by ) { 88 // ...or horizontal 89 ny = ay; 90 } else { 91 // Otherwise calculate position by solving y=mx+c (simplified) 92 double m1 = (by - ay) / (bx - ax); 93 double c1 = ay - (ax * m1); 94 double m2 = (-1) / m1; 95 double c2 = ny - (nx * m2); 96 97 nx = (c2 - c1) / (m1 - m2); 98 ny = (m1 * nx) + c1; 99 } 100 101 // Add the command to move the node to its new position. 102 if( Math.abs(nx - n.getEastNorth().east()) > MOVE_THRESHOLD && Math.abs(ny - n.getEastNorth().north()) > MOVE_THRESHOLD ) 103 commands.add(new MoveCommand(n, nx - n.getEastNorth().east(), ny - n.getEastNorth().north())); 104 } 105 52 106 if( !commands.isEmpty() ) 53 107 Main.main.undoRedo.add(new SequenceCommand(tr(TITLE), commands)); … … 64 118 @Override 65 119 protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) { 66 Set<Way> ways = findCommonWays(filterNodes(selection)); 67 setEnabled(ways != null && ways.size() == 1); 120 Set<Node> nodes = filterNodes(selection); 121 Set<Way> ways = findCommonWays(nodes); 122 setEnabled(ways != null && ways.size() == 1 && !nodes.isEmpty()); 68 123 } 69 124 … … 92 147 return result; 93 148 } 149 150 /** 151 * Find the largest empty span between nodes and returns the index of the node right after it. 152 */ 153 private int findFirstNode( Way way, Set<Node> nodes ) { 154 int pos = 0; 155 while( pos < way.getNodesCount() && !nodes.contains(way.getNode(pos)) ) 156 pos++; 157 if( pos >= way.getNodesCount() ) 158 return 0; 159 if( !way.isClosed() || nodes.size() <= 1 ) 160 return pos; 161 162 // now, way is closed 163 boolean fullCircle = false; 164 int maxLength = 0; 165 int lastPos = 0; 166 while( !fullCircle ) { 167 int length = 0; 168 boolean skippedFirst = false; 169 while( !(skippedFirst && nodes.contains(way.getNode(pos))) ) { 170 skippedFirst = true; 171 length++; 172 pos++; 173 if( pos >= way.getNodesCount() ) { 174 pos = 0; 175 fullCircle = true; 176 } 177 } 178 if( length > maxLength ) { 179 maxLength = length; 180 lastPos = pos; 181 } 182 } 183 return lastPos; 184 } 94 185 } -
applications/editors/josm/plugins/dumbutils/src/dumbutils/DumbUtilsPlugin.java
r25870 r25873 23 23 sourceTag = MainMenu.add(Main.main.menu.toolsMenu, new TagSourceAction()); 24 24 pasteRelations = MainMenu.add(Main.main.menu.toolsMenu, new PasteRelationsAction()); 25 //alignWayNodes = MainMenu.add(Main.main.menu.toolsMenu, new AlignWayNodesAction());25 alignWayNodes = MainMenu.add(Main.main.menu.toolsMenu, new AlignWayNodesAction()); 26 26 } 27 27 … … 33 33 sourceTag.setEnabled(enabled); 34 34 pasteRelations.setEnabled(enabled); 35 //alignWayNodes.setEnabled(enabled);35 alignWayNodes.setEnabled(enabled); 36 36 } 37 37 }
Note:
See TracChangeset
for help on using the changeset viewer.