Changeset 9684 in osm for applications/editors/josm/plugins/validator
- Timestamp:
- 2008-08-11T22:26:25+02:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java
r9269 r9684 23 23 24 24 /** 25 * 25 * 26 26 * A OSM data validator 27 * 27 * 28 28 * @author Francisco R. Santos <frsantos@gmail.com> 29 29 */ 30 30 public class OSMValidatorPlugin extends Plugin implements LayerChangeListener 31 31 { 32 33 34 35 36 37 38 39 32 /** The validate action */ 33 ValidateAction validateAction = new ValidateAction(this); 34 35 /** The validation dialog */ 36 ValidatorDialog validationDialog; 37 38 /** The list of errors per layer*/ 39 Map<Layer, List<TestError>> layerErrors = new HashMap<Layer, List<TestError>>(); 40 40 41 41 /** … … 45 45 public static Class[] allAvailableTests = new Class[] 46 46 { 47 DuplicateNode.class, 48 OverlappingWays.class, 49 UntaggedNode.class, 50 UntaggedWay.class, 51 SelfIntersectingWay.class, 52 DuplicatedWayNodes.class, 53 CrossingWays.class, 54 SimilarNamedWays.class, 55 NodesWithSameName.class, 56 Coastlines.class, 57 WronglyOrderedWays.class, 58 UnclosedWays.class, 59 TagChecker.class, 47 DuplicateNode.class, // ID 1 .. 99 48 OverlappingWays.class, // ID 101 .. 199 49 UntaggedNode.class, // ID 201 .. 299 50 UntaggedWay.class, // ID 301 .. 399 51 SelfIntersectingWay.class, // ID 401 .. 499 52 DuplicatedWayNodes.class, // ID 501 .. 599 53 CrossingWays.class, // ID 601 .. 699 54 SimilarNamedWays.class, // ID 701 .. 799 55 NodesWithSameName.class, // ID 801 .. 899 56 Coastlines.class, // ID 901 .. 999 57 WronglyOrderedWays.class, // ID 1001 .. 1099 58 UnclosedWays.class, // ID 1101 .. 1199 59 TagChecker.class, // ID 1201 .. 1299 60 60 }; 61 61 … … 70 70 71 71 @Override 72 public PreferenceSetting getPreferenceSetting() 72 public PreferenceSetting getPreferenceSetting() 73 73 { 74 74 return new PreferenceEditor(this); … … 76 76 77 77 @Override 78 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) 78 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) 79 79 { 80 80 if (newFrame != null) 81 81 { 82 83 84 85 86 87 Layer.listeners.add(this); 82 validationDialog = new ValidatorDialog(this); 83 newFrame.addToggleDialog(validationDialog); 84 Main.main.addLayer(new ErrorLayer(this)); 85 if( Main.pref.hasKey(PreferenceEditor.PREF_DEBUG + ".grid") ) 86 Main.main.addLayer(new GridLayer(tr("Grid"))); 87 Layer.listeners.add(this); 88 88 } 89 89 else 90 Layer.listeners.remove(this); 91 90 Layer.listeners.remove(this); 91 92 92 LinkedList<UploadHook> hooks = ((UploadAction)Main.main.menu.upload).uploadHooks; 93 Iterator<UploadHook> hooksIt = hooks.iterator(); 93 Iterator<UploadHook> hooksIt = hooks.iterator(); 94 94 while( hooksIt.hasNext() ) 95 95 { … … 161 161 } 162 162 163 164 165 * 166 * @return An array of the test classes validationDialog.tree.setErrorList(errors); 167 168 169 170 171 172 163 /** 164 * Gets the list of all available test classes 165 * 166 * @return An array of the test classes 167 */ 168 public static Class[] getAllAvailableTests() 169 { 170 return allAvailableTests; 171 } 172 173 173 /** 174 174 * Initializes all tests … … 185 185 test.getClass().getMethod("initialize", new Class[] { OSMValidatorPlugin.class} ).invoke(null, new Object[] {this}); 186 186 } 187 } 188 catch(InvocationTargetException ite) 189 { 190 ite.getCause().printStackTrace(); 191 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", test.getClass().getSimpleName(), ite.getCause().getMessage())); 192 } 193 catch(Exception e) 194 { 195 e.printStackTrace(); 196 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", test.getClass().getSimpleName(), e)); 197 } 198 } 199 } 200 201 public void activeLayerChange(Layer oldLayer, Layer newLayer) 187 } 188 catch(InvocationTargetException ite) 189 { 190 ite.getCause().printStackTrace(); 191 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", 192 test.getClass().getSimpleName(), ite.getCause().getMessage())); 193 } 194 catch(Exception e) 195 { 196 e.printStackTrace(); 197 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", 198 test.getClass().getSimpleName(), e)); 199 } 200 } 201 } 202 203 public void activeLayerChange(Layer oldLayer, Layer newLayer) 202 204 { 203 205 if( newLayer instanceof OsmDataLayer ) 204 206 { 205 206 207 Main.map.repaint(); 208 } 209 } 210 211 public void layerAdded(Layer newLayer) 207 List<TestError> errors = layerErrors.get(newLayer); 208 validationDialog.tree.setErrorList(errors); 209 Main.map.repaint(); 210 } 211 } 212 213 public void layerAdded(Layer newLayer) 212 214 { 213 215 if( newLayer instanceof OsmDataLayer ) … … 217 219 } 218 220 219 public void layerRemoved(Layer oldLayer) 221 public void layerRemoved(Layer oldLayer) 220 222 { 221 223 layerErrors.remove(oldLayer); -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java
r9598 r9684 33 33 private Test tester; 34 34 /** Internal code used by testers to classify errors */ 35 private int internalCode = -1;35 private int code; 36 36 /** If this error is selected */ 37 37 private boolean selected; 38 38 39 39 /** 40 40 * Constructors … … 44 44 * @param primitive The affected primitive 45 45 * @param primitives The affected primitives 46 * @param internalCode The internalcode47 */ 48 public TestError(Test tester, Severity severity, String message, String description, 46 * @param code The test error reference code 47 */ 48 public TestError(Test tester, Severity severity, String message, String description, int code, 49 49 List<? extends OsmPrimitive> primitives, List<?> highlighted) { 50 50 this.tester = tester; … … 54 54 this.primitives = primitives; 55 55 this.highlighted = highlighted; 56 } 57 public TestError(Test tester, Severity severity, String message, List<? extends OsmPrimitive> primitives, List<?> highlighted) 58 { 59 this(tester, severity, message, null, primitives, highlighted); 60 } 61 public TestError(Test tester, Severity severity, String message, String description, List<? extends OsmPrimitive> primitives) 62 { 63 this(tester, severity, message, description, primitives, primitives); 64 } 65 public TestError(Test tester, Severity severity, String message, List<? extends OsmPrimitive> primitives) 66 { 67 this(tester, severity, message, null, primitives, primitives); 68 } 69 public TestError(Test tester, Severity severity, String message, OsmPrimitive primitive) 70 { 71 this(tester, severity, message, null, Collections.singletonList(primitive), Collections.singletonList(primitive)); 72 } 73 public TestError(Test tester, Severity severity, String message, String description, OsmPrimitive primitive) 74 { 75 this(tester, severity, message, description, Collections.singletonList(primitive)); 76 } 77 public TestError(Test tester, Severity severity, String message, OsmPrimitive primitive, int internalCode) 78 { 79 this(tester, severity, message, null, primitive); 80 this.internalCode = internalCode; 81 } 82 public TestError(Test tester, Severity severity, String message, String description, OsmPrimitive primitive, int internalCode) 83 { 84 this(tester, severity, message, description, primitive); 85 this.internalCode = internalCode; 56 this.code = code; 57 } 58 public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives, List<?> highlighted) 59 { 60 this(tester, severity, message, null, code, primitives, highlighted); 61 } 62 public TestError(Test tester, Severity severity, String message, String description, int code, List<? extends OsmPrimitive> primitives) 63 { 64 this(tester, severity, message, description, code, primitives, primitives); 65 } 66 public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives) 67 { 68 this(tester, severity, message, null, code, primitives, primitives); 69 } 70 public TestError(Test tester, Severity severity, String message, int code, OsmPrimitive primitive) 71 { 72 this(tester, severity, message, null, code, Collections.singletonList(primitive), Collections.singletonList(primitive)); 73 } 74 public TestError(Test tester, Severity severity, String message, String description, int code, OsmPrimitive primitive) 75 { 76 this(tester, severity, message, description, code, Collections.singletonList(primitive)); 86 77 } 87 78 … … 108 99 * @param message The error message 109 100 */ 110 public void setMessage(String message) 101 public void setMessage(String message) 111 102 { 112 103 this.message = message; 113 104 } 114 115 /** 116 * Gets the list of primitives affected by this error 105 106 /** 107 * Gets the list of primitives affected by this error 117 108 * @return the list of primitives affected by this error 118 109 */ 119 public List<? extends OsmPrimitive> getPrimitives() 110 public List<? extends OsmPrimitive> getPrimitives() 120 111 { 121 112 return primitives; … … 123 114 124 115 /** 125 * Sets the list of primitives affected by this error 116 * Sets the list of primitives affected by this error 126 117 * @param primitives the list of primitives affected by this error 127 118 */ 128 119 129 public void setPrimitives(List<OsmPrimitive> primitives) 120 public void setPrimitives(List<OsmPrimitive> primitives) 130 121 { 131 122 this.primitives = primitives; … … 136 127 * @return the severity of this error 137 128 */ 138 public Severity getSeverity() 129 public Severity getSeverity() 139 130 { 140 131 return severity; … … 145 136 * @param severity the severity of this error 146 137 */ 147 public void setSeverity(Severity severity) 138 public void setSeverity(Severity severity) 148 139 { 149 140 this.severity = severity; … … 156 147 { 157 148 Collection<String> strings = new TreeSet<String>(); 158 String ignorestring = message;149 String ignorestring = Integer.toString(code); 159 150 for (OsmPrimitive o : primitives) 160 151 { … … 195 186 196 187 /** 197 * Gets the internal code 198 * @return the internal code 199 */ 200 public int getInternalCode() 201 { 202 return internalCode; 203 } 204 205 /** 206 * Sets the internal code 207 * @param internalCode The internal code 208 */ 209 public void setInternalCode(int internalCode) 210 { 211 this.internalCode = internalCode; 212 } 213 188 * Gets the code 189 * @return the code 190 */ 191 public int getCode() 192 { 193 return code; 194 } 195 214 196 /** 215 197 * Returns true if the error can be fixed automatically … … 255 237 } 256 238 257 258 259 260 261 262 263 264 265 266 267 268 269 * Constructor 270 * @param g The graphics 271 272 273 274 275 276 277 239 /** 240 * Visitor that highlights the primitives affected by this error 241 * @author frsantos 242 */ 243 class PaintVisitor implements Visitor 244 { 245 /** The graphics */ 246 private final Graphics g; 247 /** The MapView */ 248 private final MapView mv; 249 250 /** 251 * Constructor 252 * @param g The graphics 253 * @param mv The Mapview 254 */ 255 public PaintVisitor(Graphics g, MapView mv) 256 { 257 this.g = g; 258 this.mv = mv; 259 } 278 260 279 261 public void visit(OsmPrimitive p) { 280 281 282 } 283 } 284 285 286 * Draws a circle around the node 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 * 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 * Draw a small rectangle. 338 339 * 340 341 342 public void visit(Node n) 343 344 345 346 347 348 349 262 if (!p.deleted && !p.incomplete) { 263 p.visit(this); 264 } 265 } 266 267 /** 268 * Draws a circle around the node 269 * @param n The node 270 * @param color The circle color 271 */ 272 public void drawNode(Node n, Color color) 273 { 274 Point p = mv.getPoint(n.eastNorth); 275 g.setColor(color); 276 if( selected ) 277 { 278 g.fillOval(p.x-5, p.y-5, 10, 10); 279 } 280 else 281 g.drawOval(p.x-5, p.y-5, 10, 10); 282 } 283 284 /** 285 * Draws a line around the segment 286 * 287 * @param s The segment 288 * @param color The color 289 */ 290 public void drawSegment(Node n1, Node n2, Color color) 291 { 292 Point p1 = mv.getPoint(n1.eastNorth); 293 Point p2 = mv.getPoint(n2.eastNorth); 294 g.setColor(color); 295 296 double t = Math.atan2(p2.x-p1.x, p2.y-p1.y); 297 double cosT = Math.cos(t); 298 double sinT = Math.sin(t); 299 int deg = (int)Math.toDegrees(t); 300 if( selected ) 301 { 302 int[] x = new int[] {(int)(p1.x + 5*cosT), (int)(p2.x + 5*cosT), (int)(p2.x - 5*cosT), (int)(p1.x - 5*cosT)}; 303 int[] y = new int[] {(int)(p1.y - 5*sinT), (int)(p2.y - 5*sinT), (int)(p2.y + 5*sinT), (int)(p1.y + 5*sinT)}; 304 g.fillPolygon(x, y, 4); 305 g.fillArc(p1.x-5, p1.y-5, 10, 10, deg, 180 ); 306 g.fillArc(p2.x-5, p2.y-5, 10, 10, deg, -180); 307 } 308 else 309 { 310 g.drawLine((int)(p1.x + 5*cosT), (int)(p1.y - 5*sinT), (int)(p2.x + 5*cosT), (int)(p2.y - 5*sinT)); 311 g.drawLine((int)(p1.x - 5*cosT), (int)(p1.y + 5*sinT), (int)(p2.x - 5*cosT), (int)(p2.y + 5*sinT)); 312 g.drawArc(p1.x-5, p1.y-5, 10, 10, deg, 180 ); 313 g.drawArc(p2.x-5, p2.y-5, 10, 10, deg, -180); 314 } 315 } 316 317 318 /** 319 * Draw a small rectangle. 320 * White if selected (as always) or red otherwise. 321 * 322 * @param n The node to draw. 323 */ 324 public void visit(Node n) 325 { 326 if( isNodeVisible(n) ) 327 drawNode(n, severity.getColor()); 328 } 329 330 public void visit(Way w) 331 { 350 332 Node lastN = null; 351 333 for (Node n : w.nodes) { … … 354 336 continue; 355 337 } 356 357 358 359 338 if (isSegmentVisible(lastN, n)) 339 { 340 drawSegment(lastN, n, severity.getColor()); 341 } 360 342 lastN = n; 361 343 } 362 344 } 363 345 364 346 public void visit(WaySegment ws) { … … 375 357 /* No idea how to draw a relation. */ 376 358 } 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 *segments.392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 359 360 /** 361 * Checks if the given node is in the visible area. 362 * @param n The node to check for visibility 363 * @return true if the node is visible 364 */ 365 protected boolean isNodeVisible(Node n) { 366 Point p = mv.getPoint(n.eastNorth); 367 return !((p.x < 0) || (p.y < 0) || (p.x > mv.getWidth()) || (p.y > mv.getHeight())); 368 } 369 370 /** 371 * Checks if the given segment is in the visible area. 372 * NOTE: This will return true for a small number of non-visible 373 * segments. 374 * @param ls The segment to check 375 * @return true if the segment is visible 376 */ 377 protected boolean isSegmentVisible(Node n1, Node n2) { 378 Point p1 = mv.getPoint(n1.eastNorth); 379 Point p2 = mv.getPoint(n2.eastNorth); 380 if ((p1.x < 0) && (p2.x < 0)) return false; 381 if ((p1.y < 0) && (p2.y < 0)) return false; 382 if ((p1.x > mv.getWidth()) && (p2.x > mv.getWidth())) return false; 383 if ((p1.y > mv.getHeight()) && (p2.y > mv.getHeight())) return false; 384 return true; 385 } 386 } 387 388 /** 389 * Sets the selection flag of this error 390 * @param selected if this error is selected 391 */ 392 public void setSelected(boolean selected) 393 { 394 this.selected = selected; 395 } 414 396 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java
r5583 r9684 16 16 /** 17 17 * Check coastlines for errors 18 * 18 * 19 19 * @author frsantos 20 20 */ 21 public class Coastlines extends Test 21 public class Coastlines extends Test 22 22 { 23 /** All ways, grouped by cells */ 24 Map<Point2D,List<Way>> _cellWays; 25 /** The already detected errors */ 26 Bag<Way, Way> _errorWays; 23 protected static int UNORDERED_COASTLINES = 901; 24 25 /** All ways, grouped by cells */ 26 Map<Point2D,List<Way>> _cellWays; 27 /** The already detected errors */ 28 Bag<Way, Way> _errorWays; 27 29 28 30 /** 29 31 * Constructor 30 32 */ 31 public Coastlines() 33 public Coastlines() 32 34 { 33 35 super(tr("Coastlines."), … … 35 37 } 36 38 37 38 public void startTest() 39 40 41 42 39 @Override 40 public void startTest() 41 { 42 _cellWays = new HashMap<Point2D,List<Way>>(1000); 43 _errorWays = new Bag<Way, Way>(); 44 } 43 45 44 @Override45 public void endTest()46 {47 _cellWays = null;48 _errorWays = null;49 }50 51 46 @Override 52 public void visit(Way w)47 public void endTest() 53 48 { 54 if( w.deleted || w.incomplete ) 55 return; 56 57 String natural = w.get("natural"); 58 if( natural == null || !natural.equals("coastline") ) 59 return; 60 61 List<List<Way>> cellWays = Util.getWaysInCell(w, _cellWays); 62 for( List<Way> ways : cellWays) 63 { 64 for( Way w2 : ways) 65 { 66 if( _errorWays.contains(w, w2) || _errorWays.contains(w2, w) ) 67 continue; 68 69 String natural2 = w.get("natural"); 70 if( natural2 == null || !natural2.equals("coastline") ) 71 continue; 72 73 if( w.nodes.get(0).equals(w2.nodes.get(0)) || w.nodes.get(w.nodes.size() - 1).equals(w2.nodes.get(w2.nodes.size() - 1))) 74 { 75 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 76 primitives.add(w); 77 primitives.add(w2); 78 errors.add( new TestError(this, Severity.ERROR, tr("Unordered coastline"), primitives) ); 79 _errorWays.add(w, w2); 80 } 81 } 82 ways.add(w); 83 } 49 _cellWays = null; 50 _errorWays = null; 51 } 52 53 @Override 54 public void visit(Way w) 55 { 56 if( w.deleted || w.incomplete ) 57 return; 58 59 String natural = w.get("natural"); 60 if( natural == null || !natural.equals("coastline") ) 61 return; 62 63 List<List<Way>> cellWays = Util.getWaysInCell(w, _cellWays); 64 for( List<Way> ways : cellWays) 65 { 66 for( Way w2 : ways) 67 { 68 if( _errorWays.contains(w, w2) || _errorWays.contains(w2, w) ) 69 continue; 70 71 String natural2 = w.get("natural"); 72 if( natural2 == null || !natural2.equals("coastline") ) 73 continue; 74 75 if( w.nodes.get(0).equals(w2.nodes.get(0)) || w.nodes.get(w.nodes.size() - 1).equals(w2.nodes.get(w2.nodes.size() - 1))) 76 { 77 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 78 primitives.add(w); 79 primitives.add(w2); 80 errors.add( new TestError(this, Severity.ERROR, tr("Unordered coastline"), UNORDERED_COASTLINES, primitives) ); 81 _errorWays.add(w, w2); 82 } 83 } 84 ways.add(w); 85 } 84 86 } 85 87 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingWays.java
r8692 r9684 14 14 /** 15 15 * Tests if there are segments that crosses in the same layer 16 * 16 * 17 17 * @author frsantos 18 18 */ 19 public class CrossingWays extends Test 19 public class CrossingWays extends Test 20 20 { 21 protected static int CROSSING_WAYS = 601; 22 21 23 /** All way segments, grouped by cells */ 22 24 Map<Point2D,List<ExtendedSegment>> cellSegments; … … 26 28 Map<List<Way>, List<WaySegment>> ways_seen; 27 29 28 30 29 31 /** 30 32 * Constructor 31 33 */ 32 public CrossingWays() 34 public CrossingWays() 33 35 { 34 36 super(tr("Crossing ways."), … … 38 40 39 41 @Override 40 public void startTest() 42 public void startTest() 41 43 { 42 44 cellSegments = new HashMap<Point2D,List<ExtendedSegment>>(1000); … … 46 48 47 49 @Override 48 public void endTest() 50 public void endTest() 49 51 { 50 52 cellSegments = null; … … 54 56 55 57 @Override 56 public void visit(Way w) 58 public void visit(Way w) 57 59 { 58 60 if( w.deleted || w.incomplete ) 59 61 return; 60 62 61 String coastline1 = w.get("natural"); 63 String coastline1 = w.get("natural"); 62 64 boolean isCoastline1 = coastline1 != null && (coastline1.equals("water") || coastline1.equals("coastline")); 63 String railway1 = w.get("railway"); 65 String railway1 = w.get("railway"); 64 66 boolean isSubway1 = railway1 != null && railway1.equals("subway"); 65 if( w.get("highway") == null && w.get("waterway") == null && (railway1 == null || isSubway1) && !isCoastline1) 67 if( w.get("highway") == null && w.get("waterway") == null && (railway1 == null || isSubway1) && !isCoastline1) 66 68 return; 67 69 68 70 String layer1 = w.get("layer"); 69 71 70 72 int nodesSize = w.nodes.size(); … … 102 104 highlight.add(es2.ws); 103 105 104 errors.add(new TestError(this, Severity.WARNING, tr("Crossing ways"), 105 prims, 106 highlight)); 106 errors.add(new TestError(this, Severity.WARNING, 107 tr("Crossing ways"), CROSSING_WAYS, prims, highlight)); 107 108 ways_seen.put(prims, highlight); 108 109 } … … 131 132 for( Point2D cell : Util.getSegmentCells(n1, n2, 10000) ) 132 133 { 133 134 135 136 137 138 139 140 141 134 List<ExtendedSegment> segments = cellSegments.get( cell ); 135 if( segments == null ) 136 { 137 segments = new ArrayList<ExtendedSegment>(); 138 cellSegments.put(cell, segments); 139 } 140 cells.add(segments); 141 } 142 142 143 return cells; 143 144 } 144 145 146 147 148 149 150 145 146 /** 147 * A way segment with some additional information 148 * @author frsantos 149 */ 150 private class ExtendedSegment 151 { 151 152 public Node n1, n2; 152 153 153 154 public WaySegment ws; 154 155 156 157 158 155 156 /** The layer */ 157 public String layer; 158 159 /** The railway type */ 159 160 public String railway; 160 161 161 162 /** The coastline type */ 162 163 public String coastline; 163 164 165 166 167 168 169 170 171 172 173 164 165 /** 166 * Constructor 167 * @param ws The way segment 168 * @param layer The layer of the way this segment is in 169 * @param railway The railway type of the way this segment is in 170 * @param coastline The coastlyne typo of the way the segment is in 171 */ 172 public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline) 173 { 174 this.ws = ws; 174 175 this.n1 = ws.way.nodes.get(ws.lowerIndex); 175 176 this.n2 = ws.way.nodes.get(ws.lowerIndex + 1); 176 177 178 179 180 181 182 183 184 185 186 187 188 if( n1.equals(s2.n1) || n2.equals(s2.n2) || 189 190 191 192 193 194 177 this.layer = layer; 178 this.railway = railway; 179 this.coastline = coastline; 180 } 181 182 /** 183 * Checks whether this segment crosses other segment 184 * @param s2 The other segment 185 * @return true if both segements crosses 186 */ 187 public boolean intersects(ExtendedSegment s2) 188 { 189 if( n1.equals(s2.n1) || n2.equals(s2.n2) || 190 n1.equals(s2.n2) || n2.equals(s2.n1) ) 191 { 192 return false; 193 } 194 195 return Line2D.linesIntersect( 195 196 n1.eastNorth.east(), n1.eastNorth.north(), 196 197 n2.eastNorth.east(), n2.eastNorth.north(), 197 198 s2.n1.eastNorth.east(), s2.n1.eastNorth.north(), 198 199 s2.n2.eastNorth.east(), s2.n2.eastNorth.north()); 199 200 200 } 201 } 201 202 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java
r8769 r9684 17 17 /** 18 18 * Tests if there are duplicate nodes 19 * 19 * 20 20 * @author frsantos 21 21 */ 22 public class DuplicateNode extends Test 22 public class DuplicateNode extends Test 23 23 { 24 protected static int DUPLICATE_NODE = 1; 25 24 26 /** Bag of all nodes */ 25 27 Bag<LatLon, OsmPrimitive> nodes; 26 28 27 29 /** 28 30 * Constructor 29 31 */ 30 public DuplicateNode() 32 public DuplicateNode() 31 33 { 32 34 super(tr("Duplicated nodes."), … … 36 38 37 39 @Override 38 public void startTest() 40 public void startTest() 39 41 { 40 42 nodes = new Bag<LatLon, OsmPrimitive>(1000); … … 42 44 43 45 @Override 44 public void endTest() 46 public void endTest() 45 47 { 46 48 for(List<OsmPrimitive> duplicated : nodes.values() ) … … 48 50 if( duplicated.size() > 1) 49 51 { 50 TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), duplicated);52 TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), DUPLICATE_NODE, duplicated); 51 53 errors.add( testError ); 52 54 } … … 56 58 57 59 @Override 58 public void visit(Node n) 60 public void visit(Node n) 59 61 { 60 62 if(!n.deleted && !n.incomplete) 61 63 nodes.add(n.coor, n); 62 64 } 63 64 65 66 67 65 66 /** 67 * Merge the nodes into one. 68 * Copied from UtilsPlugin.MergePointsAction 69 */ 68 70 @Override 69 71 public Command fixError(TestError testError) 70 72 { 71 Collection<? extends OsmPrimitive> sel = testError.getPrimitives(); 72 Collection<OsmPrimitive> nodes = new ArrayList<OsmPrimitive>(); 73 74 Node target = null; 75 for (OsmPrimitive osm : sel) 76 nodes.add(osm); 77 78 if( nodes.size() < 2 ) 79 return null; 80 81 for ( OsmPrimitive o : nodes ) 82 { 83 Node n = (Node)o; 84 if( target == null || target.id == 0 ) 85 { 86 target = n; 87 continue; 88 } 89 if( n.id == 0 ) 90 continue; 91 if( n.id < target.id ) 92 target = n; 93 } 94 if( target == null ) 95 return null; 96 97 // target is what we're merging into 98 // nodes is the list of nodes to be removed 99 nodes.remove(target); 100 101 // Merge all properties 102 Node newtarget = new Node(target); 103 for (final OsmPrimitive o : nodes) 104 { 105 Node n = (Node)o; 106 for ( String key : n.keySet() ) 107 { 108 if( newtarget.keySet().contains(key) && !newtarget.get(key).equals(n.get(key)) ) 109 { 110 JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: " + key + " ["+newtarget.get(key)+", "+n.get(key)+"]")); 111 return null; 112 } 113 newtarget.put( key, n.get(key) ); 114 } 115 } 73 Collection<? extends OsmPrimitive> sel = testError.getPrimitives(); 74 Collection<OsmPrimitive> nodes = new ArrayList<OsmPrimitive>(); 116 75 117 Collection<Command> cmds = new LinkedList<Command>(); 76 Node target = null; 77 for (OsmPrimitive osm : sel) 78 nodes.add(osm); 79 80 if( nodes.size() < 2 ) 81 return null; 82 83 for ( OsmPrimitive o : nodes ) 84 { 85 Node n = (Node)o; 86 if( target == null || target.id == 0 ) 87 { 88 target = n; 89 continue; 90 } 91 if( n.id == 0 ) 92 continue; 93 if( n.id < target.id ) 94 target = n; 95 } 96 if( target == null ) 97 return null; 98 99 // target is what we're merging into 100 // nodes is the list of nodes to be removed 101 nodes.remove(target); 102 103 // Merge all properties 104 Node newtarget = new Node(target); 105 for (final OsmPrimitive o : nodes) 106 { 107 Node n = (Node)o; 108 for ( String key : n.keySet() ) 109 { 110 if( newtarget.keySet().contains(key) && !newtarget.get(key).equals(n.get(key)) ) 111 { 112 JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: {0} [{1}, {2}]", 113 key, newtarget.get(key), n.get(key))); 114 return null; 115 } 116 newtarget.put( key, n.get(key) ); 117 } 118 } 119 120 Collection<Command> cmds = new LinkedList<Command>(); 118 121 119 122 // Now search the ways for occurences of the nodes we are about to … … 135 138 } 136 139 137 138 139 140 cmds.add(new DeleteCommand(nodes)); 141 cmds.add(new ChangeCommand(target, newtarget)); 142 return new SequenceCommand(tr("Merge Nodes"), cmds); 140 143 } 141 144 142 145 @Override 143 146 public boolean isFixable(TestError testError) 144 147 { 145 148 return (testError.getTester() instanceof DuplicateNode); 146 } 149 } 147 150 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicatedWayNodes.java
r6302 r9684 1 1 package org.openstreetmap.josm.plugins.validator.tests; 2 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 3 5 import org.openstreetmap.josm.plugins.validator.Test; 4 6 import org.openstreetmap.josm.plugins.validator.TestError; … … 14 16 15 17 public class DuplicatedWayNodes extends Test { 18 protected static int DUPLICATE_WAY_NODE = 501; 19 16 20 public DuplicatedWayNodes() { 17 21 super(tr("Duplicated way nodes."), … … 29 33 } 30 34 if (lastN == n) { 31 errors.add(new TestError(this, Severity.ERROR, tr("Duplicated way nodes"), 35 errors.add(new TestError(this, Severity.ERROR, tr("Duplicated way nodes"), DUPLICATE_WAY_NODE, 32 36 Arrays.asList(w), Arrays.asList(n))); 33 37 break; -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/NodesWithSameName.java
r6557 r9684 14 14 15 15 public class NodesWithSameName extends Test { 16 protected static int SAME_NAME = 801; 17 16 18 private Map<String, List<Node>> namesToNodes; 17 19 18 20 public NodesWithSameName() { 19 21 super(tr("Nodes with same name"), 20 tr("Find nodes that have the same name " + 21 "(might be duplicates due to e.g. the OpenGeoDB import)")); 22 tr("Find nodes that have the same name (might be duplicates)")); 22 23 } 23 24 … … 43 44 if (nodes.size() > 1) { 44 45 errors.add(new TestError(this, Severity.WARNING, 45 tr("Nodes with same name"), nodes));46 tr("Nodes with same name"), SAME_NAME, nodes)); 46 47 } 47 48 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/OverlappingWays.java
r9598 r9684 22 22 * @author frsantos 23 23 */ 24 public class OverlappingWays extends Test 24 public class OverlappingWays extends Test 25 25 { 26 26 /** Bag of all way segments */ 27 27 Bag<Pair<Node,Node>, WaySegment> nodePairs; 28 29 /** 30 * Constructor 31 */ 32 public OverlappingWays() 28 29 protected static int OVERLAPPING_HIGHWAY = 101; 30 protected static int OVERLAPPING_RAILWAY = 102; 31 protected static int OVERLAPPING_WAY = 103; 32 protected static int OVERLAPPING_HIGHWAY_AREA = 111; 33 protected static int OVERLAPPING_RAILWAY_AREA = 112; 34 protected static int OVERLAPPING_WAY_AREA = 113; 35 protected static int OVERLAPPING_AREA = 120; 36 37 /** Constructor */ 38 public OverlappingWays() 33 39 { 34 40 super(tr("Overlapping ways."), … … 46 52 47 53 @Override 48 public void endTest() 54 public void endTest() 49 55 { 50 Map<List<Way>, List<WaySegment>> ways_seen = 51 new HashMap<List<Way>, List<WaySegment>>(500); 56 Map<List<Way>, List<WaySegment>> ways_seen = new HashMap<List<Way>, List<WaySegment>>(500); 52 57 53 58 for (List<WaySegment> duplicated : nodePairs.values()) … … 84 89 /* These ways not seen before 85 90 * If two or more of the overlapping ways are 86 87 91 * highways or railways mark a seperate error 92 */ 88 93 if ((highlight = ways_seen.get(current_ways)) == null) 89 94 { 90 95 String errortype; 96 int type; 91 97 92 98 if(area > 0) 93 99 { 94 100 if (ways == 0 || duplicated.size() == area) 101 { 95 102 errortype = tr("Overlapping areas"); 103 type = OVERLAPPING_AREA; 104 } 96 105 else if (highway == ways) 106 { 97 107 errortype = tr("Overlapping highways (with area)"); 108 type = OVERLAPPING_HIGHWAY_AREA; 109 } 98 110 else if (railway == ways) 111 { 99 112 errortype = tr("Overlapping railways (with area)"); 113 type = OVERLAPPING_RAILWAY_AREA; 114 } 100 115 else 116 { 101 117 errortype = tr("Overlapping ways (with area)"); 118 type = OVERLAPPING_WAY_AREA; 119 } 102 120 } 103 121 else if (highway == ways) 122 { 104 123 errortype = tr("Overlapping highways"); 124 type = OVERLAPPING_HIGHWAY; 125 } 105 126 else if (railway == ways) 127 { 106 128 errortype = tr("Overlapping railways"); 129 type = OVERLAPPING_RAILWAY; 130 } 107 131 else 132 { 108 133 errortype = tr("Overlapping ways"); 134 type = OVERLAPPING_WAY; 135 } 109 136 110 errors.add(new TestError(this, Severity.OTHER, tr(errortype), prims, duplicated));137 errors.add(new TestError(this, Severity.OTHER, tr(errortype), type, prims, duplicated)); 111 138 ways_seen.put(current_ways, duplicated); 112 139 } … … 122 149 123 150 @Override 124 public void visit(Way w) 151 public void visit(Way w) 125 152 { 126 153 Node lastN = null; -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SelfIntersectingWay.java
r6302 r9684 16 16 */ 17 17 public class SelfIntersectingWay extends Test { 18 protected static int SELF_INTERSECT = 401; 19 18 20 public SelfIntersectingWay() { 19 21 super(tr("Self-intersecting ways"), … … 29 31 if (nodes.contains(n)) { 30 32 errors.add(new TestError(this, 31 Severity.WARNING, tr("Self-intersecting ways"), 33 Severity.WARNING, tr("Self-intersecting ways"), SELF_INTERSECT, 32 34 Arrays.asList(w), Arrays.asList(n))); 33 35 break; … … 36 38 } 37 39 } 38 } 40 } 39 41 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SimilarNamedWays.java
r5583 r9684 13 13 import org.openstreetmap.josm.plugins.validator.util.Bag; 14 14 import org.openstreetmap.josm.plugins.validator.util.Util; 15 15 16 /** 16 17 * Checks for similar named ways, symptom of a possible typo. It uses the 17 18 * Levenshtein distance to check for similarity 18 * 19 * 19 20 * @author frsantos 20 21 */ 21 public class SimilarNamedWays extends Test 22 public class SimilarNamedWays extends Test 22 23 { 23 /** All ways, grouped by cells */ 24 Map<Point2D,List<Way>> cellWays; 25 /** The already detected errors */ 26 Bag<Way, Way> errorWays; 27 28 /** 24 protected static int SIMILAR_NAMED = 701; 25 26 /** All ways, grouped by cells */ 27 Map<Point2D,List<Way>> cellWays; 28 /** The already detected errors */ 29 Bag<Way, Way> errorWays; 30 31 /** 29 32 * Constructor 30 33 */ 31 public SimilarNamedWays() 34 public SimilarNamedWays() 32 35 { 33 36 super(tr("Similar named ways."), … … 35 38 } 36 39 37 38 public void startTest() 39 40 41 42 40 @Override 41 public void startTest() 42 { 43 cellWays = new HashMap<Point2D,List<Way>>(1000); 44 errorWays = new Bag<Way, Way>(); 45 } 43 46 44 @Override45 public void endTest()46 {47 cellWays = null;48 errorWays = null;49 }50 51 47 @Override 52 public void visit(Way w)48 public void endTest() 53 49 { 54 if( w.deleted || w.incomplete ) 55 return; 56 57 String name = w.get("name"); 58 if( name == null || name.length() < 6 ) 59 return; 60 61 List<List<Way>> theCellWays = Util.getWaysInCell(w, cellWays); 62 for( List<Way> ways : theCellWays) 63 { 64 for( Way w2 : ways) 65 { 66 if( errorWays.contains(w, w2) || errorWays.contains(w2, w) ) 67 continue; 68 69 String name2 = w2.get("name"); 70 if( name2 == null || name2.length() < 6 ) 71 continue; 72 73 int levenshteinDistance = getLevenshteinDistance(name, name2); 74 if( 0 < levenshteinDistance && levenshteinDistance <= 2 ) 75 { 76 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 77 primitives.add(w); 78 primitives.add(w2); 79 errors.add( new TestError(this, Severity.WARNING, tr("Similar named ways"), primitives) ); 80 errorWays.add(w, w2); 81 } 82 } 83 ways.add(w); 84 } 50 cellWays = null; 51 errorWays = null; 85 52 } 86 87 /**88 * Compute Levenshtein distance89 *90 * @param s First word91 * @param t Second word92 * @return The distance between words93 */94 public int getLevenshteinDistance(String s, String t)95 {96 int d[][]; // matrix97 int n; // length of s98 int m; // length of t99 int i; // iterates through s100 int j; // iterates through t101 char s_i; // ith character of s102 char t_j; // jth character of t103 int cost; // cost104 53 105 // Step 1 54 @Override 55 public void visit(Way w) 56 { 57 if( w.deleted || w.incomplete ) 58 return; 106 59 107 n = s.length(); 108 m = t.length(); 109 if (n == 0) return m; 110 if (m == 0) return n; 111 d = new int[n + 1][m + 1]; 60 String name = w.get("name"); 61 if( name == null || name.length() < 6 ) 62 return; 112 63 113 // Step 2 114 for (i = 0; i <= n; i++) d[i][0] = i; 115 for (j = 0; j <= m; j++) d[0][j] = j; 64 List<List<Way>> theCellWays = Util.getWaysInCell(w, cellWays); 65 for( List<Way> ways : theCellWays) 66 { 67 for( Way w2 : ways) 68 { 69 if( errorWays.contains(w, w2) || errorWays.contains(w2, w) ) 70 continue; 116 71 117 // Step 3 118 for (i = 1; i <= n; i++) 119 { 120 s_i = s.charAt(i - 1); 72 String name2 = w2.get("name"); 73 if( name2 == null || name2.length() < 6 ) 74 continue; 121 75 122 // Step 4 123 for (j = 1; j <= m; j++) 124 { 125 t_j = t.charAt(j - 1); 76 int levenshteinDistance = getLevenshteinDistance(name, name2); 77 if( 0 < levenshteinDistance && levenshteinDistance <= 2 ) 78 { 79 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 80 primitives.add(w); 81 primitives.add(w2); 82 errors.add( new TestError(this, Severity.WARNING, tr("Similar named ways"), SIMILAR_NAMED, primitives) ); 83 errorWays.add(w, w2); 84 } 85 } 86 ways.add(w); 87 } 88 } 126 89 127 // Step 5 128 if (s_i == t_j) 129 { 130 cost = 0; 131 } 132 else 133 { 134 cost = 1; 135 } 90 /** 91 * Compute Levenshtein distance 92 * 93 * @param s First word 94 * @param t Second word 95 * @return The distance between words 96 */ 97 public int getLevenshteinDistance(String s, String t) 98 { 99 int d[][]; // matrix 100 int n; // length of s 101 int m; // length of t 102 int i; // iterates through s 103 int j; // iterates through t 104 char s_i; // ith character of s 105 char t_j; // jth character of t 106 int cost; // cost 136 107 137 // Step 6 138 d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); 139 } 140 } 108 // Step 1 141 109 142 // Step 7 143 return d[n][m]; 110 n = s.length(); 111 m = t.length(); 112 if (n == 0) return m; 113 if (m == 0) return n; 114 d = new int[n + 1][m + 1]; 144 115 145 } 116 // Step 2 117 for (i = 0; i <= n; i++) d[i][0] = i; 118 for (j = 0; j <= m; j++) d[0][j] = j; 146 119 147 /** 148 * Get minimum of three values 149 * @param a First value 150 * @param b Second value 151 * @param c Third value 152 * @return The minimum of the tre values 153 */ 154 private static int Minimum(int a, int b, int c) 155 { 156 int mi = a; 157 if (b < mi) 158 { 159 mi = b; 160 } 161 if (c < mi) 162 { 163 mi = c; 164 } 165 return mi; 166 } 120 // Step 3 121 for (i = 1; i <= n; i++) 122 { 123 s_i = s.charAt(i - 1); 124 125 // Step 4 126 for (j = 1; j <= m; j++) 127 { 128 t_j = t.charAt(j - 1); 129 130 // Step 5 131 if (s_i == t_j) 132 { 133 cost = 0; 134 } 135 else 136 { 137 cost = 1; 138 } 139 140 // Step 6 141 d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); 142 } 143 } 144 145 // Step 7 146 return d[n][m]; 147 } 148 149 /** 150 * Get minimum of three values 151 * @param a First value 152 * @param b Second value 153 * @param c Third value 154 * @return The minimum of the tre values 155 */ 156 private static int Minimum(int a, int b, int c) 157 { 158 int mi = a; 159 if (b < mi) 160 { 161 mi = b; 162 } 163 if (c < mi) 164 { 165 mi = c; 166 } 167 return mi; 168 } 167 169 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/TagChecker.java
r9598 r9684 112 112 protected JButton deleteSrcButton; 113 113 114 protected static int EMPTY_VALUES = 0; 115 protected static int INVALID_KEY = 1; 116 protected static int INVALID_VALUE = 2; 117 protected static int FIXME = 3; 118 protected static int INVALID_SPACE = 3; 119 protected static int TAG_CHECK = 4; 114 protected static int EMPTY_VALUES = 1200; 115 protected static int INVALID_KEY = 1201; 116 protected static int INVALID_VALUE = 1202; 117 protected static int FIXME = 1203; 118 protected static int INVALID_SPACE = 1204; 119 protected static int INVALID_KEY_SPACE = 1205; 120 protected static int TAG_CHECK = 1206; 120 121 121 122 /** List of sources for spellcheck data */ … … 165 166 sources = SPELL_FILE + ";" + sources; 166 167 } 167 168 168 169 StringTokenizer st = new StringTokenizer(sources, ";"); 169 170 StringBuilder errorSources = new StringBuilder(); … … 224 225 throw new IOException( tr("Could not download data file(s):\n{0}", errorSources) ); 225 226 } 226 227 227 228 /** 228 229 * Reads the presets data. … … 245 246 readPresetFromPreferences(); 246 247 } 247 248 248 249 249 250 @Override 250 251 public void visit(Node n) … … 275 276 if(d.match(p)) 276 277 { 277 errors.add( new TestError(this, Severity.WARNING, tr("Illegal tag/value combinations"), p, TAG_CHECK) ); 278 errors.add( new TestError(this, Severity.WARNING, tr("Illegal tag/value combinations"), 279 tr(d.description()), TAG_CHECK, p) ); 278 280 withErrors.add(p, "TC"); 279 281 break; … … 289 291 if( checkValues && (value==null || value.trim().length() == 0) && !withErrors.contains(p, "EV")) 290 292 { 291 errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"), tr("Key ''{0}'' invalid.", key), p, EMPTY_VALUES) ); 293 errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"), 294 tr("Key ''{0}'' invalid.", key), EMPTY_VALUES, p) ); 292 295 withErrors.add(p, "EV"); 293 296 } 294 297 if( checkKeys && spellCheckKeyData.containsKey(key) && !withErrors.contains(p, "IPK")) 295 298 { 296 errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key"), tr("Key ''{0}'' invalid.", key), p, INVALID_KEY) ); 299 errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key"), 300 tr("Key ''{0}'' invalid.", key), INVALID_KEY, p) ); 297 301 withErrors.add(p, "IPK"); 298 302 } 299 303 if( checkKeys && key.indexOf(" ") >= 0 && !withErrors.contains(p, "IPK")) 300 304 { 301 errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key"), tr("Key ''{0}'' invalid.", key), p, INVALID_KEY) ); 305 errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key"), 306 tr("Key ''{0}'' invalid.", key), INVALID_KEY_SPACE, p) ); 302 307 withErrors.add(p, "IPK"); 303 308 } 304 309 if( checkValues && value != null && (value.startsWith(" ") || value.endsWith(" ")) && !withErrors.contains(p, "SPACE")) 305 310 { 306 errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"), tr("Key ''{0}'' invalid.", key), p, INVALID_SPACE) ); 311 errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"), 312 tr("Key ''{0}'' invalid.", key), INVALID_SPACE, p) ); 307 313 withErrors.add(p, "SPACE"); 308 314 } … … 312 318 if( values != null && !values.contains(prop.getValue()) && !withErrors.contains(p, "UPV")) 313 319 { 314 errors.add( new TestError(this, Severity.OTHER, tr("Unknown property values"), tr("Key ''{0}'' invalid.", key), p, INVALID_VALUE) ); 320 errors.add( new TestError(this, Severity.OTHER, tr("Unknown property values"), 321 tr("Key ''{0}'' invalid.", key), INVALID_VALUE, p) ); 315 322 withErrors.add(p, "UPV"); 316 323 } … … 321 328 && !withErrors.contains(p, "FIXME")) 322 329 { 323 errors.add( new TestError(this, Severity.OTHER, tr("FIXMES"), p, FIXME) );330 errors.add( new TestError(this, Severity.OTHER, tr("FIXMES"), FIXME, p) ); 324 331 withErrors.add(p, "FIXME"); 325 332 } … … 346 353 in = new BufferedReader(new InputStreamReader(inStream)); 347 354 } 348 355 349 356 XmlObjectParser parser = new XmlObjectParser(); 350 357 parser.mapOnStart("item", TaggingPreset.class); … … 355 362 parser.map("key", TaggingPreset.Key.class); 356 363 parser.start(in); 357 364 358 365 while(parser.hasNext()) 359 366 { … … 378 385 InputStream in = null; 379 386 String source = st.nextToken(); 380 try 387 try 381 388 { 382 389 if (source.startsWith("http") || source.startsWith("ftp") || source.startsWith("file")) … … 388 395 readPresets(in); 389 396 in.close(); 390 } 397 } 391 398 catch (IOException e) 392 399 { 393 400 // Error already reported by JOSM 394 } 401 } 395 402 catch (SAXException e) 396 403 { … … 426 433 super.visit(selection); 427 434 } 428 435 429 436 @Override 430 437 public void addGui(JPanel testPanel) … … 575 582 { 576 583 enabled = prefCheckKeys.isSelected() || prefCheckValues.isSelected() || prefCheckComplex.isSelected() || prefCheckFixmes.isSelected(); 577 testBeforeUpload = prefCheckKeysBeforeUpload.isSelected() || prefCheckValuesBeforeUpload.isSelected() || prefCheckFixmesBeforeUpload.isSelected() || prefCheckComplexBeforeUpload.isSelected(); 584 testBeforeUpload = prefCheckKeysBeforeUpload.isSelected() || prefCheckValuesBeforeUpload.isSelected() 585 || prefCheckFixmesBeforeUpload.isSelected() || prefCheckComplexBeforeUpload.isSelected(); 578 586 579 587 Main.pref.put(PREF_CHECK_VALUES, prefCheckValues.isSelected()); … … 620 628 else if(value.startsWith(" ") || value.endsWith(" ")) 621 629 commands.add( new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, value.trim()) ); 630 else if(key.startsWith(" ") || key.endsWith(" ")) 631 { 632 commands.add( new ChangePropertyKeyCommand(Collections.singleton(primitives.get(i)), key, key.trim()) ); 633 } 622 634 else 623 635 { … … 642 654 if( testError.getTester() instanceof TagChecker) 643 655 { 644 int code = testError.get InternalCode();645 return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE ;656 int code = testError.getCode(); 657 return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE || code == INVALID_KEY_SPACE; 646 658 } 647 659 … … 652 664 public String getData(String data) 653 665 { 654 System.out.println(data);655 666 return "not implemented yet"; 656 667 } … … 659 670 return false; 660 671 } 672 public String description() 673 { 674 return "not implemented yet"; 675 } 661 676 } 662 677 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UnclosedWays.java
r9598 r9684 18 18 * @author stoecker 19 19 */ 20 public class UnclosedWays extends Test 20 public class UnclosedWays extends Test { 21 21 /** The already detected errors */ 22 22 Bag<Way, Way> _errorWays; … … 42 42 _errorWays = null; 43 43 } 44 44 45 45 @Override 46 46 public void visit(Way w) … … 48 48 boolean force = false; /* force even if end-to-end distance is long */ 49 49 String type = null, test; 50 50 int mode = 0; 51 51 52 if( w.deleted || w.incomplete ) 52 53 return; 53 54 54 55 test = w.get("natural"); 55 56 if(test != null) … … 58 59 force = true; 59 60 type = tr("natural type {0}", tr(test)); 61 mode = 1101; 60 62 } 61 63 test = w.get("landuse"); … … 64 66 force = true; 65 67 type = tr("landuse type {0}", tr(test)); 68 mode = 1102; 66 69 } 67 70 test = w.get("amenities"); … … 70 73 force = true; 71 74 type = tr("amenities type {0}", tr(test)); 75 mode = 1103; 72 76 } 73 77 test = w.get("sport"); … … 76 80 force = true; 77 81 type = tr("sport type {0}", tr(test)); 82 mode = 1104; 78 83 } 79 84 test = w.get("tourism"); … … 82 87 force = true; 83 88 type = tr("tourism type {0}", tr(test)); 89 mode = 1105; 84 90 } 85 91 test = w.get("shop"); … … 88 94 force = true; 89 95 type = tr("shop type {0}", tr(test)); 96 mode = 1106; 90 97 } 91 98 test = w.get("leisure"); … … 94 101 force = true; 95 102 type = tr("leisure type {0}", tr(test)); 103 mode = 1107; 96 104 } 97 105 test = w.get("waterway"); … … 100 108 force = true; 101 109 type = tr("waterway type {0}", tr(test)); 110 mode = 1108; 102 111 } 103 /*test = w.get("junction");104 if(test != null && test.equals("roundabout"))105 {106 force = true;107 type = tr("junction type {0}", tr(test));108 }*/109 112 test = w.get("building"); 110 113 if (test != null && ("true".equalsIgnoreCase(test) || "yes".equalsIgnoreCase(test) || "1".equals(test))) … … 112 115 force = true; 113 116 type = tr("building"); 117 mode = 1120; 114 118 } 115 119 test = w.get("area"); … … 118 122 force = true; 119 123 type = tr("area"); 124 mode = 1130; 120 125 } 121 126 … … 129 134 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 130 135 primitives.add(w); 131 errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"), type, primitives));136 errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"), type, mode, primitives)); 132 137 _errorWays.add(w,w); 133 138 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedNode.java
r5609 r9684 13 13 import org.openstreetmap.josm.plugins.validator.Severity; 14 14 import org.openstreetmap.josm.plugins.validator.Test; 15 import org.openstreetmap.josm.plugins.validator.util.Util; 15 16 import org.openstreetmap.josm.plugins.validator.TestError; 17 16 18 /** 17 19 * Checks for untagged nodes that are in no way 18 * 20 * 19 21 * @author frsantos 20 22 */ 21 public class UntaggedNode extends Test 23 public class UntaggedNode extends Test 22 24 { 23 /** Tags allowed in a node */ 24 public static String[] allowedTags = new String[] { "created_by" }; 25 25 protected static int UNTAGGED_NODE = 201; 26 26 27 /** Bag of all nodes */ 27 28 Set<Node> emptyNodes; 28 29 29 30 /** 30 31 * Constructor 31 32 */ 32 public UntaggedNode() 33 public UntaggedNode() 33 34 { 34 35 super(tr("Untagged nodes."), … … 37 38 38 39 @Override 39 public void startTest() 40 public void startTest() 40 41 { 41 42 emptyNodes = new HashSet<Node>(100); 42 43 } 43 44 44 45 @Override 45 public void visit(Collection<OsmPrimitive> selection) 46 46 public void visit(Collection<OsmPrimitive> selection) 47 { 47 48 // If there is a partial selection, it may be false positives if a 48 49 // node is selected, but not the container way. So, in this … … 64 65 } 65 66 } 66 67 67 } 68 68 69 @Override 69 public void visit(Node n) 70 public void visit(Node n) 70 71 { 71 if (n.incomplete || n.deleted) return; 72 if(!n.incomplete && !n.deleted && Util.countDataTags(n) == 0) 73 emptyNodes.add(n); 74 } 72 75 73 int numTags = 0;74 Map<String, String> tags = n.keys;75 if( tags != null )76 {77 numTags = tags.size();78 for( String tag : allowedTags)79 if( tags.containsKey(tag) ) numTags--;80 }81 82 if( numTags == 0 )83 {84 emptyNodes.add(n);85 }86 }87 88 76 @Override 89 public void visit(Way w) 77 public void visit(Way w) 90 78 { 91 79 for (Node n : w.nodes) { … … 93 81 } 94 82 } 95 83 96 84 @Override 97 public void endTest() 85 public void endTest() 98 86 { 99 87 for(Node node : emptyNodes) 100 88 { 101 errors.add( new TestError(this, Severity.OTHER, tr("Untagged and unconnected nodes"), node) );89 errors.add( new TestError(this, Severity.OTHER, tr("Untagged and unconnected nodes"), UNTAGGED_NODE, node) ); 102 90 } 103 91 emptyNodes = null; 104 92 } 105 93 106 94 @Override 107 95 public Command fixError(TestError testError) … … 109 97 return new DeleteCommand(testError.getPrimitives()); 110 98 } 111 99 112 100 @Override 113 101 public boolean isFixable(TestError testError) 114 102 { 115 103 return (testError.getTester() instanceof UntaggedNode); 116 } 104 } 117 105 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedWay.java
r5609 r9684 13 13 import org.openstreetmap.josm.plugins.validator.Test; 14 14 import org.openstreetmap.josm.plugins.validator.TestError; 15 import org.openstreetmap.josm.plugins.validator.util.Util; 16 15 17 /** 16 18 * Checks for untagged ways 17 * 19 * 18 20 * @author frsantos 19 21 */ 20 public class UntaggedWay extends Test 22 public class UntaggedWay extends Test 21 23 { 22 24 /** Empty way error */ 23 protected static final int EMPTY_WAY = 0;25 protected static final int EMPTY_WAY = 301; 24 26 /** Untagged way error */ 25 protected static final int UNTAGGED_WAY = 1;27 protected static final int UNTAGGED_WAY = 302; 26 28 /** Unnamed way error */ 27 protected static final int UNNAMED_WAY = 2;29 protected static final int UNNAMED_WAY = 303; 28 30 /** One node way error */ 29 protected static final int ONE_NODE_WAY = 3 ;31 protected static final int ONE_NODE_WAY = 304; 30 32 31 /** Tags allowed in a way */ 32 public static final String[] ALLOWED_TAGS = new String[] { "created_by", "converted_by" }; 33 /** Ways that must have a name */ 34 public static final Set<String> NAMED_WAYS = new HashSet<String>(); 35 static 36 { 37 NAMED_WAYS.add( "motorway" ); 38 NAMED_WAYS.add( "trunk" ); 39 NAMED_WAYS.add( "primary" ); 40 NAMED_WAYS.add( "secondary" ); 41 NAMED_WAYS.add( "tertiary" ); 42 NAMED_WAYS.add( "residential" ); 43 NAMED_WAYS.add( "pedestrian" ); ; 44 } 33 45 34 /** Ways that must have a name */ 35 public static final Set<String> NAMED_WAYS = new HashSet<String>(); 36 static 37 { 38 NAMED_WAYS.add( "motorway" ); 39 NAMED_WAYS.add( "trunk" ); 40 NAMED_WAYS.add( "primary" ); 41 NAMED_WAYS.add( "secondary" ); 42 NAMED_WAYS.add( "tertiary" ); 43 NAMED_WAYS.add( "residential" ); 44 NAMED_WAYS.add( "pedestrian" ); ; 45 } 46 47 /** 46 /** 48 47 * Constructor 49 48 */ 50 public UntaggedWay() 49 public UntaggedWay() 51 50 { 52 51 super(tr("Untagged, empty, and one node ways."), … … 55 54 56 55 @Override 57 public void visit(Way w) 56 public void visit(Way w) 58 57 { 59 58 if (w.deleted || w.incomplete) return; 60 59 61 int numTags = 0;62 60 Map<String, String> tags = w.keys; 63 61 if( tags != null ) 64 62 { 65 numTags = tags.size(); 66 for( String tag : ALLOWED_TAGS) 67 if( tags.containsKey(tag) ) numTags--; 68 69 String highway = tags.get("highway"); 70 if( numTags != 0 && highway != null && NAMED_WAYS.contains(highway)) 71 { 72 if( !tags.containsKey("name") && !tags.containsKey("ref") ) 73 { 74 boolean hasName = false; 75 for( String key : w.keySet()) 76 { 77 hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref"); 78 if( hasName ) 79 break; 80 } 81 82 if( !hasName) 83 errors.add( new TestError(this, Severity.WARNING, tr("Unnamed ways"), w, UNNAMED_WAY ) ); 84 } 85 } 63 String highway = tags.get("highway"); 64 if(highway != null && NAMED_WAYS.contains(highway)) 65 { 66 if( !tags.containsKey("name") && !tags.containsKey("ref") ) 67 { 68 boolean hasName = false; 69 for( String key : w.keySet()) 70 { 71 hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref"); 72 if( hasName ) 73 break; 74 } 75 76 if( !hasName) 77 errors.add( new TestError(this, Severity.WARNING, tr("Unnamed ways"), UNNAMED_WAY, w) ); 78 } 79 } 86 80 } 87 88 if( numTags == 0 ) 89 { 90 errors.add( new TestError(this, Severity.WARNING, tr("Untagged ways"), w, UNTAGGED_WAY) ); 91 } 92 93 if( w.nodes.size() == 0 ) 94 { 95 errors.add( new TestError(this, Severity.ERROR, tr("Empty ways"), w, EMPTY_WAY) ); 96 } 97 98 if( w.nodes.size() == 1 ) 99 { 100 errors.add( new TestError(this, Severity.ERROR, tr("One node ways"), w, ONE_NODE_WAY) ); 101 } 102 103 } 104 81 82 if(Util.countDataTags(w) == 0) 83 { 84 errors.add( new TestError(this, Severity.WARNING, tr("Untagged ways"), UNTAGGED_WAY, w) ); 85 } 86 87 if( w.nodes.size() == 0 ) 88 { 89 errors.add( new TestError(this, Severity.ERROR, tr("Empty ways"), EMPTY_WAY, w) ); 90 } 91 else if( w.nodes.size() == 1 ) 92 { 93 errors.add( new TestError(this, Severity.ERROR, tr("One node ways"), ONE_NODE_WAY, w) ); 94 } 95 96 } 97 105 98 @Override 106 99 public boolean isFixable(TestError testError) … … 108 101 if( testError.getTester() instanceof UntaggedWay ) 109 102 { 110 return testError.get InternalCode() == EMPTY_WAY111 || testError.get InternalCode() == ONE_NODE_WAY;103 return testError.getCode() == EMPTY_WAY 104 || testError.getCode() == ONE_NODE_WAY; 112 105 } 113 106 114 107 return false; 115 108 } 116 109 117 110 @Override 118 111 public Command fixError(TestError testError) -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/WronglyOrderedWays.java
r8904 r9684 20 20 */ 21 21 public class WronglyOrderedWays extends Test { 22 protected static int WRONGLY_ORDERED_COAST = 1001; 23 protected static int WRONGLY_ORDERED_WATER = 1002; 24 protected static int WRONGLY_ORDERED_LAND = 1003; 25 22 26 /** The already detected errors */ 23 27 Bag<Way, Way> _errorWays; … … 43 47 _errorWays = null; 44 48 } 45 49 46 50 @Override 47 51 public void visit(Way w) 48 52 { 49 53 String errortype = ""; 50 54 int type; 55 51 56 if( w.deleted || w.incomplete ) 52 57 return; 53 58 54 59 String natural = w.get("natural"); 55 60 if( natural == null) 56 61 return; 57 62 58 63 if( natural.equals("coastline") ) 64 { 59 65 errortype = tr("Reversed coastline: land not on left side"); 66 type= WRONGLY_ORDERED_COAST; 67 } 60 68 else if(natural.equals("water") ) 69 { 61 70 errortype = tr("Reversed water: land not on left side"); 71 type= WRONGLY_ORDERED_WATER; 72 } 62 73 else if( natural.equals("land") ) 74 { 63 75 errortype = tr("Reversed land: land not on left side"); 76 type= WRONGLY_ORDERED_LAND; 77 } 64 78 else 65 79 return; … … 90 104 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 91 105 primitives.add(w); 92 errors.add( new TestError(this, Severity.WARNING, errortype, primitives) );106 errors.add( new TestError(this, Severity.WARNING, errortype, type, primitives) ); 93 107 _errorWays.add(w,w); 94 108 } -
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java
r9561 r9684 15 15 import org.openstreetmap.josm.Main; 16 16 import org.openstreetmap.josm.data.osm.Way; 17 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 18 import org.openstreetmap.josm.data.osm.Node; 18 19 import org.openstreetmap.josm.plugins.*; … … 22 23 /** 23 24 * Utility class 24 * 25 * 25 26 * @author frsantos 26 27 */ 27 public class Util 28 public class Util 28 29 { 29 /** 30 /** Tags without informational contents */ 31 private static final String[] noDataTags = new String[] { "created_by", "converted_by", "source" }; 32 public static int countDataTags(OsmPrimitive osm) 33 { 34 int numTags = 0; 35 Map<String, String> tags = osm.keys; 36 if(tags != null) 37 { 38 numTags = tags.size(); 39 for(String tag : noDataTags) 40 if(tags.containsKey(tag)) 41 --numTags; 42 } 43 return numTags; 44 } 45 46 /** 30 47 * Returns the plugin's directory of the plugin 31 * 48 * 32 49 * @return The directory of the plugin 33 50 */ … … 42 59 */ 43 60 public static Version getVersion() 44 45 46 47 61 { 62 PluginInformation info = PluginInformation.getLoaded("validator"); 63 if( info == null ) 64 return null; 48 65 49 66 return new Version(info.version, info.attr.get("Plugin-Date")); 50 51 52 53 54 * 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public Version(String revision, String time) 70 67 } 68 69 /** 70 * Utility class for displaying versions 71 * 72 * @author frsantos 73 */ 74 public static class Version 75 { 76 /** The revision */ 77 public String revision; 78 /** The build time */ 79 public String time; 80 81 /** 82 * Constructor 83 * @param revision 84 * @param time 85 */ 86 public Version(String revision, String time) 87 { 71 88 this.revision = revision; 72 89 this.time = time; 73 90 } 74 75 76 77 78 79 * 80 81 82 83 84 85 86 87 try 91 } 92 93 94 /** 95 * Loads a text file in a String 96 * 97 * @param resource The URL of the file 98 * @return A String with the file contents 99 * @throws IOException when error reading the file 100 */ 101 public static String loadFile(URL resource) throws IOException 102 { 103 BufferedReader in = null; 104 try 88 105 { 89 106 in = new BufferedReader(new InputStreamReader(resource.openStream())); 90 107 StringBuilder sb = new StringBuilder(); 91 for (String line = in.readLine(); line != null; line = in.readLine()) 108 for (String line = in.readLine(); line != null; line = in.readLine()) 92 109 { 93 110 sb.append(line); … … 107 124 } 108 125 } 109 110 111 112 113 114 115 * 116 117 118 * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 try 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 126 } 127 128 /** 129 * Mirrors a file to a local file. 130 * <p> 131 * The file mirrored is only downloaded if it has been more than one day since last download 132 * 133 * @param url The URL of the remote file 134 * @param destDir The destionation dir of the mirrored file 135 * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week 136 * @return The local file 137 */ 138 public static File mirror(URL url, String destDir, long maxTime) 139 { 140 if( url.getProtocol().equals("file") ) 141 return new File(url.toString() ) ; 142 143 String localPath = Main.pref.get( PreferenceEditor.PREFIX + ".mirror." + url); 144 File oldFile = null; 145 if( localPath != null && localPath.length() > 0) 146 { 147 StringTokenizer st = new StringTokenizer(localPath, ";"); 148 long checkDate = Long.parseLong(st.nextToken()); 149 localPath = st.nextToken(); 150 oldFile = new File(localPath); 151 maxTime = (maxTime <= 0) ? 7 * 24 * 60 * 60 * 1000 : maxTime * 1000; 152 if( System.currentTimeMillis() - checkDate < maxTime ) 153 { 154 if( oldFile.exists() ) 155 return oldFile; 156 } 157 } 158 159 File destDirFile = new File(destDir); 160 if( !destDirFile.exists() ) 161 destDirFile.mkdirs(); 162 163 localPath = destDir + System.currentTimeMillis() + "-" + new File(url.getPath()).getName(); 164 BufferedOutputStream bos = null; 165 BufferedInputStream bis = null; 166 try 167 { 168 URLConnection conn = url.openConnection(); 169 conn.setConnectTimeout(5000); 170 bis = new BufferedInputStream(conn.getInputStream()); 171 bos = new BufferedOutputStream( new FileOutputStream(localPath) ); 172 byte[] buffer = new byte[4096]; 173 int length; 174 while( (length = bis.read( buffer )) > -1 ) 175 { 176 bos.write( buffer, 0, length ); 177 } 178 } 179 catch(IOException ioe) 180 { 181 if( oldFile != null ) 182 return oldFile; 183 else 184 return null; 185 } 186 finally 187 { 188 if( bis != null ) 189 { 190 try { 191 bis.close(); 192 } catch (IOException e) { 193 e.printStackTrace(); 194 } 195 } 196 if( bos != null ) 197 { 198 try { 199 bos.close(); 200 } catch (IOException e) { 201 e.printStackTrace(); 202 } 203 } 204 } 205 206 Main.pref.put( PreferenceEditor.PREFIX + ".mirror." + url, System.currentTimeMillis() + ";" + localPath); 207 208 if( oldFile != null ) 209 oldFile.delete(); 210 211 return new File(localPath); 212 } 213 214 /** 215 * Returns the start and end cells of a way. 216 * @param w The way 217 * @param cellWays The map with all cells 218 * @return A list with all the cells the way starts or ends 219 */ 220 public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays) 221 { 205 222 if (w.nodes.size() == 0) 206 223 return Collections.emptyList(); 207 224 208 225 Node n1 = w.nodes.get(0); 209 226 Node n2 = w.nodes.get(w.nodes.size() - 1); 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 } 282 283 227 228 List<List<Way>> cells = new ArrayList<List<Way>>(2); 229 Set<Point2D> cellNodes = new HashSet<Point2D>(); 230 Point2D cell; 231 232 // First, round coordinates 233 long x0 = Math.round(n1.eastNorth.east() * 10000); 234 long y0 = Math.round(n1.eastNorth.north() * 10000); 235 long x1 = Math.round(n2.eastNorth.east() * 10000); 236 long y1 = Math.round(n2.eastNorth.north() * 10000); 237 238 // Start of the way 239 cell = new Point2D.Double(x0, y0); 240 cellNodes.add(cell); 241 List<Way> ways = cellWays.get( cell ); 242 if( ways == null ) 243 { 244 ways = new ArrayList<Way>(); 245 cellWays.put(cell, ways); 246 } 247 cells.add(ways); 248 249 // End of the way 250 cell = new Point2D.Double(x1, y1); 251 if( !cellNodes.contains(cell) ) 252 { 253 cellNodes.add(cell); 254 ways = cellWays.get( cell ); 255 if( ways == null ) 256 { 257 ways = new ArrayList<Way>(); 258 cellWays.put(cell, ways); 259 } 260 cells.add(ways); 261 } 262 263 // Then floor coordinates, in case the way is in the border of the cell. 264 x0 = (long)Math.floor(n1.eastNorth.east() * 10000); 265 y0 = (long)Math.floor(n1.eastNorth.north() * 10000); 266 x1 = (long)Math.floor(n2.eastNorth.east() * 10000); 267 y1 = (long)Math.floor(n2.eastNorth.north() * 10000); 268 269 // Start of the way 270 cell = new Point2D.Double(x0, y0); 271 if( !cellNodes.contains(cell) ) 272 { 273 cellNodes.add(cell); 274 ways = cellWays.get( cell ); 275 if( ways == null ) 276 { 277 ways = new ArrayList<Way>(); 278 cellWays.put(cell, ways); 279 } 280 cells.add(ways); 281 } 282 283 // End of the way 284 cell = new Point2D.Double(x1, y1); 285 if( !cellNodes.contains(cell) ) 286 { 287 cellNodes.add(cell); 288 ways = cellWays.get( cell ); 289 if( ways == null ) 290 { 291 ways = new ArrayList<Way>(); 292 cellWays.put(cell, ways); 293 } 294 cells.add(ways); 295 } 296 297 return cells; 298 } 299 300 /** 284 301 * Returns the coordinates of all cells in a grid that a line between 2 285 302 * nodes intersects with. 286 * 303 * 287 304 * @param n1 The first node. 288 305 * @param n2 The second node. … … 291 308 * @return A list with the coordinates of all cells 292 309 */ 293 public static List<Point2D> getSegmentCells(Node n1, Node n2, int gridDetail) 310 public static List<Point2D> getSegmentCells(Node n1, Node n2, int gridDetail) 294 311 { 295 312 List<Point2D> cells = new ArrayList<Point2D>(); 296 313 double x0 = n1.eastNorth.east() * gridDetail; 297 314 double x1 = n2.eastNorth.east() * gridDetail; 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 315 double y0 = n1.eastNorth.north() * gridDetail + 1; 316 double y1 = n2.eastNorth.north() * gridDetail + 1; 317 318 if( x0 > x1 ) 319 { 320 // Move to 1st-4th cuadrants 321 double aux; 322 aux = x0; x0 = x1; x1 = aux; 323 aux = y0; y0 = y1; y1 = aux; 324 } 325 326 double dx = x1 - x0; 327 double dy = y1 - y0; 328 long stepY = y0 <= y1 ? 1 : -1; 329 long gridX0 = (long)Math.floor(x0); 330 long gridX1 = (long)Math.floor(x1); 331 long gridY0 = (long)Math.floor(y0); 332 long gridY1 = (long)Math.floor(y1); 333 334 long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1; 318 335 while( (gridX0 <= gridX1 && (gridY0 - gridY1)*stepY <= 0) && maxSteps-- > 0) 319 336 { 320 337 cells.add( new Point2D.Double(gridX0, gridY0) ); 321 322 // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line? 323 324 // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line 325 326 327 328 338 339 // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line? 340 // Note: segment line formula: y=dy/dx(x-x1)+y1 341 // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line 342 double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0); 343 double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1; 344 345 double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2); 329 346 double distY = Math.pow(scanX - x0, 2) + Math.pow(gridY0 + stepY - y0, 2); 330 347 331 348 if( distX < distY) 332 333 334 335 336 349 gridX0 += 1; 350 else 351 gridY0 += stepY; 352 } 353 337 354 return cells; 338 } 355 } 339 356 }
Note:
See TracChangeset
for help on using the changeset viewer.