source: josm/src/org/openstreetmap/josm/actions/AlignInCircleAction.java@ 298

Last change on this file since 298 was 298, checked in by imi, 17 years ago
  • added license description to head of each source file
File size: 2.7 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
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.LinkedList;
10
11import javax.swing.JOptionPane;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.command.Command;
15import org.openstreetmap.josm.command.MoveCommand;
16import org.openstreetmap.josm.command.SequenceCommand;
17import org.openstreetmap.josm.data.coor.EastNorth;
18import org.openstreetmap.josm.data.coor.LatLon;
19import org.openstreetmap.josm.data.osm.Node;
20import org.openstreetmap.josm.data.osm.OsmPrimitive;
21
22/**
23 * Aligns all selected nodes within a circle. (Usefull for roundabouts)
24 *
25 * @author Matthew Newton
26 */
27public final class AlignInCircleAction extends JosmAction {
28
29 public AlignInCircleAction() {
30 super(tr("Align Nodes in Circle"), "aligncircle", tr("Move the selected nodes into a circle."), KeyEvent.VK_O, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
31 }
32
33 public void actionPerformed(ActionEvent e) {
34 Collection<OsmPrimitive> sel = Main.ds.getSelected();
35 Collection<Node> nodes = new LinkedList<Node>();
36 for (OsmPrimitive osm : sel)
37 if (osm instanceof Node)
38 nodes.add((Node)osm);
39 if (nodes.size() < 4) {
40 JOptionPane.showMessageDialog(Main.parent, tr("Please select at least four nodes."));
41 return;
42 }
43
44 // Get average position of all nodes
45 Node avn = new Node(new LatLon(0,0));
46 for (Node n : nodes) {
47 avn.eastNorth = new EastNorth(avn.eastNorth.east()+n.eastNorth.east(), avn.eastNorth.north()+n.eastNorth.north());
48 avn.coor = Main.proj.eastNorth2latlon(avn.eastNorth);
49 }
50 avn.eastNorth = new EastNorth(avn.eastNorth.east()/nodes.size(), avn.eastNorth.north()/nodes.size());
51 avn.coor = Main.proj.eastNorth2latlon(avn.eastNorth);
52 // Node "avn" now is central to all selected nodes.
53
54 // Now calculate the average distance to each node from the
55 // centre.
56 double avdist = 0;
57 for (Node n : nodes)
58 avdist += Math.sqrt(avn.eastNorth.distance(n.eastNorth));
59 avdist = avdist / nodes.size();
60
61 Collection<Command> cmds = new LinkedList<Command>();
62 // Move each node to that distance from the centre.
63 for (Node n : nodes) {
64 double dx = n.eastNorth.east() - avn.eastNorth.east();
65 double dy = n.eastNorth.north() - avn.eastNorth.north();
66 double dist = Math.sqrt(avn.eastNorth.distance(n.eastNorth));
67 cmds.add(new MoveCommand(n, (dx * (avdist / dist)) - dx, (dy * (avdist / dist)) - dy));
68 }
69
70 Main.main.editLayer().add(new SequenceCommand(tr("Align Nodes in Circle"), cmds));
71 Main.map.repaint();
72 }
73}
Note: See TracBrowser for help on using the repository browser.