source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/Coastlines.java@ 10448

Last change on this file since 10448 was 10448, checked in by Don-vip, 8 years ago

fix more deprecation warnings

  • Property svn:eol-style set to native
File size: 7.8 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.awt.geom.Area;
7import java.util.ArrayList;
8import java.util.Collection;
9import java.util.Collections;
10import java.util.Iterator;
11import java.util.LinkedList;
12import java.util.List;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.command.ChangeCommand;
16import org.openstreetmap.josm.command.Command;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.Way;
20import org.openstreetmap.josm.data.validation.Severity;
21import org.openstreetmap.josm.data.validation.Test;
22import org.openstreetmap.josm.data.validation.TestError;
23import org.openstreetmap.josm.gui.layer.OsmDataLayer;
24import org.openstreetmap.josm.gui.progress.ProgressMonitor;
25
26/**
27 * Check coastlines for errors
28 *
29 * @author frsantos
30 * @author Teemu Koskinen
31 */
32public class Coastlines extends Test {
33
34 protected static final int UNORDERED_COASTLINE = 901;
35 protected static final int REVERSED_COASTLINE = 902;
36 protected static final int UNCONNECTED_COASTLINE = 903;
37
38 private List<Way> coastlines;
39
40 private Area downloadedArea;
41
42 /**
43 * Constructor
44 */
45 public Coastlines() {
46 super(tr("Coastlines"), tr("This test checks that coastlines are correct."));
47 }
48
49 @Override
50 public void startTest(ProgressMonitor monitor) {
51
52 super.startTest(monitor);
53
54 OsmDataLayer layer = Main.getLayerManager().getEditLayer();
55
56 if (layer != null) {
57 downloadedArea = layer.data.getDataSourceArea();
58 }
59
60 coastlines = new LinkedList<>();
61 }
62
63 @Override
64 public void endTest() {
65 for (Way c1 : coastlines) {
66 Node head = c1.firstNode();
67 Node tail = c1.lastNode();
68
69 if (c1.getNodesCount() == 0 || head.equals(tail)) {
70 continue;
71 }
72
73 int headWays = 0;
74 int tailWays = 0;
75 boolean headReversed = false;
76 boolean tailReversed = false;
77 boolean headUnordered = false;
78 boolean tailUnordered = false;
79 Way next = null;
80 Way prev = null;
81
82 for (Way c2 : coastlines) {
83 if (c1 == c2) {
84 continue;
85 }
86
87 if (c2.containsNode(head)) {
88 headWays++;
89 next = c2;
90
91 if (head.equals(c2.firstNode())) {
92 headReversed = true;
93 } else if (!head.equals(c2.lastNode())) {
94 headUnordered = true;
95 }
96 }
97
98 if (c2.containsNode(tail)) {
99 tailWays++;
100 prev = c2;
101
102 if (tail.equals(c2.lastNode())) {
103 tailReversed = true;
104 } else if (!tail.equals(c2.firstNode())) {
105 tailUnordered = true;
106 }
107 }
108 }
109
110 // To avoid false positives on upload (only modified primitives
111 // are visited), we have to check possible connection to ways
112 // that are not in the set of validated primitives.
113 if (headWays == 0) {
114 Collection<OsmPrimitive> refs = head.getReferrers();
115 for (OsmPrimitive ref : refs) {
116 if (ref != c1 && isCoastline(ref)) {
117 // ref cannot be in <code>coastlines</code>, otherwise we would
118 // have picked it up already
119 headWays++;
120 next = (Way) ref;
121
122 if (head.equals(next.firstNode())) {
123 headReversed = true;
124 } else if (!head.equals(next.lastNode())) {
125 headUnordered = true;
126 }
127 }
128 }
129 }
130 if (tailWays == 0) {
131 Collection<OsmPrimitive> refs = tail.getReferrers();
132 for (OsmPrimitive ref : refs) {
133 if (ref != c1 && isCoastline(ref)) {
134 tailWays++;
135 prev = (Way) ref;
136
137 if (tail.equals(prev.lastNode())) {
138 tailReversed = true;
139 } else if (!tail.equals(prev.firstNode())) {
140 tailUnordered = true;
141 }
142 }
143 }
144 }
145
146 List<OsmPrimitive> primitives = new ArrayList<>();
147 primitives.add(c1);
148
149 if (headWays == 0 || tailWays == 0) {
150 List<OsmPrimitive> highlight = new ArrayList<>();
151
152 if (headWays == 0 && head.getCoor().isIn(downloadedArea)) {
153 highlight.add(head);
154 }
155 if (tailWays == 0 && tail.getCoor().isIn(downloadedArea)) {
156 highlight.add(tail);
157 }
158
159 if (!highlight.isEmpty()) {
160 errors.add(new TestError(this, Severity.ERROR, tr("Unconnected coastline"),
161 UNCONNECTED_COASTLINE, primitives, highlight));
162 }
163 }
164
165 boolean unordered = false;
166 boolean reversed = headWays == 1 && headReversed && tailWays == 1 && tailReversed;
167
168 if (headWays > 1 || tailWays > 1) {
169 unordered = true;
170 } else if (headUnordered || tailUnordered) {
171 unordered = true;
172 } else if (reversed && next == prev) {
173 unordered = true;
174 } else if ((headReversed || tailReversed) && headReversed != tailReversed) {
175 unordered = true;
176 }
177
178 if (unordered) {
179 List<OsmPrimitive> highlight = new ArrayList<>();
180
181 if (headWays > 1 || headUnordered || headReversed || reversed) {
182 highlight.add(head);
183 }
184 if (tailWays > 1 || tailUnordered || tailReversed || reversed) {
185 highlight.add(tail);
186 }
187
188 errors.add(new TestError(this, Severity.ERROR, tr("Unordered coastline"),
189 UNORDERED_COASTLINE, primitives, highlight));
190 } else if (reversed) {
191 errors.add(new TestError(this, Severity.ERROR, tr("Reversed coastline"),
192 REVERSED_COASTLINE, primitives));
193 }
194 }
195
196 coastlines = null;
197 downloadedArea = null;
198
199 super.endTest();
200 }
201
202 @Override
203 public void visit(Way way) {
204 if (!way.isUsable())
205 return;
206
207 if (isCoastline(way)) {
208 coastlines.add(way);
209 }
210 }
211
212 private static boolean isCoastline(OsmPrimitive osm) {
213 return osm instanceof Way && "coastline".equals(osm.get("natural"));
214 }
215
216 @Override
217 public Command fixError(TestError testError) {
218 if (isFixable(testError)) {
219 // primitives list can be empty if all primitives have been purged
220 Iterator<? extends OsmPrimitive> it = testError.getPrimitives().iterator();
221 if (it.hasNext()) {
222 Way way = (Way) it.next();
223 Way newWay = new Way(way);
224
225 List<Node> nodesCopy = newWay.getNodes();
226 Collections.reverse(nodesCopy);
227 newWay.setNodes(nodesCopy);
228
229 return new ChangeCommand(way, newWay);
230 }
231 }
232 return null;
233 }
234
235 @Override
236 public boolean isFixable(TestError testError) {
237 if (testError.getTester() instanceof Coastlines)
238 return testError.getCode() == REVERSED_COASTLINE;
239
240 return false;
241 }
242}
Note: See TracBrowser for help on using the repository browser.