Changeset 9684 in osm for applications/editors/josm/plugins/validator/src
- Timestamp:
- 2008-08-11T22:26:25+02:00 (17 years ago)
- Location:
- applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator
- Files:
-
- 16 edited
-
OSMValidatorPlugin.java (modified) (7 diffs)
-
TestError.java (modified) (12 diffs)
-
tests/Coastlines.java (modified) (2 diffs)
-
tests/CrossingWays.java (modified) (7 diffs)
-
tests/DuplicateNode.java (modified) (6 diffs)
-
tests/DuplicatedWayNodes.java (modified) (3 diffs)
-
tests/NodesWithSameName.java (modified) (2 diffs)
-
tests/OverlappingWays.java (modified) (4 diffs)
-
tests/SelfIntersectingWay.java (modified) (3 diffs)
-
tests/SimilarNamedWays.java (modified) (2 diffs)
-
tests/TagChecker.java (modified) (18 diffs)
-
tests/UnclosedWays.java (modified) (14 diffs)
-
tests/UntaggedNode.java (modified) (5 diffs)
-
tests/UntaggedWay.java (modified) (3 diffs)
-
tests/WronglyOrderedWays.java (modified) (3 diffs)
-
util/Util.java (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified 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 /** 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>>();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 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);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 * Gets the list of all available test classes165 * 166 * @return An array of the test classesvalidationDialog.tree.setErrorList(errors);167 */168 public static Class[] getAllAvailableTests()169 {170 return allAvailableTests;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 List<TestError> errors = layerErrors.get(newLayer);206 validationDialog.tree.setErrorList(errors);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); -
TabularUnified 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 Theinternalcode47 */ 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 * Visitor that highlights the primitives affected by this error259 * @author frsantos260 */261 class PaintVisitor implements Visitor262 {263 /** The graphics */264 private final Graphics g;265 /** The MapView */266 private final MapView mv;267 268 /**269 * Constructor270 * @param g The graphics271 * @param mv The Mapview272 */273 public PaintVisitor(Graphics g, MapView mv)274 {275 this.g = g;276 this.mv = mv;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 if (!p.deleted && !p.incomplete) {281 p.visit(this);282 } 283 } 284 285 /**286 * Draws a circle around the node287 * @param n The node288 * @param color The circle color289 */290 public void drawNode(Node n, Color color)291 {292 Point p = mv.getPoint(n.eastNorth);293 g.setColor(color);294 if( selected )295 {296 g.fillOval(p.x-5, p.y-5, 10, 10);297 }298 else299 g.drawOval(p.x-5, p.y-5, 10, 10);300 }301 302 /**303 * Draws a line around the segment304 * 305 * @param s The segment306 * @param color The color307 */308 public void drawSegment(Node n1, Node n2, Color color)309 {310 Point p1 = mv.getPoint(n1.eastNorth);311 Point p2 = mv.getPoint(n2.eastNorth);312 g.setColor(color);313 314 double t = Math.atan2(p2.x-p1.x, p2.y-p1.y);315 double cosT = Math.cos(t);316 double sinT = Math.sin(t);317 int deg = (int)Math.toDegrees(t);318 if( selected )319 {320 int[] x = new int[] {(int)(p1.x + 5*cosT), (int)(p2.x + 5*cosT), (int)(p2.x - 5*cosT), (int)(p1.x - 5*cosT)};321 int[] y = new int[] {(int)(p1.y - 5*sinT), (int)(p2.y - 5*sinT), (int)(p2.y + 5*sinT), (int)(p1.y + 5*sinT)};322 g.fillPolygon(x, y, 4);323 g.fillArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );324 g.fillArc(p2.x-5, p2.y-5, 10, 10, deg, -180);325 }326 else327 {328 g.drawLine((int)(p1.x + 5*cosT), (int)(p1.y - 5*sinT), (int)(p2.x + 5*cosT), (int)(p2.y - 5*sinT));329 g.drawLine((int)(p1.x - 5*cosT), (int)(p1.y + 5*sinT), (int)(p2.x - 5*cosT), (int)(p2.y + 5*sinT));330 g.drawArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );331 g.drawArc(p2.x-5, p2.y-5, 10, 10, deg, -180);332 }333 }334 335 336 /**337 * Draw a small rectangle.338 * White if selected (as always) or red otherwise.339 * 340 * @param n The node to draw.341 */342 public void visit(Node n)343 {344 if( isNodeVisible(n) )345 drawNode(n, severity.getColor());346 }347 348 public void visit(Way w)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 if (isSegmentVisible(lastN, n))357 {358 drawSegment(lastN, n, severity.getColor());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 * Checks if the given node is in the visible area.380 * @param n The node to check for visibility381 * @return true if the node is visible382 */383 protected boolean isNodeVisible(Node n) {384 Point p = mv.getPoint(n.eastNorth);385 return !((p.x < 0) || (p.y < 0) || (p.x > mv.getWidth()) || (p.y > mv.getHeight()));386 }387 388 /**389 * Checks if the given segment is in the visible area.390 * NOTE: This will return true for a small number of non-visible391 *segments.392 * @param ls The segment to check393 * @return true if the segment is visible394 */395 protected boolean isSegmentVisible(Node n1, Node n2) {396 Point p1 = mv.getPoint(n1.eastNorth);397 Point p2 = mv.getPoint(n2.eastNorth);398 if ((p1.x < 0) && (p2.x < 0)) return false;399 if ((p1.y < 0) && (p2.y < 0)) return false;400 if ((p1.x > mv.getWidth()) && (p2.x > mv.getWidth())) return false;401 if ((p1.y > mv.getHeight()) && (p2.y > mv.getHeight())) return false;402 return true;403 }404 }405 406 /**407 * Sets the selection flag of this error408 * @param selected if this error is selected409 */410 public void setSelected(boolean selected)411 {412 this.selected = selected;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 } -
TabularUnified 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 @Override38 public void startTest()39 {40 _cellWays = new HashMap<Point2D,List<Way>>(1000);41 _errorWays = new Bag<Way, Way>();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 } -
TabularUnified 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 String layer1 = w.get("layer");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 List<ExtendedSegment> segments = cellSegments.get( cell );134 if( segments == null )135 {136 segments = new ArrayList<ExtendedSegment>();137 cellSegments.put(cell, segments);138 }139 cells.add(segments);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 * A way segment with some additional information147 * @author frsantos148 */149 private class ExtendedSegment150 {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 /** The layer */156 public String layer;157 158 /** The railway type */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 * Constructor166 * @param ws The way segment167 * @param layer The layer of the way this segment is in168 * @param railway The railway type of the way this segment is in169 * @param coastline The coastlyne typo of the way the segment is in170 */171 public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline)172 {173 this.ws = ws;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 this.layer = layer;177 this.railway = railway;178 this.coastline = coastline;179 }180 181 /**182 * Checks whether this segment crosses other segment183 * @param s2 The other segment184 * @return true if both segements crosses185 */186 public boolean intersects(ExtendedSegment s2)187 {188 if( n1.equals(s2.n1) || n2.equals(s2.n2) || 189 n1.equals(s2.n2) || n2.equals(s2.n1) )190 {191 return false;192 }193 194 return Line2D.linesIntersect(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 } -
TabularUnified 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 * Merge the nodes into one.66 * Copied from UtilsPlugin.MergePointsAction67 */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 cmds.add(new DeleteCommand(nodes));138 cmds.add(new ChangeCommand(target, newtarget));139 return new SequenceCommand(tr("Merge Nodes"), cmds);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 } -
TabularUnified 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; -
TabularUnified 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 } -
TabularUnified 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 * highways or railways mark a seperate error87 */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; -
TabularUnified 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 } -
TabularUnified 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 @Override38 public void startTest()39 {40 cellWays = new HashMap<Point2D,List<Way>>(1000);41 errorWays = new Bag<Way, Way>();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 } -
TabularUnified 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 } -
TabularUnified 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 } -
TabularUnified 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 } -
TabularUnified 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) -
TabularUnified 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 } -
TabularUnified 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 PluginInformation info = PluginInformation.getLoaded("validator");46 if( info == null )47 return null;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 * Utility class for displaying versions54 * 55 * @author frsantos56 */57 public static class Version58 {59 /** The revision */60 public String revision;61 /** The build time */62 public String time;63 64 /**65 * Constructor66 * @param revision67 * @param time68 */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 * Loads a text file in a String79 * 80 * @param resource The URL of the file81 * @return A String with the file contents82 * @throws IOException when error reading the file83 */84 public static String loadFile(URL resource) throws IOException85 {86 BufferedReader in = null;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 * Mirrors a file to a local file.113 * <p>114 * The file mirrored is only downloaded if it has been more than one day since last download115 * 116 * @param url The URL of the remote file117 * @param destDir The destionation dir of the mirrored file118 * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week119 * @return The local file120 */121 public static File mirror(URL url, String destDir, long maxTime)122 {123 if( url.getProtocol().equals("file") )124 return new File(url.toString() ) ;125 126 String localPath = Main.pref.get( PreferenceEditor.PREFIX + ".mirror." + url);127 File oldFile = null;128 if( localPath != null && localPath.length() > 0)129 {130 StringTokenizer st = new StringTokenizer(localPath, ";");131 long checkDate = Long.parseLong(st.nextToken());132 localPath = st.nextToken();133 oldFile = new File(localPath);134 maxTime = (maxTime <= 0) ? 7 * 24 * 60 * 60 * 1000 : maxTime * 1000;135 if( System.currentTimeMillis() - checkDate < maxTime )136 {137 if( oldFile.exists() )138 return oldFile;139 }140 }141 142 File destDirFile = new File(destDir);143 if( !destDirFile.exists() )144 destDirFile.mkdirs();145 146 localPath = destDir + System.currentTimeMillis() + "-" + new File(url.getPath()).getName();147 BufferedOutputStream bos = null;148 BufferedInputStream bis = null;149 try 150 {151 URLConnection conn = url.openConnection();152 conn.setConnectTimeout(5000);153 bis = new BufferedInputStream(conn.getInputStream());154 bos = new BufferedOutputStream( new FileOutputStream(localPath) );155 byte[] buffer = new byte[4096];156 int length;157 while( (length = bis.read( buffer )) > -1 )158 {159 bos.write( buffer, 0, length );160 }161 }162 catch(IOException ioe)163 {164 if( oldFile != null )165 return oldFile;166 else167 return null;168 }169 finally170 {171 if( bis != null )172 {173 try {174 bis.close();175 } catch (IOException e) {176 e.printStackTrace();177 }178 }179 if( bos != null )180 {181 try {182 bos.close();183 } catch (IOException e) {184 e.printStackTrace();185 }186 }187 }188 189 Main.pref.put( PreferenceEditor.PREFIX + ".mirror." + url, System.currentTimeMillis() + ";" + localPath);190 191 if( oldFile != null )192 oldFile.delete();193 194 return new File(localPath);195 }196 197 /**198 * Returns the start and end cells of a way.199 * @param w The way200 * @param cellWays The map with all cells201 * @return A list with all the cells the way starts or ends202 */203 public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays)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 return Collections.emptyList();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 List<List<Way>> cells = new ArrayList<List<Way>>(2);212 Set<Point2D> cellNodes = new HashSet<Point2D>();213 Point2D cell;214 215 // First, round coordinates216 long x0 = Math.round(n1.eastNorth.east() * 10000);217 long y0 = Math.round(n1.eastNorth.north() * 10000);218 long x1 = Math.round(n2.eastNorth.east() * 10000);219 long y1 = Math.round(n2.eastNorth.north() * 10000);220 221 // Start of the way222 cell = new Point2D.Double(x0, y0);223 cellNodes.add(cell);224 List<Way> ways = cellWays.get( cell );225 if( ways == null )226 {227 ways = new ArrayList<Way>();228 cellWays.put(cell, ways);229 }230 cells.add(ways);231 232 // End of the way233 cell = new Point2D.Double(x1, y1);234 if( !cellNodes.contains(cell) )235 {236 cellNodes.add(cell);237 ways = cellWays.get( cell );238 if( ways == null )239 {240 ways = new ArrayList<Way>();241 cellWays.put(cell, ways);242 }243 cells.add(ways);244 }245 246 // Then floor coordinates, in case the way is in the border of the cell.247 x0 = (long)Math.floor(n1.eastNorth.east() * 10000);248 y0 = (long)Math.floor(n1.eastNorth.north() * 10000);249 x1 = (long)Math.floor(n2.eastNorth.east() * 10000);250 y1 = (long)Math.floor(n2.eastNorth.north() * 10000);251 252 // Start of the way253 cell = new Point2D.Double(x0, y0);254 if( !cellNodes.contains(cell) )255 {256 cellNodes.add(cell);257 ways = cellWays.get( cell );258 if( ways == null )259 {260 ways = new ArrayList<Way>();261 cellWays.put(cell, ways);262 }263 cells.add(ways);264 }265 266 // End of the way267 cell = new Point2D.Double(x1, y1);268 if( !cellNodes.contains(cell) )269 {270 cellNodes.add(cell);271 ways = cellWays.get( cell );272 if( ways == null )273 {274 ways = new ArrayList<Way>();275 cellWays.put(cell, ways);276 }277 cells.add(ways);278 }279 280 return cells;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 double y0 = n1.eastNorth.north() * gridDetail + 1;299 double y1 = n2.eastNorth.north() * gridDetail + 1;300 301 if( x0 > x1 )302 {303 // Move to 1st-4th cuadrants304 double aux;305 aux = x0; x0 = x1; x1 = aux;306 aux = y0; y0 = y1; y1 = aux;307 }308 309 double dx = x1 - x0;310 double dy = y1 - y0;311 long stepY = y0 <= y1 ? 1 : -1;312 long gridX0 = (long)Math.floor(x0);313 long gridX1 = (long)Math.floor(x1);314 long gridY0 = (long)Math.floor(y0);315 long gridY1 = (long)Math.floor(y1);316 317 long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1;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 // Note: segment line formula: y=dy/dx(x-x1)+y1324 // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line 325 double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0);326 double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1;327 328 double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2);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 gridX0 += 1;333 else334 gridY0 += stepY;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.
