Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r18589 r18590 492 492 double pdx = point.getX() - p1.getX(); 493 493 double pdy = point.getY() - p1.getY(); 494 495 double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy);496 497 if (segmentOnly && offset <= 0)498 return p1;499 else if (segmentOnly && offset >= 1)500 return p2;501 else502 return p1.interpolate(p2, offset);503 }504 505 /**506 * Get the closest point to a segment507 * @param p1 Point 1 of the segment508 * @param p2 Point 2 of the segment509 * @param point The point to use to get the closest point on the segment510 * @param segmentOnly {@code true} if the point <i>must</i> be on the segment511 * @return The closest point on the segment if {@code segmentOnly = true}, otherwise the closest point on the infinite line.512 */513 private static ILatLon closestPointTo(ILatLon p1, ILatLon p2, ILatLon point, boolean segmentOnly) {514 CheckParameterUtil.ensureParameterNotNull(p1, "p1");515 CheckParameterUtil.ensureParameterNotNull(p2, "p2");516 CheckParameterUtil.ensureParameterNotNull(point, "point");517 518 double ldx = p2.lon() - p1.lon();519 double ldy = p2.lat() - p1.lat();520 521 //segment zero length522 if (ldx == 0 && ldy == 0)523 return p1;524 525 double pdx = point.lon() - p1.lon();526 double pdy = point.lat() - p1.lat();527 494 528 495 double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy); … … 1534 1501 1535 1502 double smallest = Double.MAX_VALUE; 1503 EastNorth en0 = node.getEastNorth(); 1536 1504 // go through the nodes as if they were paired 1537 1505 Iterator<Node> iter = way.getNodes().iterator(); 1538 Node en1 = iter.next();1506 EastNorth en1 = iter.next().getEastNorth(); 1539 1507 while (iter.hasNext()) { 1540 Node en2 = iter.next();1541 double distance = getSegmentNodeDistSq(en1, en2, node);1508 EastNorth en2 = iter.next().getEastNorth(); 1509 double distance = getSegmentNodeDistSq(en1, en2, en0); 1542 1510 if (distance < smallest) 1543 1511 smallest = distance; … … 1592 1560 double rValue = Double.MAX_VALUE; 1593 1561 Iterator<Node> iter1 = w1.getNodes().iterator(); 1562 List<Node> w2Nodes = w2.getNodes(); 1594 1563 Node w1N1 = iter1.next(); 1595 List<Node> w2Nodes = w2.getNodes();1596 1564 while (iter1.hasNext()) { 1597 1565 Node w1N2 = iter1.next(); … … 1638 1606 return Double.NaN; 1639 1607 } 1640 if (getSegmentSegmentIntersection(ws1Node1, ws1Node2, ws2Node1, ws2Node2) != null) 1608 EastNorth enWs1Node1 = ws1Node1.getEastNorth(); 1609 EastNorth enWs1Node2 = ws1Node2.getEastNorth(); 1610 EastNorth enWs2Node1 = ws2Node1.getEastNorth(); 1611 EastNorth enWs2Node2 = ws2Node2.getEastNorth(); 1612 if (getSegmentSegmentIntersection(enWs1Node1, enWs1Node2, enWs2Node1, enWs2Node2) != null) 1641 1613 return 0; 1642 1614 1643 double dist1sq = getSegmentNodeDistSq( ws1Node1, ws1Node2, ws2Node1);1644 double dist2sq = getSegmentNodeDistSq( ws1Node1, ws1Node2, ws2Node2);1645 double dist3sq = getSegmentNodeDistSq( ws2Node1, ws2Node2, ws1Node1);1646 double dist4sq = getSegmentNodeDistSq( ws2Node1, ws2Node2, ws1Node2);1615 double dist1sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node1); 1616 double dist2sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node2); 1617 double dist3sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node1); 1618 double dist4sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node2); 1647 1619 double smallest = Math.min(Math.min(dist1sq, dist2sq), Math.min(dist3sq, dist4sq)); 1648 1620 return smallest != Double.MAX_VALUE ? Math.sqrt(smallest) : Double.NaN; … … 1679 1651 * @return the square of the euclidean distance from p to the closest point on the segment 1680 1652 */ 1681 private static double getSegmentNodeDistSq( ILatLon s1, ILatLon s2, ILatLonp) {1682 ILatLonc1 = closestPointTo(s1, s2, p, true);1683 return c1.distanceSq(p .lon(), p.lat());1653 private static double getSegmentNodeDistSq(EastNorth s1, EastNorth s2, EastNorth p) { 1654 EastNorth c1 = closestPointTo(s1, s2, p, true); 1655 return c1.distanceSq(p); 1684 1656 } 1685 1657 } -
trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java
r18589 r18590 5 5 import static org.junit.jupiter.api.Assertions.assertFalse; 6 6 import static org.junit.jupiter.api.Assertions.assertNotEquals; 7 import static org.junit.jupiter.api.Assertions.assertNotNull; 7 8 import static org.junit.jupiter.api.Assertions.assertTrue; 8 9 … … 17 18 import java.util.stream.Stream; 18 19 19 import org.junit.Assert;20 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 20 21 import org.junit.jupiter.api.Test; 21 22 import org.junit.jupiter.api.extension.RegisterExtension; … … 40 41 import org.openstreetmap.josm.testutils.JOSMTestRules; 41 42 42 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;43 44 43 /** 45 44 * Unit tests of {@link Geometry} class. … … 51 50 @RegisterExtension 52 51 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 53 public JOSMTestRules test = new JOSMTestRules().preferences().projection();52 static JOSMTestRules test = new JOSMTestRules().preferences().projection(); 54 53 55 54 /** … … 65 64 EastNorth intersectionPoint = Geometry.getLineLineIntersection(p1, p2, p3, p4); 66 65 66 assertNotNull(intersectionPoint); 67 67 EastNorth d1 = p3.subtract(intersectionPoint); 68 68 EastNorth d2 = p1.subtract(p2); … … 72 72 Double len2 = d2.length(); 73 73 74 Double angle1 = Geometry.getCornerAngle(p1, p2, intersectionPoint); 75 Double angle2 = Geometry.getCornerAngle(p3, p4, intersectionPoint); 76 Assert.assertTrue("intersection point not on line, angle: " + angle1, 77 Math.abs(angle1) < 1e-10); 78 Assert.assertTrue("intersection point not on line, angle: " + angle2, 79 Math.abs(angle1) < 1e-10); 80 81 Assert.assertTrue("cross product != 1 : " + Math.abs(crossProduct/len1/len2), 82 Math.abs(Math.abs(crossProduct/len1/len2) - 1) < 1e-10); 83 Assert.assertTrue("scalar product != 0 : " + scalarProduct/len1/len2, 84 Math.abs(scalarProduct/len1/len2) < 1e-10); 74 double angle1 = Geometry.getCornerAngle(p1, p2, intersectionPoint); 75 double angle2 = Geometry.getCornerAngle(p3, p4, intersectionPoint); 76 assertTrue(Math.abs(angle1) < 1e-10, "intersection point not on line, angle: " + angle1); 77 assertTrue(Math.abs(angle1) < 1e-10, "intersection point not on line, angle: " + angle2); 78 79 assertTrue(Math.abs(Math.abs(crossProduct/len1/len2) - 1) < 1e-10, "cross product != 1 : " + Math.abs(crossProduct/len1/len2)); 80 assertTrue(Math.abs(scalarProduct/len1/len2) < 1e-10, "scalar product != 0 : " + scalarProduct/len1/len2); 85 81 } 86 82 … … 96 92 Way closedWay = (Way) SubclassFilteredCollection.filter(ds.allPrimitives(), 97 93 SearchCompiler.compile("landuse=forest")).iterator().next(); 98 Assert.assertEquals(5760015.7353515625, Geometry.closedWayArea(closedWay), 1e-3);99 Assert.assertEquals(5760015.7353515625, Geometry.computeArea(closedWay), 1e-3);94 assertEquals(5760015.7353515625, Geometry.closedWayArea(closedWay), 1e-3); 95 assertEquals(5760015.7353515625, Geometry.computeArea(closedWay), 1e-3); 100 96 } 101 97 } … … 111 107 DataSet ds = OsmReader.parseDataSet(in, null); 112 108 final Relation r = ds.getRelations().iterator().next(); 113 Assert.assertEquals(4401735.20703125, Geometry.multipolygonArea(r), 1e-3);114 Assert.assertEquals(4401735.20703125, Geometry.computeArea(r), 1e-3);109 assertEquals(4401735.20703125, Geometry.multipolygonArea(r), 1e-3); 110 assertEquals(4401735.20703125, Geometry.computeArea(r), 1e-3); 115 111 } 116 112 } … … 128 124 SearchCompiler.compile("landuse=forest")).iterator().next(); 129 125 Geometry.AreaAndPerimeter areaAndPerimeter = Geometry.getAreaAndPerimeter(closedWay.getNodes()); 130 Assert.assertEquals(12495000., areaAndPerimeter.getArea(), 1e-3);131 Assert.assertEquals(15093.201209424187, areaAndPerimeter.getPerimeter(), 1e-3);126 assertEquals(12495000., areaAndPerimeter.getArea(), 1e-3); 127 assertEquals(15093.201209424187, areaAndPerimeter.getPerimeter(), 1e-3); 132 128 } 133 129 } … … 374 370 mp2.put("type", "multipolygon"); 375 371 assertFalse(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp2, null)); 376 assertFalse(Geometry.filterInsideMultipolygon( Arrays.asList(w1), mp2).contains(w1));372 assertFalse(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2).contains(w1)); 377 373 378 374 node4.setCoor(new LatLon(1.006, 0.99)); 379 375 // now w1 is inside 380 376 assertTrue(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp2, null)); 381 assertTrue(Geometry.filterInsideMultipolygon( Arrays.asList(w1), mp2).contains(w1));382 assertTrue(Geometry.filterInsideMultipolygon( Arrays.asList(mp1), mp2).contains(mp1));377 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2).contains(w1)); 378 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(mp1), mp2).contains(mp1)); 383 379 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(w1)); 384 380 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(mp1)); … … 494 490 495 491 Way closestSegment = Geometry.getClosestWaySegment(way1, new Node(new LatLon(0, 0.5))).toWay(); 496 Assert.assertTrue(closestSegment.containsNode(node1));497 Assert.assertTrue(closestSegment.containsNode(node2));492 assertTrue(closestSegment.containsNode(node1)); 493 assertTrue(closestSegment.containsNode(node2)); 498 494 } 499 495
Note:
See TracChangeset
for help on using the changeset viewer.