source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java@ 5902

Last change on this file since 5902 was 5902, checked in by Don-vip, 11 years ago

fix #8622 - Validator: new test to detect invalid highway tags on roundabouts

File size: 4.4 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.Arrays;
8import java.util.HashMap;
9import java.util.HashSet;
10import java.util.List;
11import java.util.Map;
12
13import org.openstreetmap.josm.command.ChangePropertyCommand;
14import org.openstreetmap.josm.command.Command;
15import org.openstreetmap.josm.data.osm.Node;
16import org.openstreetmap.josm.data.osm.OsmUtils;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.data.validation.Severity;
19import org.openstreetmap.josm.data.validation.Test;
20import org.openstreetmap.josm.data.validation.TestError;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * Test that performs semantic checks on highways.
25 * @since 5902
26 */
27public class Highways extends Test {
28
29 protected static final int WRONG_ROUNDABOUT_HIGHWAY = 2701;
30
31 protected static final List<String> CLASSIFIED_HIGHWAYS = Arrays.asList(
32 "motorway", "trunk", "primary", "secondary", "tertiary", "living_street", "residential", "unclassified");
33
34 /**
35 * Constructs a new {@code Highways} test.
36 */
37 public Highways() {
38 super(tr("Highways"), tr("Performs semantic checks on highways."));
39 }
40
41 protected class WrongRoundaboutHighway extends TestError {
42
43 public final String correctValue;
44
45 public WrongRoundaboutHighway(Way w, String key) {
46 super(Highways.this, Severity.WARNING,
47 tr("Incorrect roundabout (highway: {0} instead of {1})", w.get("highway"), key),
48 WRONG_ROUNDABOUT_HIGHWAY, w);
49 this.correctValue = key;
50 }
51 }
52
53 @Override
54 public void visit(Way w) {
55 if (w.isUsable()) {
56 if (w.hasKey("highway") && w.hasKey("junction") && w.get("junction").equals("roundabout")) {
57 Map<String, List<Way>> map = new HashMap<String, List<Way>>();
58 // Count all highways (per type) connected to this roundabout
59 // As roundabouts are closed ways, take care of not processing the first/last node twice
60 for (Node n : new HashSet<Node>(w.getNodes())) {
61 for (Way h : Utils.filteredCollection(n.getReferrers(), Way.class)) {
62 if (h != w && h.hasKey("highway")) {
63 List<Way> list = map.get(h.get("highway"));
64 if (list == null) {
65 map.put(h.get("highway"), list = new ArrayList<Way>());
66 }
67 list.add(h);
68 }
69 }
70 }
71 // The roundabout should carry the highway tag of its two biggest highways
72 for (String s : CLASSIFIED_HIGHWAYS) {
73 List<Way> list = map.get(s);
74 if (list != null && list.size() >= 2) {
75 // Except when a single road is connected, but with two oneway segments
76 Boolean oneway1 = OsmUtils.getOsmBoolean(list.get(0).get("oneway"));
77 Boolean oneway2 = OsmUtils.getOsmBoolean(list.get(1).get("oneway"));
78 if (list.size() > 2 || oneway1 == null || oneway2 == null || !oneway1 || !oneway2) {
79 // Error when the highway tags do not match
80 if (!w.get("highway").equals(s)) {
81 errors.add(new TestError(this, Severity.WARNING,
82 tr("Incorrect roundabout (highway: {0} instead of {1})", w.get("highway"), s),
83 WRONG_ROUNDABOUT_HIGHWAY, w));
84 }
85 break;
86 }
87 }
88 }
89 }
90 }
91 }
92
93 @Override
94 public boolean isFixable(TestError testError) {
95 return testError instanceof WrongRoundaboutHighway;
96 }
97
98 @Override
99 public Command fixError(TestError testError) {
100 if (testError instanceof WrongRoundaboutHighway) {
101 return new ChangePropertyCommand(testError.getPrimitives().iterator().next(),
102 "highway", ((WrongRoundaboutHighway) testError).correctValue);
103 }
104 return null;
105 }
106}
Note: See TracBrowser for help on using the repository browser.