Ticket #20716: josm_20716_power_v3.patch
| File josm_20716_power_v3.patch, 12.4 KB (added by , 5 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java b/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
a b 47 47 /** Bag of all way segments */ 48 48 private MultiMap<Pair<Node, Node>, WaySegment> nodePairs; 49 49 50 private boolean onlyKn wonLinear;50 private boolean onlyKnownLinear; 51 51 private boolean includeOther; 52 52 private boolean ignoreLayer; 53 53 … … 83 83 super.startTest(monitor); 84 84 nodePairs = new MultiMap<>(1000); 85 85 includeOther = isBeforeUpload ? ValidatorPrefHelper.PREF_OTHER_UPLOAD.get() : ValidatorPrefHelper.PREF_OTHER.get(); 86 onlyKn wonLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true);86 onlyKnownLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true); 87 87 ignoreLayer = Config.getPref().getBoolean("overlapping-ways.ignore-layer", false); 88 88 } 89 89 … … 192 192 errortype = tr("Waterway shares segment with linear way"); 193 193 type = OVERLAPPING_WATERWAY_LINEAR_WAY; 194 194 severity = Severity.WARNING; 195 } else if (!includeOther || onlyKn wonLinear) {195 } else if (!includeOther || onlyKnownLinear) { 196 196 return; 197 197 } else if (countHighway > 0) { 198 198 errortype = tr("Highway shares segment with other way"); … … 269 269 if (IGNORED.test(w)) 270 270 return; 271 271 272 if (onlyKn wonLinear && (w.concernsArea() || w.getInterestingTags().isEmpty()))272 if (onlyKnownLinear && (w.concernsArea() || w.getInterestingTags().isEmpty())) 273 273 return; 274 274 275 275 Node lastN = null; -
src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 diff --git a/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java b/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
a b 11 11 import java.util.Set; 12 12 13 13 import org.openstreetmap.josm.data.osm.Node; 14 import org.openstreetmap.josm.data.osm.NodePair; 14 15 import org.openstreetmap.josm.data.osm.OsmPrimitive; 15 16 import org.openstreetmap.josm.data.osm.Relation; 16 17 import org.openstreetmap.josm.data.osm.RelationMember; … … 25 26 import org.openstreetmap.josm.tools.Geometry; 26 27 27 28 /** 28 * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole tag.<br> 29 * See #7812 for discussions about this test. 29 * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole/portal tag and also for ways where 30 * are unusually long segments without line support feature.<br> 31 * See #7812 and #20716 for discussions about this test. 30 32 */ 31 33 public class PowerLines extends Test { 32 34 33 35 /** Test identifier */ 34 36 protected static final int POWER_LINES = 2501; 35 37 protected static final int POWER_CONNECTION = 2502; 38 protected static final int POWER_SEGMENT_LENGTH = 2503; 36 39 37 40 /** Values for {@code power} key interpreted as power lines */ 38 41 static final Collection<String> POWER_LINE_TAGS = Arrays.asList("line", "minor_line"); 39 42 /** Values for {@code power} key interpreted as power towers */ 40 static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole" );43 static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole", "portal", "catenary_mast"); 41 44 /** Values for {@code power} key interpreted as power stations */ 42 static final Collection<String> POWER_STATION_TAGS = Arrays.asList(" station", "sub_station", "substation", "plant", "generator");45 static final Collection<String> POWER_STATION_TAGS = Arrays.asList("generator", "plant", "substation"); 43 46 /** Values for {@code building} key interpreted as power stations */ 44 47 static final Collection<String> BUILDING_STATION_TAGS = Arrays.asList("transformer_tower"); 45 48 /** Values for {@code power} key interpreted as allowed power items */ 46 static final Collection<String> POWER_ ALLOWED_TAGS = Arrays.asList("switch", "transformer", "busbar", "generator", "switchgear",47 " portal", "terminal", "insulator");49 static final Collection<String> POWER_INFRASTRUCTURE_TAGS = Arrays.asList("compensator", "converter", 50 "generator", "insulator", "switch", "switchgear", "terminal", "transformer"); 48 51 49 52 private final Set<Node> badConnections = new LinkedHashSet<>(); 50 private final Set<Node> missingTowerOrPole = new LinkedHashSet<>(); 53 private final Set<Node> missingTag = new LinkedHashSet<>(); 54 private final Set<NodePair> missingNode = new LinkedHashSet<>(); 51 55 52 56 private final List<OsmPrimitive> powerStations = new ArrayList<>(); 53 57 … … 58 62 super(tr("Power lines"), tr("Checks for nodes in power lines that do not have a power=tower/pole tag.")); 59 63 } 60 64 61 @Override62 public void visit(Way w) {63 if (w.isUsable()) {64 if (isPowerLine(w) && !w.hasTag("location", "underground")) {65 for (Node n : w.getNodes()) {66 if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)67 && (!w.isFirstLastNode(n) || !isPowerStation(n))) {68 missingTowerOrPole.add(n);69 }70 }71 } else if (w.isClosed() && isPowerStation(w)) {72 powerStations.add(w);73 }74 }75 }76 77 65 @Override 78 66 public void visit(Node n) { 79 67 boolean nodeInLineOrCable = false; … … 89 77 badConnections.add(n); 90 78 } 91 79 92 private static boolean isRelatedToPower(Way way) { 93 if (way.hasTag("power") || way.hasTag("building")) 94 return true; 95 for (OsmPrimitive ref : way.getReferrers()) { 96 if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) { 97 for (RelationMember rm : ((Relation) ref).getMembers()) { 98 if (way == rm.getMember()) 99 return true; 80 @Override 81 public void visit(Way w) { 82 if (w.isUsable()) { 83 if (isPowerLine(w) && !w.hasKey("line") && !w.hasTag("location", "underground")) { 84 float avgWayLength = (float) (w.getLength() / w.getRealNodesCount()); 85 Node prevNode = w.firstNode(); 86 87 for (Node n : w.getNodes()) { 88 // handle power station power line connections (power=line + line=*) 89 boolean skip = false; 90 for (OsmPrimitive p : n.getReferrers()) { 91 if (p instanceof Way && !p.equals(w) && isPowerLine((Way) p) && p.hasKey("line")) { 92 skip = true; 93 break; 94 } 95 } 96 if (skip) { 97 prevNode = n; 98 continue; 99 } 100 101 // handle missing tags 102 if (!isPowerTower(n) && !isPowerInfrastructure(n) && IN_DOWNLOADED_AREA.test(n) 103 && (!w.isFirstLastNode(n) || !isPowerStation(n))) { 104 missingTag.add(n); 105 } 106 107 // handle missing nodes 108 double distance = n.getCoor().greatCircleDistance(prevNode.getCoor()); 109 double threshold = w.hasTag("power", "line") ? 1.6 : 1.8; 110 if (w.getRealNodesCount() > 4 && distance > avgWayLength * threshold && !isPowerInfrastructure(n)) { 111 missingNode.add(new NodePair(prevNode, n)); 112 } 113 prevNode = n; 100 114 } 115 } else if (w.isClosed() && isPowerStation(w)) { 116 powerStations.add(w); 101 117 } 102 118 } 103 return false;104 119 } 105 120 106 121 @Override … … 118 133 119 134 @Override 120 135 public void endTest() { 121 for (Node n : missingT owerOrPole) {136 for (Node n : missingTag) { 122 137 if (!isInPowerStation(n)) { 123 138 errors.add(TestError.builder(this, Severity.WARNING, POWER_LINES) 124 .message(tr("Missing power tower/pole within power line"))139 .message(tr("Missing power line support tag from node")) 125 140 .primitives(n) 126 141 .build()); 127 142 } … … 130 145 for (Node n : badConnections) { 131 146 errors.add(TestError.builder(this, Severity.WARNING, POWER_CONNECTION) 132 147 .message(tr("Node connects a power line or cable with an object " 133 + "which is not related to the power infrastructure.")) 134 .primitives(n).build()); 148 + "which is not related to the power infrastructure")) 149 .primitives(n) 150 .build()); 135 151 } 152 153 for (NodePair pair : missingNode) { 154 errors.add(TestError.builder(this, Severity.WARNING, POWER_SEGMENT_LENGTH) 155 .message(tr("Missing line support node within power line")) 156 .primitives(pair.getA(), pair.getB()) 157 .build()); 158 } 159 136 160 clearCollections(); 137 161 super.endTest(); 138 162 } 139 163 164 private static boolean isRelatedToPower(Way way) { 165 if (way.hasTag("power") || way.hasTag("building")) 166 return true; 167 for (OsmPrimitive ref : way.getReferrers()) { 168 if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) { 169 for (RelationMember rm : ((Relation) ref).getMembers()) { 170 if (way == rm.getMember()) 171 return true; 172 } 173 } 174 } 175 return false; 176 } 177 140 178 protected final boolean isInPowerStation(Node n) { 141 179 for (OsmPrimitive station : powerStations) { 142 180 List<List<Node>> nodesLists = new ArrayList<>(); … … 171 209 /** 172 210 * Determines if the specified primitive denotes a power station. 173 211 * @param p The primitive to be tested 174 * @return {@code true} if power key is set and equal to station/sub_station/plant212 * @return {@code true} if power key is set and equal to generator/substation/plant 175 213 */ 176 214 protected static final boolean isPowerStation(OsmPrimitive p) { 177 215 return isPowerIn(p, POWER_STATION_TAGS) || isBuildingIn(p, BUILDING_STATION_TAGS); 178 216 } 179 217 180 218 /** 181 * Determines if the specified node denotes a power tower/pole .219 * Determines if the specified node denotes a power tower/pole/portal/catenary_mast. 182 220 * @param n The node to be tested 183 * @return {@code true} if power key is set and equal to tower/pole 221 * @return {@code true} if power key is set and equal to tower/pole/portal/catenary_mast 184 222 */ 185 223 protected static final boolean isPowerTower(Node n) { 186 224 return isPowerIn(n, POWER_TOWER_TAGS); … … 189 227 /** 190 228 * Determines if the specified node denotes a power infrastructure allowed on a power line. 191 229 * @param n The node to be tested 192 * @return True if power key is set and equal to switch/tranformer/busbar/generator 230 * @return True if power key is set and equal to compensator/converter/generator/insulator 231 * /switch/switchgear/terminal/transformer 193 232 */ 194 protected static final boolean isPower Allowed(Node n) {195 return isPowerIn(n, POWER_ ALLOWED_TAGS);233 protected static final boolean isPowerInfrastructure(Node n) { 234 return isPowerIn(n, POWER_INFRASTRUCTURE_TAGS); 196 235 } 197 236 198 237 /** … … 218 257 private void clearCollections() { 219 258 powerStations.clear(); 220 259 badConnections.clear(); 221 missingTowerOrPole.clear(); 260 missingTag.clear(); 261 missingNode.clear(); 222 262 } 223 263 }
