- Timestamp:
- 2024-01-30T09:04:11+01:00 (10 months ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/ValidateAction.java
r17616 r18960 13 13 import org.openstreetmap.josm.data.validation.Test; 14 14 import org.openstreetmap.josm.data.validation.ValidationTask; 15 import org.openstreetmap.josm.data.validation.util.AggregatePrimitivesVisitor;16 15 import org.openstreetmap.josm.gui.MainApplication; 17 16 import org.openstreetmap.josm.gui.MapFrame; … … 71 70 lastSelection = null; 72 71 } else { 73 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor();74 selection = v.visit(selection);75 72 lastSelection = selection; 76 73 } -
trunk/src/org/openstreetmap/josm/actions/upload/ValidateUploadHook.java
r18776 r18960 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; … … 18 19 import org.openstreetmap.josm.data.validation.TestError; 19 20 import org.openstreetmap.josm.data.validation.ValidationTask; 20 import org.openstreetmap.josm.data.validation.util.AggregatePrimitivesVisitor;21 21 import org.openstreetmap.josm.gui.ExtendedDialog; 22 22 import org.openstreetmap.josm.gui.MainApplication; … … 46 46 public boolean checkUpload(APIDataSet apiDataSet) { 47 47 AtomicBoolean returnCode = new AtomicBoolean(); 48 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor();49 v.visit(apiDataSet.getPrimitivesToAdd());50 Collection<OsmPrimitive> visited = v.visit(apiDataSet.getPrimitivesToUpdate());48 Collection<OsmPrimitive> toCheck = new HashSet<>(); 49 toCheck.addAll(apiDataSet.getPrimitivesToAdd()); 50 toCheck.addAll(apiDataSet.getPrimitivesToUpdate()); 51 51 OsmValidator.initializeTests(); 52 52 new ValidationTask(errors -> { … … 59 59 GuiHelper.runInEDTAndWait(() -> returnCode.set(displayErrorScreen(errors))); 60 60 } 61 }, null, OsmValidator.getEnabledTests(true), visited, null, true).run();61 }, null, OsmValidator.getEnabledTests(true), toCheck, null, true).run(); 62 62 63 63 return returnCode.get(); -
trunk/src/org/openstreetmap/josm/data/preferences/sources/ValidatorPrefHelper.java
r16296 r18960 58 58 59 59 /** 60 * See #23397 61 * The preferences key for the addition of parent objects for modified objects 62 */ 63 public static final BooleanProperty PREF_ADD_PARENTS = new BooleanProperty(PREFIX + ".partial.add.parents", true); 64 65 /** 66 * See #23397 67 * The preferences key for the deletion of results which do not belong to the selection 68 * or the parents of modified objects. 69 * 70 */ 71 public static final BooleanProperty PREF_REMOVE_IRRELEVANT = new BooleanProperty(PREFIX + ".partial.removeIrrelevant", true); 72 73 /** 60 74 * Constructs a new {@code PresetPrefHelper}. 61 75 */ -
trunk/src/org/openstreetmap/josm/data/validation/Test.java
r17732 r18960 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; … … 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 18960 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 } -
trunk/src/org/openstreetmap/josm/data/validation/TestError.java
r18637 r18960 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; … … 63 64 /** If this error is selected */ 64 65 private boolean selected; 66 /** If all relevant primitives are known*/ 67 private boolean incompletePrimitives; 65 68 /** Supplying a command to fix the error */ 66 69 private final Supplier<Command> fixingCommand; … … 81 84 private Collection<?> highlighted; 82 85 private Supplier<Command> fixingCommand; 86 private boolean incompletePrimitives; 83 87 84 88 Builder(Test tester, Severity severity, int code) { … … 215 219 CheckParameterUtil.ensureParameterNotNull(highlighted, "highlighted"); 216 220 this.highlighted = Collections.singleton(highlighted); 221 return this; 222 } 223 224 /** 225 * Sets a flag that the list of primitives may be incomplete. See #23397 226 * 227 * @return {@code this} 228 */ 229 public Builder imcompletePrimitives() { 230 this.incompletePrimitives = true; 217 231 return this; 218 232 } … … 277 291 this.uniqueCode = builder.uniqueCode; 278 292 this.fixingCommand = builder.fixingCommand; 293 this.incompletePrimitives = builder.incompletePrimitives; 279 294 } 280 295 … … 667 682 } 668 683 684 /** 685 * Check if any of the primitives in this error occurs in the given set of primitives. 686 * @param given the set of primitives 687 * @return true if any of the primitives in this error occurs in the given set of primitives, else false 688 * @since 18960 689 */ 690 public boolean isConcerned(Set<? extends OsmPrimitive> given) { 691 if (incompletePrimitives) 692 return true; 693 for (OsmPrimitive p : getPrimitives()) { 694 if (given.contains(p)) { 695 return true; 696 } 697 } 698 return false; 699 } 669 700 } -
trunk/src/org/openstreetmap/josm/data/validation/ValidationTask.java
r18850 r18960 7 7 import java.util.ArrayList; 8 8 import java.util.Collection; 9 import java.util.Collections; 10 import java.util.HashSet; 9 11 import java.util.List; 12 import java.util.Set; 10 13 import java.util.function.BiConsumer; 11 14 import java.util.function.Consumer; … … 14 17 15 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Way; 16 20 import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; 21 import org.openstreetmap.josm.data.validation.util.AggregatePrimitivesVisitor; 17 22 import org.openstreetmap.josm.gui.MainApplication; 18 23 import org.openstreetmap.josm.gui.MapFrame; … … 31 36 private final Consumer<List<TestError>> onFinish; 32 37 private Collection<Test> tests; 33 private final Collection<OsmPrimitive> validatedPrimitives;38 private final Collection<OsmPrimitive> initialPrimitives; 34 39 private final Collection<OsmPrimitive> formerValidatedPrimitives; 35 40 private final boolean beforeUpload; … … 72 77 false /*don't ignore exceptions */); 73 78 this.onFinish = onFinish; 74 this. validatedPrimitives = validatedPrimitives;79 this.initialPrimitives = validatedPrimitives; 75 80 this.formerValidatedPrimitives = formerValidatedPrimitives; 76 81 this.tests = tests; … … 78 83 } 79 84 85 /** 86 * Find objects parent objects of given objects which should be checked for geometry problems 87 * or mismatches between child tags and parent tags. 88 * @param primitives the given objects 89 * @return the collection of relevant parent objects 90 */ 91 private static Set<OsmPrimitive> getRelevantParents(Collection<OsmPrimitive> primitives) { 92 Set<OsmPrimitive> addedWays = new HashSet<>(); 93 Set<OsmPrimitive> addedRelations = new HashSet<>(); 94 for (OsmPrimitive p : primitives) { 95 for (OsmPrimitive parent : p.getReferrers()) { 96 if (parent.isDeleted()) 97 continue; 98 if (parent instanceof Way) 99 addedWays.add(parent); 100 else 101 addedRelations.add(parent); 102 } 103 } 104 105 // allow to find invalid multipolygon relations caused by moved nodes 106 OsmPrimitive.getParentRelations(addedWays).stream().filter(r -> r.isMultipolygon() && !r.isDeleted()) 107 .forEach(addedRelations::add); 108 HashSet<OsmPrimitive> extendedSet = new HashSet<>(); 109 extendedSet.addAll(addedWays); 110 extendedSet.addAll(addedRelations); 111 return extendedSet; 112 113 } 80 114 protected ValidationTask(ProgressMonitor progressMonitor, 81 115 Collection<Test> tests, … … 123 157 if (Utils.isEmpty(tests)) 124 158 return; 159 int testCounter = 0; 160 final boolean isPartial = this.beforeUpload || formerValidatedPrimitives != null; 161 Set<OsmPrimitive> filter = null; 162 Collection<OsmPrimitive> validatedPrimitives = initialPrimitives; 163 if (isPartial) { 164 Set<OsmPrimitive> other = Collections.emptySet(); 165 if (Boolean.TRUE.equals(ValidatorPrefHelper.PREF_ADD_PARENTS.get())) { 166 other = getRelevantParents(initialPrimitives); 167 } 168 HashSet<OsmPrimitive> extendedSet = new HashSet<>(); 169 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor(); 170 extendedSet.addAll(v.visit(initialPrimitives)); 171 extendedSet.addAll(other); 172 validatedPrimitives = extendedSet; 173 filter = new HashSet<>(initialPrimitives); 174 filter.addAll(other); 175 } 125 176 getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size()); 126 int testCounter = 0; 177 127 178 for (Test test : tests) { 128 179 if (canceled) … … 132 183 test.setBeforeUpload(this.beforeUpload); 133 184 // Pre-upload checks only run on a partial selection. 134 test.setPartialSelection( this.beforeUpload || formerValidatedPrimitives != null);185 test.setPartialSelection(isPartial); 135 186 test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false)); 136 187 test.visit(validatedPrimitives); 137 188 test.endTest(); 189 if (isPartial && Boolean.TRUE.equals(ValidatorPrefHelper.PREF_REMOVE_IRRELEVANT.get())) { 190 // #23397: remove errors for objects which were not in the initial list of primitives 191 test.removeIrrelevantErrors(filter); 192 } 193 138 194 errors.addAll(test.getErrors()); 139 195 if (this.testConsumer != null) { -
trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
r18870 r18960 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; … … 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; … … 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; … … 306 310 @Override 307 311 public void endTest() { 308 super.endTest(); 312 final Collection<Way> selection; 313 if (this instanceof SelfCrossing || !partialSelection) { 314 selection = waysToTest; 315 } else { 316 selection = new HashSet<>(); 317 DataSet ds = OsmDataManager.getInstance().getActiveDataSet(); 318 if (ds != null) { 319 for (Way w: waysToTest) { 320 selection.addAll(ds.searchWays(w.getBBox())); 321 } 322 } 323 } 324 for (Way w : selection) { 325 if (!w.isDeleted() && isPrimitiveUsable(w)) { 326 testWay(w); 327 } 328 } 329 // free storage 309 330 cellSegments.clear(); 310 331 seenWays.clear(); 332 waysToTest.clear(); 333 if (partialSelection) 334 removeIrrelevantErrors(waysToTest); 335 super.endTest(); 311 336 } 312 337 … … 345 370 @Override 346 371 public void visit(Way w) { 372 waysToTest.add(w); 373 } 374 375 private void testWay(Way w) { 347 376 boolean findSelfCrossingOnly = this instanceof SelfCrossing; 348 377 if (findSelfCrossingOnly) { … … 483 512 SelfCrossing test = new SelfCrossing(); 484 513 test.visit(way); 514 test.endTest(); 485 515 return !test.getErrors().isEmpty(); 486 516 } -
trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java
r17243 r18960 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; … … 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 /** … … 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); … … 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) { … … 166 184 waysNoTags = null; 167 185 knownHashCodes = null; 186 waysToCheck = null; 187 super.endTest(); 168 188 } 169 189 … … 182 202 if (!w.isUsable()) 183 203 return; 204 if (partialSelection) 205 waysToCheck.add(w); 206 else 207 checkWay(w); 208 } 209 210 private void checkWay(Way w) { 184 211 List<LatLon> wLat = getOrderedNodes(w); 185 212 // If this way has not direction-dependant keys, make sure the list is ordered the same for all ways (fix #8015) -
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerRule.java
r18762 r18960 34 34 import org.openstreetmap.josm.gui.mappaint.MultiCascade; 35 35 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 36 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition; 36 37 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 37 38 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; … … 378 379 } 379 380 } 381 } else if (env.parent != null) { 382 boolean imcompletePrimitives = false; 383 if (matchingSelector instanceof Selector.ChildOrParentSelector) { 384 Selector right = ((Selector.ChildOrParentSelector) matchingSelector).right; 385 if (right.getConditions().stream().anyMatch(ClassCondition.class::isInstance)) { 386 // see #23397 387 // TODO: find a way to collect all and only those parent objects which triggered this error 388 imcompletePrimitives = true; 389 } 390 } 391 if (imcompletePrimitives) 392 res.add(errorBuilder.primitives(p).highlight(p).imcompletePrimitives().build()); 393 else 394 res.add(errorBuilder.primitives(p, (OsmPrimitive) env.parent).highlight(p).build()); 380 395 } else { 381 396 res.add(errorBuilder.primitives(p).build()); -
trunk/src/org/openstreetmap/josm/data/validation/util/AggregatePrimitivesVisitor.java
r12809 r18960 15 15 * A visitor that aggregates all primitives it visits. 16 16 * <p> 17 * The primitives are sorted according to their type: first nodes, then ways.18 17 * 19 18 * @author frsantos … … 25 24 /** 26 25 * Visits a collection of primitives 27 * @param data The collection of primitives 26 * @param data The collection of primitives in no specific order. 28 27 * @return The aggregated primitives 29 28 */
Note:
See TracChangeset
for help on using the changeset viewer.