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

Last change on this file since 28708 was 28708, checked in by larry0ua, 14 years ago

'RelToolbox: fix possible NPE in associatedStreet fixer'

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