source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/AssociatedStreetFixer.java@ 35351

Last change on this file since 35351 was 33708, checked in by donvip, 7 years ago

fix #josm15403, fix #josm15407, fix #josm15412

File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package relcontext.relationfix;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.HashMap;
8import java.util.List;
9import java.util.Map;
10
11import org.openstreetmap.josm.command.ChangeCommand;
12import org.openstreetmap.josm.command.Command;
13import org.openstreetmap.josm.command.SequenceCommand;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
16import org.openstreetmap.josm.data.osm.Relation;
17import org.openstreetmap.josm.data.osm.RelationMember;
18import org.openstreetmap.josm.data.osm.Way;
19import org.openstreetmap.josm.gui.MainApplication;
20
21public class AssociatedStreetFixer extends RelationFixer {
22
23 public AssociatedStreetFixer() {
24 super("associatedStreet");
25 }
26
27 @Override
28 public boolean isRelationGood(Relation rel) {
29 for (RelationMember m : rel.getMembers()) {
30 if (m.getType().equals(OsmPrimitiveType.NODE) && !"house".equals(m.getRole())) {
31 setWarningMessage(tr("Node without ''house'' role found"));
32 return false;
33 }
34 if (m.getType().equals(OsmPrimitiveType.WAY) && !("house".equals(m.getRole()) || "street".equals(m.getRole()))) {
35 setWarningMessage(tr("Way without ''house'' or ''street'' role found"));
36 return false;
37 }
38 if (m.getType().equals(OsmPrimitiveType.RELATION) && !"house".equals(m.getRole())) {
39 setWarningMessage(tr("Relation without ''house'' role found"));
40 return false;
41 }
42 }
43 // relation should have name
44 if (!rel.hasKey("name")) {
45 setWarningMessage(tr("Relation does not have name"));
46 return false;
47 }
48 // check that all street members have same name as relation (???)
49 String streetName = rel.get("name");
50 if (streetName == null) {
51 streetName = "";
52 }
53 for (RelationMember m : rel.getMembers()) {
54 if ("street".equals(m.getRole()) && !streetName.equals(m.getWay().get("name"))) {
55 String anotherName = m.getWay().get("name");
56 if (anotherName != null && !anotherName.isEmpty()) {
57 setWarningMessage(tr("Relation has streets with different names"));
58 return false;
59 }
60 }
61 }
62 clearWarningMessage();
63 return true;
64 }
65
66 @Override
67 public Command fixRelation(Relation source) {
68 // any way with highway tag -> street
69 // any way/point/relation with addr:housenumber=* or building=* or type=multipolygon -> house
70 // name - check which name is most used in street members and add to relation
71 // copy this name to the other street members (???)
72 Relation rel = new Relation(source);
73 boolean fixed = false;
74
75 for (int i = 0; i < rel.getMembersCount(); i++) {
76 RelationMember m = rel.getMember(i);
77
78 if (m.isNode()) {
79 Node node = m.getNode();
80 if (!"house".equals(m.getRole()) &&
81 (node.hasKey("building") || node.hasKey("addr:housenumber"))) {
82 fixed = true;
83 rel.setMember(i, new RelationMember("house", node));
84 }
85 } else if (m.isWay()) {
86 Way way = m.getWay();
87 if (!"street".equals(m.getRole()) && way.hasKey("highway")) {
88 fixed = true;
89 rel.setMember(i, new RelationMember("street", way));
90 } else if (!"house".equals(m.getRole()) &&
91 (way.hasKey("building") || way.hasKey("addr:housenumber"))) {
92 fixed = true;
93 rel.setMember(i, new RelationMember("house", way));
94 }
95 } else if (m.isRelation()) {
96 Relation relation = m.getRelation();
97 if (!"house".equals(m.getRole()) &&
98 (relation.hasKey("building") || relation.hasKey("addr:housenumber") || "multipolygon".equals(relation.get("type")))) {
99 fixed = true;
100 rel.setMember(i, new RelationMember("house", relation));
101 }
102 }
103 }
104
105 // fill relation name
106 Map<String, Integer> streetNames = new HashMap<>();
107 for (RelationMember m : rel.getMembers()) {
108 if ("street".equals(m.getRole()) && m.isWay()) {
109 String name = m.getWay().get("name");
110 if (name == null || name.isEmpty()) {
111 continue;
112 }
113
114 Integer count = streetNames.get(name);
115
116 streetNames.put(name, count != null ? count + 1 : 1);
117 }
118 }
119 String commonName = "";
120 Integer commonCount = 0;
121 for (Map.Entry<String, Integer> entry : streetNames.entrySet()) {
122 if (entry.getValue() > commonCount) {
123 commonCount = entry.getValue();
124 commonName = entry.getKey();
125 }
126 }
127
128 if (!rel.hasKey("name") && !commonName.isEmpty()) {
129 fixed = true;
130 rel.put("name", commonName);
131 } else {
132 commonName = ""; // set empty common name - if we already have name on relation, do not overwrite it
133 }
134
135 List<Command> commandList = new ArrayList<>();
136 if (fixed) {
137 commandList.add(new ChangeCommand(MainApplication.getLayerManager().getEditDataSet(), source, rel));
138 }
139
140 /*if (!commonName.isEmpty())
141 // fill common name to streets
142 for (RelationMember m : rel.getMembers())
143 if ("street".equals(m.getRole()) && m.isWay()) {
144 String name = m.getWay().get("name");
145 if (commonName.equals(name)) continue;
146
147 // TODO: ask user if he really wants to overwrite street name??
148
149 Way oldWay = m.getWay();
150 Way newWay = new Way(oldWay);
151 newWay.put("name", commonName);
152
153 commandList.add(new ChangeCommand(MainApplication.getLayerManager().getEditDataSet(), oldWay, newWay));
154 }
155 */
156 // return results
157 if (commandList.size() == 0)
158 return null;
159 if (commandList.size() == 1)
160 return commandList.get(0);
161 return new SequenceCommand(tr("fix associatedStreet relation"), commandList);
162 }
163}
Note: See TracBrowser for help on using the repository browser.