Ticket #23397: 23397-a2.patch
File 23397-a2.patch, 10.3 KB (added by , 20 months ago) |
---|
-
src/org/openstreetmap/josm/actions/upload/ValidateUploadHook.java
6 6 import java.awt.Dimension; 7 7 import java.awt.GridBagLayout; 8 8 import java.util.Collection; 9 import java.util.HashSet; 9 10 import java.util.List; 10 11 import java.util.concurrent.atomic.AtomicBoolean; 11 12 … … 13 14 import javax.swing.JScrollPane; 14 15 15 16 import org.openstreetmap.josm.data.APIDataSet; 17 import org.openstreetmap.josm.data.osm.Node; 16 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 19 import org.openstreetmap.josm.data.validation.OsmValidator; 18 20 import org.openstreetmap.josm.data.validation.TestError; … … 45 47 @Override 46 48 public boolean checkUpload(APIDataSet apiDataSet) { 47 49 AtomicBoolean returnCode = new AtomicBoolean(); 50 Collection<OsmPrimitive> initialList = new HashSet<>(apiDataSet.getPrimitivesToAdd()); 51 initialList.addAll(apiDataSet.getPrimitivesToUpdate()); 52 // see #23397 53 // create extended list with parent objects of modified nodes as they may mean a geometry change 54 // maybe find a better place to do this? 55 Collection<OsmPrimitive> extendedList = new HashSet<>(initialList); 56 for (OsmPrimitive p : initialList) { 57 if (p instanceof Node && !p.isNew()) { 58 for (OsmPrimitive parent : p.getReferrers()) { 59 if (!parent.isDeleted()) { 60 extendedList.add(parent); 61 } 62 } 63 } 64 } 48 65 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor(); 49 v.visit(apiDataSet.getPrimitivesToAdd()); 50 Collection<OsmPrimitive> visited = v.visit(apiDataSet.getPrimitivesToUpdate()); 66 Collection<OsmPrimitive> visited = v.visit(extendedList); 51 67 OsmValidator.initializeTests(); 52 68 new ValidationTask(errors -> { 53 69 if (errors.stream().allMatch(TestError::isIgnored)) { -
src/org/openstreetmap/josm/data/validation/Test.java
6 6 import java.awt.GridBagConstraints; 7 7 import java.util.ArrayList; 8 8 import java.util.Collection; 9 import java.util.HashSet; 9 10 import java.util.List; 10 11 import java.util.Optional; 12 import java.util.Set; 11 13 import java.util.function.Predicate; 12 14 import java.util.stream.Collectors; 13 15 … … 383 385 public Object getSource() { 384 386 return "Java: " + this.getClass().getName(); 385 387 } 388 389 /** 390 * Filter the list of errors, remove all which do not concern the given list of primitives 391 * @param given the list of primitives 392 * @since xxx 393 */ 394 public void removeIrrelevantErrors(Collection<? extends OsmPrimitive> given) { 395 if (errors == null || errors.isEmpty()) 396 return; 397 // filter errors for those which are needed, don't show errors for objects which were not in the selection 398 final Set<? extends OsmPrimitive> relevant; 399 if (given instanceof Set) { 400 relevant = (Set<? extends OsmPrimitive>) given; 401 } else { 402 relevant = new HashSet<>(given); 403 } 404 errors.removeIf(e -> !e.isConcerned(relevant)); 405 } 386 406 } -
src/org/openstreetmap/josm/data/validation/TestError.java
12 12 import java.util.List; 13 13 import java.util.Locale; 14 14 import java.util.Map; 15 import java.util.Set; 15 16 import java.util.TreeSet; 16 17 import java.util.function.Supplier; 17 18 import java.util.stream.Collectors; … … 666 667 ", code=" + code + ", message=" + message + ']'; 667 668 } 668 669 670 /** 671 * Check if any of the primitives in this error occurs in the given set of primitives. 672 * @param given the set of primitives 673 * @return true if any of the primitives in this error occurs in the given set of primitives, else false 674 * @since xxx 675 */ 676 public boolean isConcerned(Set<? extends OsmPrimitive> given) { 677 for (OsmPrimitive p : getPrimitives()) { 678 if (given.contains(p)) { 679 return true; 680 } 681 } 682 return false; 683 } 669 684 } -
src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
6 6 import java.awt.geom.Point2D; 7 7 import java.util.ArrayList; 8 8 import java.util.Arrays; 9 import java.util.Collection; 9 10 import java.util.HashMap; 10 11 import java.util.HashSet; 11 12 import java.util.List; … … 16 17 17 18 import org.openstreetmap.josm.data.coor.EastNorth; 18 19 import org.openstreetmap.josm.data.coor.ILatLon; 20 import org.openstreetmap.josm.data.osm.DataSet; 21 import org.openstreetmap.josm.data.osm.OsmDataManager; 19 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 20 23 import org.openstreetmap.josm.data.osm.OsmUtils; 21 24 import org.openstreetmap.josm.data.osm.Relation; … … 81 84 private final Map<Point2D, List<WaySegment>> cellSegments = new HashMap<>(1000); 82 85 /** The already detected ways in error */ 83 86 private final Map<List<Way>, List<WaySegment>> seenWays = new HashMap<>(50); 87 private final Set<Way> waysToTest = new HashSet<>(); 84 88 85 89 protected final int code; 90 private DataSet ds; 86 91 87 92 /** 88 93 * General crossing ways test. … … 305 310 306 311 @Override 307 312 public void endTest() { 308 super.endTest(); 313 ds = OsmDataManager.getInstance().getActiveDataSet(); 314 if (ds == null || waysToTest.isEmpty()) 315 return; 316 final Collection<Way> selection; 317 if (this instanceof SelfCrossing || !partialSelection) { 318 selection = waysToTest; 319 } else { 320 selection = new HashSet<>(); 321 for (Way w: waysToTest) { 322 selection.addAll(ds.searchWays(w.getBBox())); 323 } 324 } 325 for (Way w : selection) { 326 if (!w.isDeleted() && isPrimitiveUsable(w)) { 327 testWay(w); 328 } 329 } 330 // free storage 309 331 cellSegments.clear(); 310 332 seenWays.clear(); 333 if (partialSelection) { 334 removeIrrelevantErrors(waysToTest); 335 } 336 super.endTest(); 337 waysToTest.clear(); 338 ds = null; 311 339 } 312 340 313 341 static boolean isCoastline(OsmPrimitive w) { … … 344 372 345 373 @Override 346 374 public void visit(Way w) { 375 waysToTest.add(w); 376 } 377 378 private void testWay(Way w) { 347 379 boolean findSelfCrossingOnly = this instanceof SelfCrossing; 348 380 if (findSelfCrossingOnly) { 349 381 // free memory, we are not interested in previous ways … … 482 514 CheckParameterUtil.ensureParameterNotNull(way, "way"); 483 515 SelfCrossing test = new SelfCrossing(); 484 516 test.visit(way); 517 test.endTest(); 485 518 return !test.getErrors().isEmpty(); 486 519 } 487 520 } -
src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java
7 7 import java.util.Collection; 8 8 import java.util.Collections; 9 9 import java.util.HashSet; 10 import java.util.LinkedHashSet; 10 11 import java.util.LinkedList; 11 12 import java.util.List; 12 13 import java.util.Map; … … 103 104 104 105 /** Set of known hashcodes for list of coordinates **/ 105 106 private Set<Integer> knownHashCodes; 107 private List<Way> waysToCheck; 106 108 107 109 /** 108 110 * Constructor … … 115 117 @Override 116 118 public void startTest(ProgressMonitor monitor) { 117 119 super.startTest(monitor); 120 waysToCheck = new ArrayList<>(); 118 121 ways = new MultiMap<>(1000); 119 122 waysNoTags = new MultiMap<>(1000); 120 123 knownHashCodes = new HashSet<>(1000); … … 122 125 123 126 @Override 124 127 public void endTest() { 125 super.endTest(); 128 if (partialSelection && !waysToCheck.isEmpty()) { 129 // make sure that we have the error candidates even if not selected 130 Set<Way> extended = new LinkedHashSet<>(waysToCheck); 131 for (Way w : waysToCheck) { 132 // select a node, anyone can be used but a middle node is less likely to have many parent ways 133 final Node n = w.getNode(w.getNodesCount()/2); 134 // check the ways which might be in the same position 135 for (Way other : n.getParentWays()) { 136 if (other != w && !other.isDeleted() && other.isUsable() 137 && other.getNodesCount() == w.getNodesCount()) 138 extended.add(other); 139 } 140 } 141 extended.forEach(this::checkWay); 142 } 143 126 144 for (Set<OsmPrimitive> duplicated : ways.values()) { 127 145 if (duplicated.size() > 1) { 128 146 TestError testError = TestError.builder(this, Severity.ERROR, DUPLICATE_WAY) … … 162 180 errors.add(testError); 163 181 } 164 182 } 183 184 if (partialSelection) { 185 removeIrrelevantErrors(waysToCheck); 186 } 187 165 188 ways = null; 166 189 waysNoTags = null; 167 190 knownHashCodes = null; 191 waysToCheck = null; 192 super.endTest(); 168 193 } 169 194 170 195 /** … … 181 206 public void visit(Way w) { 182 207 if (!w.isUsable()) 183 208 return; 209 if (partialSelection) 210 waysToCheck.add(w); 211 else 212 checkWay(w); 213 } 214 215 private void checkWay(Way w) { 184 216 List<LatLon> wLat = getOrderedNodes(w); 185 217 // If this way has not direction-dependant keys, make sure the list is ordered the same for all ways (fix #8015) 186 218 if (!w.hasDirectionKeys()) {