1 | // License: GPL. See LICENSE file for details.
|
---|
2 | package org.openstreetmap.josm.data.validation.tests;
|
---|
3 |
|
---|
4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
5 |
|
---|
6 | import java.util.ArrayList;
|
---|
7 | import java.util.List;
|
---|
8 |
|
---|
9 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
10 | import org.openstreetmap.josm.data.osm.Way;
|
---|
11 | import org.openstreetmap.josm.data.validation.Severity;
|
---|
12 | import org.openstreetmap.josm.data.validation.Test;
|
---|
13 | import org.openstreetmap.josm.data.validation.TestError;
|
---|
14 | import org.openstreetmap.josm.gui.progress.ProgressMonitor;
|
---|
15 |
|
---|
16 | /**
|
---|
17 | * Check cyclic ways for errors
|
---|
18 | *
|
---|
19 | * @author jrreid
|
---|
20 | */
|
---|
21 | public class WronglyOrderedWays extends Test {
|
---|
22 |
|
---|
23 | protected static int WRONGLY_ORDERED_COAST = 1001;
|
---|
24 | protected static int WRONGLY_ORDERED_WATER = 1002;
|
---|
25 | protected static int WRONGLY_ORDERED_LAND = 1003;
|
---|
26 |
|
---|
27 | /**
|
---|
28 | * Constructor
|
---|
29 | */
|
---|
30 | public WronglyOrderedWays() {
|
---|
31 | super(tr("Wrongly Ordered Ways."),
|
---|
32 | tr("This test checks the direction of water, land and coastline ways."));
|
---|
33 | }
|
---|
34 |
|
---|
35 | @Override
|
---|
36 | public void startTest(ProgressMonitor monitor) {
|
---|
37 | super.startTest(monitor);
|
---|
38 | }
|
---|
39 |
|
---|
40 | @Override
|
---|
41 | public void endTest() {
|
---|
42 | super.endTest();
|
---|
43 | }
|
---|
44 |
|
---|
45 | @Override
|
---|
46 | public void visit(Way w) {
|
---|
47 | String errortype = "";
|
---|
48 | int type;
|
---|
49 |
|
---|
50 | if (!w.isUsable())
|
---|
51 | return;
|
---|
52 | if (w.getNodesCount() <= 0)
|
---|
53 | return;
|
---|
54 |
|
---|
55 | String natural = w.get("natural");
|
---|
56 | if (natural == null)
|
---|
57 | return;
|
---|
58 |
|
---|
59 | if (natural.equals("coastline")) {
|
---|
60 | errortype = tr("Reversed coastline: land not on left side");
|
---|
61 | type= WRONGLY_ORDERED_COAST;
|
---|
62 | } else if (natural.equals("water")) {
|
---|
63 | errortype = tr("Reversed water: land not on left side");
|
---|
64 | type= WRONGLY_ORDERED_WATER;
|
---|
65 | } else if (natural.equals("land")) {
|
---|
66 | errortype = tr("Reversed land: land not on left side");
|
---|
67 | type= WRONGLY_ORDERED_LAND;
|
---|
68 | } else
|
---|
69 | return;
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * Test the directionality of the way
|
---|
73 | *
|
---|
74 | * Assuming a closed non-looping way, compute twice the area
|
---|
75 | * of the polygon using the formula 2*a = sum (Xn * Yn+1 - Xn+1 * Yn)
|
---|
76 | * If the area is negative the way is ordered in a clockwise direction
|
---|
77 | *
|
---|
78 | */
|
---|
79 | if (w.getNode(0) == w.getNode(w.getNodesCount()-1)) {
|
---|
80 | double area2 = 0;
|
---|
81 |
|
---|
82 | for (int node = 1; node < w.getNodesCount(); node++) {
|
---|
83 | area2 += (w.getNode(node-1).getCoor().lon() * w.getNode(node).getCoor().lat()
|
---|
84 | - w.getNode(node).getCoor().lon() * w.getNode(node-1).getCoor().lat());
|
---|
85 | }
|
---|
86 |
|
---|
87 | if (((natural.equals("coastline") || natural.equals("land")) && area2 < 0.)
|
---|
88 | || (natural.equals("water") && area2 > 0.)) {
|
---|
89 | List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
|
---|
90 | primitives.add(w);
|
---|
91 | errors.add( new TestError(this, Severity.OTHER, errortype, type, primitives) );
|
---|
92 | }
|
---|
93 | }
|
---|
94 | }
|
---|
95 | }
|
---|