Ticket #23397: 23397-also-add-mp.patch
File 23397-also-add-mp.patch, 14.0 KB (added by , 18 months ago) |
---|
-
src/org/openstreetmap/josm/actions/ValidateAction.java
12 12 import org.openstreetmap.josm.data.validation.OsmValidator; 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; 18 17 import org.openstreetmap.josm.tools.Shortcut; … … 70 69 selection = getLayerManager().getActiveDataSet().allNonDeletedPrimitives(); 71 70 lastSelection = null; 72 71 } else { 73 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor();74 selection = v.visit(selection);75 72 lastSelection = selection; 76 73 } 77 74 } else { -
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 … … 17 18 import org.openstreetmap.josm.data.validation.OsmValidator; 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; 23 23 import org.openstreetmap.josm.gui.dialogs.validator.ValidatorTreePanel; … … 45 45 @Override 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 -> { 53 53 if (errors.stream().allMatch(TestError::isIgnored)) { … … 58 58 // of the progress monitor. 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(); 64 64 } -
src/org/openstreetmap/josm/data/validation/ValidationTask.java
6 6 import java.awt.GraphicsEnvironment; 7 7 import java.util.ArrayList; 8 8 import java.util.Collection; 9 import java.util.HashSet; 9 10 import java.util.List; 11 import java.util.Set; 10 12 import java.util.function.BiConsumer; 11 13 import java.util.function.Consumer; 12 14 13 15 import javax.swing.JOptionPane; 14 16 17 import org.openstreetmap.josm.data.osm.Node; 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; 19 24 import org.openstreetmap.josm.gui.Notification; … … 30 35 public class ValidationTask extends PleaseWaitRunnable { 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; 36 41 private boolean canceled; … … 71 76 progressMonitor != null ? progressMonitor : new PleaseWaitProgressMonitor(tr("Validating")), 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; 77 82 this.beforeUpload = beforeUpload; 78 83 } 79 84 85 /** 86 * Create extended collection 87 * - add child objects because MapCss tests may need them to work properly 88 * - add parent objects of modified nodes as they may mean a geometry change (see #23397) 89 * @param primitives the primitives 90 * @return extended collection of primitives 91 */ 92 private static Collection<OsmPrimitive> extendCollection(Collection<OsmPrimitive> primitives) { 93 Set<OsmPrimitive> addedWays = new HashSet<>(); 94 Set<OsmPrimitive> addedRelations = new HashSet<>(); 95 for (OsmPrimitive p : primitives) { 96 if (!(p instanceof Node && p.isModified() && !p.isNew())) 97 continue; 98 for (OsmPrimitive parent : p.getReferrers()) { 99 if (parent.isDeleted() || parent.isModified() || parent.isNew()) 100 continue; 101 if (parent instanceof Way) 102 addedWays.add(parent); 103 else 104 addedRelations.add(parent); 105 } 106 } 107 // allow to find invalid multipolygon relations caused by moved nodes 108 OsmPrimitive.getParentRelations(addedWays).stream().filter(r -> r.isMultipolygon()) 109 .forEach(addedRelations::add); 110 HashSet<OsmPrimitive> extendedSet = new HashSet<>(); 111 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor(); 112 extendedSet.addAll(v.visit(primitives)); 113 extendedSet.addAll(addedWays); 114 extendedSet.addAll(addedRelations); 115 return extendedSet; 116 } 117 80 118 protected ValidationTask(ProgressMonitor progressMonitor, 81 119 Collection<Test> tests, 82 120 Collection<OsmPrimitive> validatedPrimitives, … … 122 160 protected void realRun() { 123 161 if (Utils.isEmpty(tests)) 124 162 return; 163 int testCounter = 0; 164 final boolean isPartial = this.beforeUpload || formerValidatedPrimitives != null; 165 166 Collection<OsmPrimitive> validatedPrimitives = isPartial ? extendCollection(initialPrimitives) : initialPrimitives; 125 167 getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size()); 126 int testCounter = 0; 168 127 169 for (Test test : tests) { 128 170 if (canceled) 129 171 return; … … 131 173 getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter, tests.size(), test.getName())); 132 174 test.setBeforeUpload(this.beforeUpload); 133 175 // Pre-upload checks only run on a partial selection. 134 test.setPartialSelection( this.beforeUpload || formerValidatedPrimitives != null);176 test.setPartialSelection(isPartial); 135 177 test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false)); 136 178 test.visit(validatedPrimitives); 137 179 test.endTest(); -
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; 86 90 … … 305 309 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 super.endTest(); 311 334 } 312 335 313 336 static boolean isCoastline(OsmPrimitive w) { … … 344 367 345 368 @Override 346 369 public void visit(Way w) { 370 waysToTest.add(w); 371 } 372 373 private void testWay(Way w) { 347 374 boolean findSelfCrossingOnly = this instanceof SelfCrossing; 348 375 if (findSelfCrossingOnly) { 349 376 // free memory, we are not interested in previous ways … … 482 509 CheckParameterUtil.ensureParameterNotNull(way, "way"); 483 510 SelfCrossing test = new SelfCrossing(); 484 511 test.visit(way); 512 test.endTest(); 485 513 return !test.getErrors().isEmpty(); 486 514 } 487 515 } -
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) … … 165 183 ways = null; 166 184 waysNoTags = null; 167 185 knownHashCodes = null; 186 waysToCheck = null; 187 super.endTest(); 168 188 } 169 189 170 190 /** … … 181 201 public void visit(Way w) { 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) 186 213 if (!w.hasDirectionKeys()) { -
src/org/openstreetmap/josm/data/validation/util/AggregatePrimitivesVisitor.java
14 14 /** 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 20 19 */ … … 24 23 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 */ 30 29 public Collection<OsmPrimitive> visit(Collection<OsmPrimitive> data) {