Ticket #24851: 24851-powerlines-v2.patch
| File 24851-powerlines-v2.patch, 5.3 KB (added by , 4 days ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
11 11 import java.util.EnumSet; 12 12 import java.util.HashMap; 13 13 import java.util.HashSet; 14 import java.util.LinkedHashSet; 14 15 import java.util.List; 15 16 import java.util.Map; 17 import java.util.Map.Entry; 16 18 import java.util.Set; 19 import java.util.stream.Collectors; 17 20 18 21 import org.openstreetmap.josm.data.coor.ILatLon; 19 22 import org.openstreetmap.josm.data.osm.Node; … … 75 78 76 79 private double hillyCompensation; 77 80 private double hillyThreshold; 78 private final Set<Node> badConnections = new HashSet<>();79 private final Set<Node> missingTags = new HashSet<>();81 private final Map<Node, Set<OsmPrimitive>> badConnections = new HashMap<>(); 82 private final Map<Node, Set<OsmPrimitive>> missingTags = new HashMap<>(); 80 83 private final Set<Way> wrongLineType = new HashSet<>(); 81 84 private final Set<WaySegment> missingNodes = new HashSet<>(); 82 85 private final Set<OsmPrimitive> refDiscontinuities = new HashSet<>(); … … 98 101 99 102 @Override 100 103 public void visit(Node n) { 101 boolean nodeInLineOrCable = false; 102 boolean connectedToUnrelated = false; 103 for (Way parent : n.getParentWays()) { 104 if (parent.hasTag(POWER, "line", MINOR_LINE, "cable")) 105 nodeInLineOrCable = true; 106 else if (!isRelatedToPower(parent)) 107 connectedToUnrelated = true; 104 if (!n.isConnectionNode() || n.referrers(Way.class).noneMatch(w -> isPowerLineOrCable(w))) 105 return; 106 107 List<Way> unrelatedParents = n.referrers(Way.class).filter(w -> !isPowerLineOrCable(w) && !isRelatedToPower(w)) 108 .collect(Collectors.toList()); 109 if (!unrelatedParents.isEmpty()) { 110 Set<OsmPrimitive> set = badConnections.computeIfAbsent(n, k -> new HashSet<>()); 111 set.addAll(unrelatedParents); 108 112 } 109 if (nodeInLineOrCable && connectedToUnrelated)110 badConnections.add(n);111 113 } 112 114 113 115 @Override … … 162 164 powerlineChecks(w); 163 165 } 164 166 // Then return the errors 165 for (Node n : missingTags) { 167 for (Entry<Node, Set<OsmPrimitive>> entry : missingTags.entrySet()) { 168 Node n = entry.getKey(); 166 169 if (!isInPowerStation(n)) { 167 170 errors.add(TestError.builder(this, Severity.WARNING, POWER_SUPPORT) 168 171 // the "missing tag" grouping can become broken if the MapCSS message get reworded 169 172 .message(tr("missing tag"), tr("node without power=*")) 170 .primitives(n) 173 .primitives(getAllPrimitives(entry)) 174 .highlight(n) 171 175 .build()); 172 176 } 173 177 } 174 178 175 for ( Node n : badConnections) {179 for (Entry<Node, Set<OsmPrimitive>> entry : badConnections.entrySet()) { 176 180 errors.add(TestError.builder(this, Severity.WARNING, POWER_CONNECTION) 177 181 .message(tr("Node connects a power line or cable with an object " 178 182 + "which is not related to the power infrastructure")) 179 .primitives(n) 183 .primitives(getAllPrimitives(entry)) 184 .highlight(entry.getKey()) 180 185 .build()); 181 186 } 182 187 … … 224 229 } 225 230 226 231 /** 232 * Combine the node and the related objects. 233 * @param entry a map entry with a node and related objects 234 * @return set containing the node and the related objects 235 */ 236 private Collection<? extends OsmPrimitive> getAllPrimitives(Entry<Node, Set<OsmPrimitive>> entry) { 237 Set<OsmPrimitive> primitives = new LinkedHashSet<>(); 238 primitives.add(entry.getKey()); 239 primitives.addAll(entry.getValue()); 240 return primitives; 241 } 242 243 /** 227 244 * The base powerline checks 228 245 * @param w The powerline to check 229 246 */ … … 253 270 254 271 /// handle missing power line support tags (e.g. tower) 255 272 if (!isPowerTower(n) && !isPowerInfrastructure(n) && IN_DOWNLOADED_AREA.test(n) 256 && (!w.isFirstLastNode(n) || !isPowerStation(n))) 257 missingTags.add(n); 273 && (!w.isFirstLastNode(n) || !isPowerStation(n))) { 274 Set<OsmPrimitive> set = missingTags.computeIfAbsent(n, k -> new HashSet<>()); 275 set.add(w); 276 } 258 277 259 278 /// handle missing nodes 260 279 double segmentLen = n.greatCircleDistance(prevNode); … … 669 688 } 670 689 671 690 /** 691 * Determines if the specified way denotes a power line or cable. 692 * @param w The way to be tested 693 * @return {@code true} if power key is set and equal to line,minor_line or cable 694 */ 695 protected static boolean isPowerLineOrCable(Way w) { 696 return isPowerIn(w, Arrays.asList("line", MINOR_LINE, "cable")); 697 } 698 699 /** 672 700 * Determines if the specified primitive denotes a power station. 673 701 * @param p The primitive to be tested 674 702 * @return {@code true} if power key is set and equal to generator/substation/plant
