source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java @ 13690

Last change on this file since 13690 was 13690, checked in by Don-vip, 10 months ago

fix #16189 - increase right angle min threshold to 0.25 + allow 180° angles

  • Property svn:eol-style set to native
File size: 3.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collections;
7import java.util.List;
8
9import org.openstreetmap.josm.actions.OrthogonalizeAction;
10import org.openstreetmap.josm.actions.OrthogonalizeAction.InvalidUserInputException;
11import org.openstreetmap.josm.data.osm.Node;
12import org.openstreetmap.josm.data.osm.Way;
13import org.openstreetmap.josm.data.validation.Severity;
14import org.openstreetmap.josm.data.validation.Test;
15import org.openstreetmap.josm.data.validation.TestError;
16import org.openstreetmap.josm.gui.progress.ProgressMonitor;
17import org.openstreetmap.josm.spi.preferences.Config;
18import org.openstreetmap.josm.tools.Logging;
19import org.openstreetmap.josm.tools.Pair;
20
21/**
22 * Checks for buildings with angles close to right angle.
23 *
24 * @author marxin
25 * @since 13670
26 */
27public class RightAngleBuildingTest extends Test {
28
29    /** Maximum angle difference from right angle that is considered as invalid. */
30    protected double maxAngleDelta;
31
32    /** Minimum angle difference from right angle that is considered as invalid. */
33    protected double minAngleDelta;
34
35    /**
36     * Constructs a new {@code RightAngleBuildingTest} test.
37     */
38    public RightAngleBuildingTest() {
39        super(tr("Almost right angle buildings"),
40                tr("Checks for buildings that have angles close to right angle and are not orthogonalized."));
41    }
42
43    @Override
44    public void visit(Way w) {
45        if (!w.isUsable() || !w.isClosed() || !isBuilding(w)) return;
46
47        List<Pair<Double, Node>> angles = w.getAngles();
48        for (Pair<Double, Node> pair: angles) {
49            if (checkAngle(w, pair.a, pair.b)) {
50                TestError.Builder builder = TestError.builder(this, Severity.WARNING, 3701)
51                                                     .message(tr("Building with an almost square angle"))
52                                                     .primitives(w)
53                                                     .highlight(pair.b);
54                if (angles.stream().noneMatch(
55                        p -> Math.abs(p.a - 90) >= maxAngleDelta && Math.abs(p.a - 180) >= minAngleDelta)) {
56                    builder.fix(() -> {
57                        try {
58                            return OrthogonalizeAction.orthogonalize(Collections.singleton(w));
59                        } catch (InvalidUserInputException e) {
60                            Logging.warn(e);
61                            return null;
62                        }
63                    });
64                }
65                errors.add(builder.build());
66                return;
67            }
68        }
69    }
70
71    @Override
72    public void startTest(ProgressMonitor monitor) {
73        super.startTest(monitor);
74        maxAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.maximumDelta", 10.0);
75        minAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.minimumDelta", 0.25);
76    }
77
78    private boolean checkAngle(Way w, double angle, Node n) {
79        double difference = Math.abs(angle - 90);
80        return difference > minAngleDelta && difference < maxAngleDelta;
81    }
82}
Note: See TracBrowser for help on using the repository browser.