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

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

see #16189 - do not alter non-orthogonal building shapes

  • Property svn:eol-style set to native
File size: 3.1 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(p -> Math.abs(p.a - 90) >= maxAngleDelta)) {
55                    builder.fix(() -> {
56                        try {
57                            return OrthogonalizeAction.orthogonalize(Collections.singleton(w));
58                        } catch (InvalidUserInputException e) {
59                            Logging.warn(e);
60                            return null;
61                        }
62                    });
63                }
64                errors.add(builder.build());
65                return;
66            }
67        }
68    }
69
70    @Override
71    public void startTest(ProgressMonitor monitor) {
72        super.startTest(monitor);
73        maxAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.maximumDelta", 10.0);
74        minAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.minimumDelta", 0.1);
75    }
76
77    private boolean checkAngle(Way w, double angle, Node n) {
78        double difference = Math.abs(angle - 90);
79        return difference > minAngleDelta && difference < maxAngleDelta;
80    }
81}
Note: See TracBrowser for help on using the repository browser.