Changeset 15008 in josm
- Timestamp:
- 2019-04-21T07:43:00+02:00 (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java
r13030 r15008 13 13 * The way. 14 14 */ 15 public Way way;15 public final Way way; 16 16 17 17 /** … … 19 19 * index <code>lowerIndex + 1</code>. 20 20 */ 21 public int lowerIndex;21 public final int lowerIndex; 22 22 23 23 /** -
trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
r14437 r15008 272 272 for (int j = i + 1; j < allPolygons.size(); j++) { 273 273 PolyData pd2 = allPolygons.get(j); 274 if (!checkProblemMap(crossingPolyMap, pd1, pd2)) { 275 if (hasIntersectionWay(pd2, intersectionWays)) 276 checkPolygonsForSharedNodes(r, pd1, pd2, sharedNodes); 274 if (!checkProblemMap(crossingPolyMap, pd1, pd2) && hasIntersectionWay(pd2, intersectionWays)) { 275 checkPolygonsForSharedNodes(r, pd1, pd2, sharedNodes); 277 276 } 278 277 } … … 472 471 Area a1 = new Area(pd1.get()); 473 472 Area a2 = new Area(pd2.get()); 474 PolygonIntersection areaRes = Geometry.polygonIntersection(a1, a2 , 1e-6);473 PolygonIntersection areaRes = Geometry.polygonIntersection(a1, a2); 475 474 if (areaRes == PolygonIntersection.OUTSIDE) 476 475 return ExtPolygonIntersection.OUTSIDE; … … 842 841 843 842 for (PolyData pd : polygons) { 844 if (processOuterWay(level, polygons, result, pd) == null) { 845 return null; 846 } 843 processOuterWay(level, polygons, result, pd); 847 844 } 848 845 … … 850 847 } 851 848 852 private ObjectprocessOuterWay(int level, List<PolyData> polygons, List<PolygonLevel> result, PolyData pd) {849 private void processOuterWay(int level, List<PolyData> polygons, List<PolygonLevel> result, PolyData pd) { 853 850 List<PolyData> inners = findInnerWaysCandidates(pd, polygons); 854 851 … … 865 862 result.add(pol); 866 863 } 867 return result;868 864 } 869 865 -
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r14521 r15008 2 2 package org.openstreetmap.josm.tools; 3 3 4 import java.awt.Rectangle;5 4 import java.awt.geom.Area; 6 5 import java.awt.geom.Line2D; 7 6 import java.awt.geom.Path2D; 7 import java.awt.geom.PathIterator; 8 import java.awt.geom.Rectangle2D; 8 9 import java.math.BigDecimal; 9 10 import java.math.MathContext; … … 72 73 } 73 74 75 /** threshold value for size of intersection area given in east/north space */ 76 public static final double INTERSECTION_EPS_EAST_NORTH = 1e-4; 77 74 78 /** 75 79 * Will find all intersection and add nodes there for list of given ways. … … 578 582 Area a1 = getArea(first); 579 583 Area a2 = getArea(second); 580 return polygonIntersection(a1, a2 );581 } 582 583 /** 584 * Tests if two polygons intersect. 584 return polygonIntersection(a1, a2, INTERSECTION_EPS_EAST_NORTH); 585 } 586 587 /** 588 * Tests if two polygons intersect. It is assumed that the area is given in East North points. 585 589 * @param a1 Area of first polygon 586 590 * @param a2 Area of second polygon … … 589 593 */ 590 594 public static PolygonIntersection polygonIntersection(Area a1, Area a2) { 591 return polygonIntersection(a1, a2, 1.0);595 return polygonIntersection(a1, a2, INTERSECTION_EPS_EAST_NORTH); 592 596 } 593 597 … … 604 608 inter.intersect(a2); 605 609 606 Rectangle bounds = inter.getBounds(); 607 608 if (inter.isEmpty() || bounds.getHeight()*bounds.getWidth() <= eps) { 610 if (inter.isEmpty() || !checkIntersection(inter, eps)) { 609 611 return PolygonIntersection.OUTSIDE; 610 612 } else if (a2.getBounds2D().contains(a1.getBounds2D()) && inter.equals(a1)) { … … 618 620 619 621 /** 622 * Check an intersection area which might describe multiple small polygons. 623 * Return true if any of the polygons is bigger than the given threshold. 624 * @param inter the intersection area 625 * @param eps an area threshold, everything below is considered an empty intersection 626 * @return true if any of the polygons is bigger than the given threshold 627 */ 628 private static boolean checkIntersection(Area inter, double eps) { 629 PathIterator pit = inter.getPathIterator(null); 630 double[] res = new double[6]; 631 Rectangle2D r = new Rectangle2D.Double(); 632 while (!pit.isDone()) { 633 int type = pit.currentSegment(res); 634 switch (type) { 635 case PathIterator.SEG_MOVETO: 636 r = new Rectangle2D.Double(res[0], res[1], 0, 0); 637 break; 638 case PathIterator.SEG_LINETO: 639 r.add(res[0], res[1]); 640 break; 641 case PathIterator.SEG_CLOSE: 642 if (r.getWidth() > eps || r.getHeight() > eps) 643 return true; 644 break; 645 default: 646 break; 647 } 648 pit.next(); 649 } 650 return false; 651 } 652 653 /** 620 654 * Tests if point is inside a polygon. The polygon can be self-intersecting. In such case the contains function works in xor-like manner. 621 655 * @param polygonNodes list of nodes from polygon path. … … 778 812 * 779 813 * @param p1 first point 780 * @param p2 Common endpoint814 * @param common Common end point 781 815 * @param p3 third point 782 816 * @return Angle in radians (-pi, pi] 783 817 */ 784 public static double getCornerAngle(EastNorth p1, EastNorth p2, EastNorth p3) {818 public static double getCornerAngle(EastNorth p1, EastNorth common, EastNorth p3) { 785 819 786 820 CheckParameterUtil.ensure(p1, "p1", EastNorth::isValid); 787 CheckParameterUtil.ensure( p2, "p2", EastNorth::isValid);821 CheckParameterUtil.ensure(common, "p2", EastNorth::isValid); 788 822 CheckParameterUtil.ensure(p3, "p3", EastNorth::isValid); 789 823 790 Double result = getSegmentAngle(p2, p1) - getSegmentAngle(p2, p3);824 double result = getSegmentAngle(common, p1) - getSegmentAngle(common, p3); 791 825 if (result <= -Math.PI) { 792 826 result += 2 * Math.PI; -
trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java
r13712 r15008 3 3 4 4 import static org.junit.Assert.assertEquals; 5 import static org.junit.Assert.assertNotEquals; 5 6 6 7 import java.io.FileInputStream; … … 159 160 assertEquals(new EastNorth(150, 266d + 2d/3d), Geometry.getCentroidEN(Arrays.asList(en1, en2, en3))); 160 161 } 162 163 164 /** 165 * Test of {@link Geometry#polygonIntersection} method with two triangles. 166 */ 167 @Test 168 public void testPolygonIntersectionTriangles() { 169 Node node1 = new Node(new LatLon(0.0, 1.0)); 170 Node node2 = new Node(new LatLon(0.0, 2.0)); 171 Node node3 = new Node(new LatLon(5.0, 1.5)); 172 List<Node> poly1 = Arrays.asList(node1, node2, node3, node1); 173 Node node4 = new Node(new LatLon(10.0, 1.0)); 174 Node node5 = new Node(new LatLon(10.0, 2.0)); 175 Node node6 = new Node(new LatLon(5.000001, 1.5)); 176 List<Node> poly2 = Arrays.asList(node4, node5, node6, node4); 177 // no intersection, not even touching 178 assertEquals(Geometry.PolygonIntersection.OUTSIDE, Geometry.polygonIntersection(poly1, poly2)); 179 180 node5.setCoor(new LatLon(5.0, 1.5)); 181 // touching in a single point with two different nodes 182 assertEquals(Geometry.PolygonIntersection.OUTSIDE, Geometry.polygonIntersection(poly1, poly2)); 183 184 node5.setCoor(new LatLon(4.99999999, 1.5)); 185 // now node5 lies inside way1, intersection is a very small area, in OSM precision nodes are equal 186 assertEquals(node5.getCoor().getRoundedToOsmPrecision(), node3.getCoor().getRoundedToOsmPrecision()); 187 assertEquals(Geometry.PolygonIntersection.CROSSING, Geometry.polygonIntersection(poly1, poly2)); 188 189 node5.setCoor(new LatLon(4.9999999, 1.5)); 190 // intersection area is too big to ignore 191 assertNotEquals(node5.getCoor().getRoundedToOsmPrecision(), node3.getCoor().getRoundedToOsmPrecision()); 192 assertEquals(Geometry.PolygonIntersection.CROSSING, Geometry.polygonIntersection(poly1, poly2)); 193 } 194 195 /** 196 * Test of {@link Geometry#polygonIntersection} method with two V-shapes 197 */ 198 @Test 199 public void testPolygonIntersectionVShapes() { 200 Node node1 = new Node(new LatLon(1.0, 1.0)); 201 Node node2 = new Node(new LatLon(2.0, 2.0)); 202 Node node3 = new Node(new LatLon(0.9, 1.0)); 203 Node node4 = new Node(new LatLon(2.0, 0.0)); 204 List<Node> poly1 = Arrays.asList(node1, node2, node3, node4, node1); 205 Node node5 = new Node(new LatLon(3.0, 1.0)); 206 Node node6 = new Node(new LatLon(2.0, 2.0)); // like node2 207 Node node7 = new Node(new LatLon(3.1, 1.0)); 208 Node node8 = new Node(new LatLon(2.0, 0.0)); // like node4 209 List<Node> poly2 = Arrays.asList(node5, node6, node7, node8, node5); 210 211 // touching in two points but not overlapping 212 assertEquals(Geometry.PolygonIntersection.OUTSIDE, Geometry.polygonIntersection(poly1, poly2)); 213 214 // touching in one point, small overlap at the other 215 node6.setCoor(new LatLon(1.9999999, 2.0)); 216 assertEquals(Geometry.PolygonIntersection.CROSSING, Geometry.polygonIntersection(poly1, poly2)); 217 218 // two small overlaps, but clearly visible because lines are crossing 219 node6.setCoor(new LatLon(1.99999999, 2.0)); 220 node8.setCoor(new LatLon(1.99999999, 0.0)); 221 assertEquals(Geometry.PolygonIntersection.OUTSIDE, Geometry.polygonIntersection(poly1, poly2)); 222 } 161 223 }
Note:
See TracChangeset
for help on using the changeset viewer.