1 | package UtilsPlugin;
|
---|
2 |
|
---|
3 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
4 |
|
---|
5 | import java.util.ArrayList;
|
---|
6 | import java.util.Arrays;
|
---|
7 | import java.util.LinkedList;
|
---|
8 | import java.util.Collection;
|
---|
9 |
|
---|
10 | import java.awt.event.ActionEvent;
|
---|
11 |
|
---|
12 | import org.openstreetmap.josm.Main;
|
---|
13 | import org.openstreetmap.josm.data.osm.Node;
|
---|
14 | import org.openstreetmap.josm.data.osm.Segment;
|
---|
15 | import org.openstreetmap.josm.data.osm.Way;
|
---|
16 | import org.openstreetmap.josm.gui.MapFrame;
|
---|
17 | import org.openstreetmap.josm.plugins.Plugin;
|
---|
18 | import org.openstreetmap.josm.command.Command;
|
---|
19 | import org.openstreetmap.josm.command.AddCommand;
|
---|
20 | import org.openstreetmap.josm.command.DeleteCommand;
|
---|
21 | import org.openstreetmap.josm.command.ChangeCommand;
|
---|
22 | import org.openstreetmap.josm.command.SequenceCommand;
|
---|
23 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
24 |
|
---|
25 | import javax.swing.AbstractAction;
|
---|
26 |
|
---|
27 | class MergePointLineAction extends AbstractAction {
|
---|
28 | public MergePointLineAction() {
|
---|
29 | super("Join Point and Segment");
|
---|
30 | }
|
---|
31 | public void actionPerformed(ActionEvent e) {
|
---|
32 | Collection<OsmPrimitive> sel = Main.ds.getSelected();
|
---|
33 | Node node = null;
|
---|
34 | Segment seg = null;
|
---|
35 | Way way = null;
|
---|
36 |
|
---|
37 | boolean error = false;
|
---|
38 | for (OsmPrimitive osm : sel)
|
---|
39 | {
|
---|
40 | if (osm instanceof Node)
|
---|
41 | if( node == null )
|
---|
42 | node = (Node)osm;
|
---|
43 | else
|
---|
44 | error = true;
|
---|
45 | if (osm instanceof Segment)
|
---|
46 | if( seg == null )
|
---|
47 | seg = (Segment)osm;
|
---|
48 | else
|
---|
49 | error = true;
|
---|
50 | if (osm instanceof Way)
|
---|
51 | if( way == null )
|
---|
52 | way = (Way)osm;
|
---|
53 | else
|
---|
54 | error = true;
|
---|
55 | }
|
---|
56 | if( node == null || !(seg == null ^ way == null))
|
---|
57 | error = true;
|
---|
58 | if( error )
|
---|
59 | {
|
---|
60 | javax.swing.JOptionPane.showMessageDialog(Main.parent, tr("Must select one node and one segment/way."));
|
---|
61 | return;
|
---|
62 | }
|
---|
63 | if( way != null )
|
---|
64 | {
|
---|
65 | if( way.isIncomplete() )
|
---|
66 | {
|
---|
67 | javax.swing.JOptionPane.showMessageDialog(Main.parent, tr("Selected way must be complete."));
|
---|
68 | return;
|
---|
69 | }
|
---|
70 | double mindist = 0;
|
---|
71 | // System.out.println( node.toString() );
|
---|
72 | // If the user has selected a way and a point, we need to determine the segment that is closest to the given point.
|
---|
73 | for (Segment s : way.segments )
|
---|
74 | {
|
---|
75 | if( s.incomplete )
|
---|
76 | continue;
|
---|
77 |
|
---|
78 | // System.out.println( s.toString() );
|
---|
79 | double dx1 = s.from.coor.lat() - node.coor.lat();
|
---|
80 | double dy1 = s.from.coor.lon() - node.coor.lon();
|
---|
81 | double dx2 = s.to.coor.lat() - node.coor.lat();
|
---|
82 | double dy2 = s.to.coor.lon() - node.coor.lon();
|
---|
83 |
|
---|
84 | // System.out.println( dx1+","+dx2+" && "+dy1+","+dy2 );
|
---|
85 | double len1 = Math.sqrt(dx1*dx1+dy1*dy1);
|
---|
86 | double len2 = Math.sqrt(dx2*dx2+dy2*dy2);
|
---|
87 | dx1 /= len1;
|
---|
88 | dy1 /= len1;
|
---|
89 | dx2 /= len2;
|
---|
90 | dy2 /= len2;
|
---|
91 | // System.out.println( dx1+","+dx2+" && "+dy1+","+dy2 );
|
---|
92 |
|
---|
93 | double dist = dx1*dx2 + dy1*dy2;
|
---|
94 | // System.out.println( "Dist: "+dist );
|
---|
95 | if( dist < mindist )
|
---|
96 | {
|
---|
97 | mindist = dist;
|
---|
98 | seg = s;
|
---|
99 | }
|
---|
100 | }
|
---|
101 | if( seg == null )
|
---|
102 | {
|
---|
103 | javax.swing.JOptionPane.showMessageDialog(Main.parent, tr("No segment found in range"));
|
---|
104 | return;
|
---|
105 | }
|
---|
106 | }
|
---|
107 |
|
---|
108 | if( seg.incomplete )
|
---|
109 | {
|
---|
110 | javax.swing.JOptionPane.showMessageDialog(Main.parent, tr("Both objects must be complete."));
|
---|
111 | return;
|
---|
112 | }
|
---|
113 | if( node == seg.from || node == seg.to )
|
---|
114 | {
|
---|
115 | javax.swing.JOptionPane.showMessageDialog(Main.parent, tr("Node can't be endpoint of segment"));
|
---|
116 | return;
|
---|
117 | }
|
---|
118 | // Now do the merging
|
---|
119 | Collection<Command> cmds = new LinkedList<Command>();
|
---|
120 | Segment newseg1 = new Segment(seg);
|
---|
121 | newseg1.to = node;
|
---|
122 | Segment newseg2 = new Segment(node, seg.to);
|
---|
123 | if (seg.keys != null)
|
---|
124 | newseg2.keys = new java.util.HashMap<String, String>(seg.keys);
|
---|
125 | newseg2.selected = newseg1.selected;
|
---|
126 |
|
---|
127 | cmds.add(new ChangeCommand(seg,newseg1));
|
---|
128 | cmds.add(new AddCommand(newseg2));
|
---|
129 |
|
---|
130 | // find ways affected and fix them up...
|
---|
131 | for (final Way w : Main.ds.ways)
|
---|
132 | {
|
---|
133 | if( w.deleted )
|
---|
134 | continue;
|
---|
135 | int pos = w.segments.indexOf(seg);
|
---|
136 | if( pos == -1 )
|
---|
137 | continue;
|
---|
138 | Way newway = new Way(w);
|
---|
139 | newway.segments.add(pos+1, newseg2);
|
---|
140 | cmds.add(new ChangeCommand(w,newway));
|
---|
141 | }
|
---|
142 | Main.main.editLayer().add(new SequenceCommand(tr("Join Node and Line"), cmds));
|
---|
143 | Main.map.repaint();
|
---|
144 | }
|
---|
145 | }
|
---|