Changeset 4344 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2011-08-26T22:26:37+02:00 (13 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/WronglyOrderedWays.java
r3674 r4344 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.util.ArrayList; 7 import java.util.List; 6 import java.util.Collections; 8 7 9 import org.openstreetmap.josm.data.osm.OsmPrimitive;10 8 import org.openstreetmap.josm.data.osm.Way; 11 9 import org.openstreetmap.josm.data.validation.Severity; 12 10 import org.openstreetmap.josm.data.validation.Test; 13 11 import org.openstreetmap.josm.data.validation.TestError; 14 import org.openstreetmap.josm. gui.progress.ProgressMonitor;12 import org.openstreetmap.josm.tools.Geometry; 15 13 16 14 /** … … 22 20 23 21 protected static int WRONGLY_ORDERED_COAST = 1001; 24 protected static int WRONGLY_ORDERED_WATER = 1002;22 //protected static int WRONGLY_ORDERED_WATER = 1002; 25 23 protected static int WRONGLY_ORDERED_LAND = 1003; 26 24 … … 34 32 35 33 @Override 36 public void startTest(ProgressMonitor monitor) { 37 super.startTest(monitor); 38 } 34 public void visit(Way w) { 39 35 40 @Override 41 public void endTest() { 42 super.endTest(); 43 } 44 45 @Override 46 public void visit(Way w) { 47 String errortype = ""; 48 int type; 49 50 if (!w.isUsable()) 51 return; 52 if (w.getNodesCount() <= 0) 36 if (!w.isUsable() || !w.isClosed()) 53 37 return; 54 38 55 39 String natural = w.get("natural"); 56 if (natural == null) 40 if (natural == null) { 57 41 return; 42 } else if ("coastline".equals(natural) && Geometry.isClockwise(w)) { 43 reportError(w, tr("Reversed coastline: land not on left side"), WRONGLY_ORDERED_COAST); 44 /*} else if ("water".equals(natural) && !Geometry.isClockwise(w)) { 45 reportError(w, tr("Reversed water: land not on left side"), WRONGLY_ORDERED_WATER);*/ 46 } else if ("land".equals(natural) && Geometry.isClockwise(w)) { 47 reportError(w, tr("Reversed land: land not on left side"), WRONGLY_ORDERED_LAND); 48 } else { 49 return; 50 } 58 51 59 if (natural.equals("coastline")) { 60 errortype = tr("Reversed coastline: land not on left side"); 61 type= WRONGLY_ORDERED_COAST; 62 } else if (natural.equals("water")) { 63 errortype = tr("Reversed water: land not on left side"); 64 type= WRONGLY_ORDERED_WATER; 65 } else if (natural.equals("land")) { 66 errortype = tr("Reversed land: land not on left side"); 67 type= WRONGLY_ORDERED_LAND; 68 } else 69 return; 52 } 70 53 71 /** 72 * Test the directionality of the way 73 * 74 * Assuming a closed non-looping way, compute twice the area 75 * of the polygon using the formula 2*a = sum (Xn * Yn+1 - Xn+1 * Yn) 76 * If the area is negative the way is ordered in a clockwise direction 77 * 78 */ 79 if (w.getNode(0) == w.getNode(w.getNodesCount()-1)) { 80 double area2 = 0; 81 82 for (int node = 1; node < w.getNodesCount(); node++) { 83 area2 += (w.getNode(node-1).getCoor().lon() * w.getNode(node).getCoor().lat() 84 - w.getNode(node).getCoor().lon() * w.getNode(node-1).getCoor().lat()); 85 } 86 87 if (((natural.equals("coastline") || natural.equals("land")) && area2 < 0.) 88 || (natural.equals("water") && area2 > 0.)) { 89 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(); 90 primitives.add(w); 91 errors.add( new TestError(this, Severity.OTHER, errortype, type, primitives) ); 92 } 93 } 54 private void reportError(Way w, String msg, int type) { 55 errors.add(new TestError(this, Severity.OTHER, msg, type, Collections.singletonList(w))); 94 56 } 95 57 } -
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r4134 r4344 15 15 import org.openstreetmap.josm.command.Command; 16 16 import org.openstreetmap.josm.data.coor.EastNorth; 17 import org.openstreetmap.josm.data.coor.LatLon; 17 18 import org.openstreetmap.josm.data.osm.BBox; 18 19 import org.openstreetmap.josm.data.osm.Node; … … 221 222 */ 222 223 public static boolean angleIsClockwise(Node commonNode, Node firstNode, Node secondNode) { 223 double dy1 = (firstNode.getEastNorth().getY() - commonNode.getEastNorth().getY()); 224 double dy2 = (secondNode.getEastNorth().getY() - commonNode.getEastNorth().getY()); 225 double dx1 = (firstNode.getEastNorth().getX() - commonNode.getEastNorth().getX()); 226 double dx2 = (secondNode.getEastNorth().getX() - commonNode.getEastNorth().getX()); 227 228 return dy1 * dx2 - dx1 * dy2 > 0; 224 return angleIsClockwise(commonNode.getEastNorth(), firstNode.getEastNorth(), secondNode.getEastNorth()); 229 225 } 230 226 … … 527 523 } 528 524 529 525 /** 526 * Determines whether a way is oriented clockwise. 527 * 528 * Internals: Assuming a closed non-looping way, compute twice the area 529 * of the polygon using the formula {@code 2 * area = sum (X[n] * Y[n+1] - X[n+1] * Y[n])}. 530 * If the area is negative the way is ordered in a clockwise direction. 531 * 532 * @param w the way to be checked. 533 * @return true if and only if way is oriented clockwise. 534 * @throws IllegalArgumentException if way is not closed (see {@see Way#isClosed}). 535 * @see http://paulbourke.net/geometry/polyarea/ 536 */ 537 public static boolean isClockwise(Way w) { 538 if (!w.isClosed()) { 539 throw new IllegalArgumentException("Way must be closed to check orientation."); 540 } 541 542 double area2 = 0.; 543 int nodesCount = w.getNodesCount(); 544 545 for (int node = 1; node <= /*sic! consider last-first as well*/ nodesCount; node++) { 546 LatLon coorPrev = w.getNode(node - 1).getCoor(); 547 LatLon coorCurr = w.getNode(node % nodesCount).getCoor(); 548 area2 += coorPrev.lon() * coorCurr.lat(); 549 area2 -= coorCurr.lon() * coorPrev.lat(); 550 } 551 return area2 < 0; 552 } 530 553 }
Note:
See TracChangeset
for help on using the changeset viewer.