source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java@ 3715

Last change on this file since 3715 was 3671, checked in by bastiK, 13 years ago

adapt coding style (to some degree); there shouldn't be any semantic changes in this commit

  • Property svn:eol-style set to native
File size: 7.4 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.geom.Line2D;
7import java.awt.geom.Point2D;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Map;
14
15import org.openstreetmap.josm.data.osm.Node;
16import org.openstreetmap.josm.data.osm.Way;
17import org.openstreetmap.josm.data.osm.WaySegment;
18import org.openstreetmap.josm.data.validation.OsmValidator;
19import org.openstreetmap.josm.data.validation.Severity;
20import org.openstreetmap.josm.data.validation.Test;
21import org.openstreetmap.josm.data.validation.TestError;
22import org.openstreetmap.josm.data.validation.util.ValUtil;
23import org.openstreetmap.josm.gui.progress.ProgressMonitor;
24
25/**
26 * Tests if there are segments that crosses in the same layer
27 *
28 * @author frsantos
29 */
30public class CrossingWays extends Test {
31 protected static int CROSSING_WAYS = 601;
32
33 /** All way segments, grouped by cells */
34 Map<Point2D,List<ExtendedSegment>> cellSegments;
35 /** The already detected errors */
36 HashSet<WaySegment> errorSegments;
37 /** The already detected ways in error */
38 Map<List<Way>, List<WaySegment>> ways_seen;
39
40 /**
41 * Constructor
42 */
43 public CrossingWays() {
44 super(tr("Crossing ways."),
45 tr("This test checks if two roads, railways, waterways or buildings crosses in the same layer, but are not connected by a node."));
46 }
47
48 @Override
49 public void startTest(ProgressMonitor monitor) {
50 super.startTest(monitor);
51 cellSegments = new HashMap<Point2D,List<ExtendedSegment>>(1000);
52 errorSegments = new HashSet<WaySegment>();
53 ways_seen = new HashMap<List<Way>, List<WaySegment>>(50);
54 }
55
56 @Override
57 public void endTest() {
58 super.endTest();
59 cellSegments = null;
60 errorSegments = null;
61 ways_seen = null;
62 }
63
64 @Override
65 public void visit(Way w) {
66 if(!w.isUsable())
67 return;
68
69 String coastline1 = w.get("natural");
70 boolean isCoastline1 = "water".equals(coastline1) || "coastline".equals(coastline1);
71 String railway1 = w.get("railway");
72 boolean isSubway1 = "subway".equals(railway1);
73 boolean isTram1 = "tram".equals(railway1);
74 boolean isBuilding = (w.get("building") != null);
75
76 if (w.get("highway") == null && w.get("waterway") == null
77 && (railway1 == null || isSubway1 || isTram1)
78 && !isCoastline1 && !isBuilding)
79 return;
80
81 String layer1 = w.get("layer");
82
83 int nodesSize = w.getNodesCount();
84 for (int i = 0; i < nodesSize - 1; i++) {
85 WaySegment ws = new WaySegment(w, i);
86 ExtendedSegment es1 = new ExtendedSegment(ws, layer1, railway1, coastline1);
87 List<List<ExtendedSegment>> cellSegments = getSegments(es1.n1, es1.n2);
88 for (List<ExtendedSegment> segments : cellSegments) {
89 for (ExtendedSegment es2 : segments) {
90 List<Way> prims;
91 List<WaySegment> highlight;
92
93 if (errorSegments.contains(ws) && errorSegments.contains(es2.ws))
94 continue;
95
96 String layer2 = es2.layer;
97 String railway2 = es2.railway;
98 String coastline2 = es2.coastline;
99 if (layer1 == null ? layer2 != null : !layer1.equals(layer2))
100 continue;
101
102 if (!es1.intersects(es2) ) continue;
103 if (isSubway1 && "subway".equals(railway2)) continue;
104 if (isTram1 && "tram".equals(railway2)) continue;
105
106 boolean isCoastline2 = coastline2 != null && (coastline2.equals("water") || coastline2.equals("coastline"));
107 if (isCoastline1 != isCoastline2) continue;
108
109 if ((es1.railway != null && es1.railway.equals("abandoned"))
110 || (railway2 != null && railway2.equals("abandoned"))) continue;
111
112 prims = Arrays.asList(es1.ws.way, es2.ws.way);
113 if ((highlight = ways_seen.get(prims)) == null) {
114 highlight = new ArrayList<WaySegment>();
115 highlight.add(es1.ws);
116 highlight.add(es2.ws);
117
118 errors.add(new TestError(this, Severity.WARNING,
119 isBuilding ? tr("Crossing buildings") : tr("Crossing ways"),
120 CROSSING_WAYS,
121 prims,
122 highlight));
123 ways_seen.put(prims, highlight);
124 } else {
125 highlight.add(es1.ws);
126 highlight.add(es2.ws);
127 }
128 }
129 segments.add(es1);
130 }
131 }
132 }
133
134 /**
135 * Returns all the cells this segment crosses. Each cell contains the list
136 * of segments already processed
137 *
138 * @param n1 The first node
139 * @param n2 The second node
140 * @return A list with all the cells the segment crosses
141 */
142 public List<List<ExtendedSegment>> getSegments(Node n1, Node n2) {
143
144 List<List<ExtendedSegment>> cells = new ArrayList<List<ExtendedSegment>>();
145 for(Point2D cell : ValUtil.getSegmentCells(n1, n2, OsmValidator.griddetail)) {
146 List<ExtendedSegment> segments = cellSegments.get(cell);
147 if (segments == null) {
148 segments = new ArrayList<ExtendedSegment>();
149 cellSegments.put(cell, segments);
150 }
151 cells.add(segments);
152 }
153 return cells;
154 }
155
156 /**
157 * A way segment with some additional information
158 * @author frsantos
159 */
160 public static class ExtendedSegment {
161 public Node n1, n2;
162
163 public WaySegment ws;
164
165 /** The layer */
166 public String layer;
167
168 /** The railway type */
169 public String railway;
170
171 /** The coastline type */
172 public String coastline;
173
174 /**
175 * Constructor
176 * @param ws The way segment
177 * @param layer The layer of the way this segment is in
178 * @param railway The railway type of the way this segment is in
179 * @param coastline The coastline typo of the way the segment is in
180 */
181 public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline) {
182 this.ws = ws;
183 this.n1 = ws.way.getNodes().get(ws.lowerIndex);
184 this.n2 = ws.way.getNodes().get(ws.lowerIndex + 1);
185 this.layer = layer;
186 this.railway = railway;
187 this.coastline = coastline;
188 }
189
190 /**
191 * Checks whether this segment crosses other segment
192 * @param s2 The other segment
193 * @return true if both segments crosses
194 */
195 public boolean intersects(ExtendedSegment s2) {
196 if (n1.equals(s2.n1) || n2.equals(s2.n2) ||
197 n1.equals(s2.n2) || n2.equals(s2.n1))
198 return false;
199
200 return Line2D.linesIntersect(
201 n1.getEastNorth().east(), n1.getEastNorth().north(),
202 n2.getEastNorth().east(), n2.getEastNorth().north(),
203 s2.n1.getEastNorth().east(), s2.n1.getEastNorth().north(),
204 s2.n2.getEastNorth().east(), s2.n2.getEastNorth().north());
205 }
206 }
207}
Note: See TracBrowser for help on using the repository browser.