1 | // License: GPL.
|
---|
2 | package converttomultipoly;
|
---|
3 |
|
---|
4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
5 |
|
---|
6 | import java.awt.event.ActionEvent;
|
---|
7 | import java.awt.event.KeyEvent;
|
---|
8 | import java.util.ArrayList;
|
---|
9 | import java.util.Collection;
|
---|
10 | import java.util.HashSet;
|
---|
11 | import java.util.LinkedList;
|
---|
12 |
|
---|
13 | import javax.swing.JOptionPane;
|
---|
14 |
|
---|
15 | import org.openstreetmap.josm.Main;
|
---|
16 | import org.openstreetmap.josm.actions.JosmAction;
|
---|
17 | import org.openstreetmap.josm.command.AddCommand;
|
---|
18 | import org.openstreetmap.josm.command.ChangePropertyCommand;
|
---|
19 | import org.openstreetmap.josm.command.Command;
|
---|
20 | import org.openstreetmap.josm.command.SequenceCommand;
|
---|
21 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
22 | import org.openstreetmap.josm.data.osm.Relation;
|
---|
23 | import org.openstreetmap.josm.data.osm.RelationMember;
|
---|
24 | import org.openstreetmap.josm.data.osm.Way;
|
---|
25 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
26 |
|
---|
27 | /**
|
---|
28 | * Convert an area into an advance multipolygon.
|
---|
29 | *
|
---|
30 | * New relation with type=multipolygon is created for each ways.
|
---|
31 | *
|
---|
32 | * All the tags (except the source tag) will be moved into the relation.
|
---|
33 | */
|
---|
34 | @SuppressWarnings("serial")
|
---|
35 | public class MultipolyAction extends JosmAction {
|
---|
36 |
|
---|
37 | public MultipolyAction() {
|
---|
38 | super(tr("Convert to multipolygon"), "multipoly_convert",
|
---|
39 | tr("Convert to multipolygon."),
|
---|
40 | Shortcut.registerShortcut("tools:multipolyconv", tr("Tool: {0}",
|
---|
41 | tr("Convert to multipolygon")), KeyEvent.VK_M,
|
---|
42 | Shortcut.ALT_CTRL_SHIFT), true);
|
---|
43 | }
|
---|
44 |
|
---|
45 | /**
|
---|
46 | * The action button has been clicked
|
---|
47 | *
|
---|
48 | * @param e
|
---|
49 | * Action Event
|
---|
50 | */
|
---|
51 | public void actionPerformed(ActionEvent e) {
|
---|
52 |
|
---|
53 | // Get all ways in some type=multipolygon relation
|
---|
54 | HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
|
---|
55 | for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
|
---|
56 | if (!r.isUsable())
|
---|
57 | continue;
|
---|
58 | if (r.get("type") != "multipolygon")
|
---|
59 | continue;
|
---|
60 | for (RelationMember rm : r.getMembers()) {
|
---|
61 | OsmPrimitive m = rm.getMember();
|
---|
62 | if (m instanceof Way && rm.getRole().compareTo("inner") != 0) {
|
---|
63 | relationsInMulti.add(m);
|
---|
64 | }
|
---|
65 | }
|
---|
66 | }
|
---|
67 |
|
---|
68 | // List of selected ways
|
---|
69 | ArrayList<Way> selectedWays = new ArrayList<Way>();
|
---|
70 |
|
---|
71 | // For every selected way
|
---|
72 | for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
|
---|
73 | if (osm instanceof Way) {
|
---|
74 | Way way = (Way) osm;
|
---|
75 | // Check if way is already in another multipolygon
|
---|
76 | if (relationsInMulti.contains(osm)) {
|
---|
77 | JOptionPane
|
---|
78 | .showMessageDialog(
|
---|
79 | Main.parent,
|
---|
80 | tr("One of the selected ways is already part of another multipolygon."));
|
---|
81 | return;
|
---|
82 | }
|
---|
83 |
|
---|
84 | selectedWays.add(way);
|
---|
85 | }
|
---|
86 | }
|
---|
87 |
|
---|
88 | if (Main.map == null) {
|
---|
89 | JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
|
---|
90 | return;
|
---|
91 | }
|
---|
92 |
|
---|
93 | Collection<Command> cmds = new LinkedList<Command>();
|
---|
94 | // Add ways to it
|
---|
95 | for (int i = 0; i < selectedWays.size(); i++) {
|
---|
96 | Way way = selectedWays.get(i);
|
---|
97 |
|
---|
98 | // Create new relation
|
---|
99 | Relation rel = new Relation();
|
---|
100 | rel.put("type", "multipolygon");
|
---|
101 |
|
---|
102 | RelationMember rm = new RelationMember("outer", way);
|
---|
103 | rel.addMember(rm);
|
---|
104 |
|
---|
105 | for (String key : way.getKeys().keySet()) {
|
---|
106 | if (!key.equals("area") || !way.get(key).equals("yes")) {
|
---|
107 | rel.put(key, way.get(key));
|
---|
108 | }
|
---|
109 | if (!key.equals("source")) {
|
---|
110 | cmds.add(new ChangePropertyCommand(way, key, null));
|
---|
111 | }
|
---|
112 | }
|
---|
113 | // Add relation
|
---|
114 | cmds.add(new AddCommand(rel));
|
---|
115 | }
|
---|
116 | // Commit
|
---|
117 | Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), cmds));
|
---|
118 | Main.map.repaint();
|
---|
119 | }
|
---|
120 |
|
---|
121 | /** Enable this action only if something is selected */
|
---|
122 | @Override
|
---|
123 | protected void updateEnabledState() {
|
---|
124 | if (getCurrentDataSet() == null) {
|
---|
125 | setEnabled(false);
|
---|
126 | } else {
|
---|
127 | updateEnabledState(getCurrentDataSet().getSelected());
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | /** Enable this action only if something is selected */
|
---|
132 | @Override
|
---|
133 | protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
|
---|
134 | if (selection == null) {
|
---|
135 | setEnabled(false);
|
---|
136 | return;
|
---|
137 | }
|
---|
138 | for (OsmPrimitive primitive: selection) {
|
---|
139 | if (!(primitive instanceof Way)) {
|
---|
140 | setEnabled(false);
|
---|
141 | return;
|
---|
142 | }
|
---|
143 | if (!((Way)primitive).isClosed()) {
|
---|
144 | setEnabled(false);
|
---|
145 | return;
|
---|
146 | }
|
---|
147 | for (Relation r: OsmPrimitive.getFilteredList(primitive.getReferrers(), Relation.class)) {
|
---|
148 | for (RelationMember rm: r.getMembers()) {
|
---|
149 | if (rm.getMember() == primitive && !"inner".equals(rm.getRole())) {
|
---|
150 | setEnabled(false);
|
---|
151 | return;
|
---|
152 | }
|
---|
153 | }
|
---|
154 | }
|
---|
155 | }
|
---|
156 | setEnabled(selection.size() >= 1);
|
---|
157 | }
|
---|
158 | }
|
---|