Changeset 18590 in josm for trunk


Ignore:
Timestamp:
2022-11-08T21:50:55+01:00 (2 years ago)
Author:
taylor.smock
Message:

See #22453: Decrease allocations/CPU samples in Geometry.getDistanceSegmentSegment

This mostly reverts r18589, as it changed the distances returned to LatLon space,
which caused tests to fail.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/Geometry.java

    r18589 r18590  
    492492        double pdx = point.getX() - p1.getX();
    493493        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         else
    502             return p1.interpolate(p2, offset);
    503     }
    504 
    505     /**
    506      * Get the closest point to a segment
    507      * @param p1 Point 1 of the segment
    508      * @param p2 Point 2 of the segment
    509      * @param point The point to use to get the closest point on the segment
    510      * @param segmentOnly {@code true} if the point <i>must</i> be on the segment
    511      * @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 length
    522         if (ldx == 0 && ldy == 0)
    523             return p1;
    524 
    525         double pdx = point.lon() - p1.lon();
    526         double pdy = point.lat() - p1.lat();
    527494
    528495        double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy);
     
    15341501
    15351502        double smallest = Double.MAX_VALUE;
     1503        EastNorth en0 = node.getEastNorth();
    15361504        // go through the nodes as if they were paired
    15371505        Iterator<Node> iter = way.getNodes().iterator();
    1538         Node en1 = iter.next();
     1506        EastNorth en1 = iter.next().getEastNorth();
    15391507        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);
    15421510            if (distance < smallest)
    15431511                smallest = distance;
     
    15921560        double rValue = Double.MAX_VALUE;
    15931561        Iterator<Node> iter1 = w1.getNodes().iterator();
     1562        List<Node> w2Nodes = w2.getNodes();
    15941563        Node w1N1 = iter1.next();
    1595         List<Node> w2Nodes = w2.getNodes();
    15961564        while (iter1.hasNext()) {
    15971565            Node w1N2 = iter1.next();
     
    16381606            return Double.NaN;
    16391607        }
    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)
    16411613            return 0;
    16421614
    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);
    16471619        double smallest = Math.min(Math.min(dist1sq, dist2sq), Math.min(dist3sq, dist4sq));
    16481620        return smallest != Double.MAX_VALUE ? Math.sqrt(smallest) : Double.NaN;
     
    16791651     * @return the square of the euclidean distance from p to the closest point on the segment
    16801652     */
    1681     private static double getSegmentNodeDistSq(ILatLon s1, ILatLon s2, ILatLon p) {
    1682         ILatLon c1 = 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);
    16841656    }
    16851657}
  • trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java

    r18589 r18590  
    55import static org.junit.jupiter.api.Assertions.assertFalse;
    66import static org.junit.jupiter.api.Assertions.assertNotEquals;
     7import static org.junit.jupiter.api.Assertions.assertNotNull;
    78import static org.junit.jupiter.api.Assertions.assertTrue;
    89
     
    1718import java.util.stream.Stream;
    1819
    19 import org.junit.Assert;
     20import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
    2021import org.junit.jupiter.api.Test;
    2122import org.junit.jupiter.api.extension.RegisterExtension;
     
    4041import org.openstreetmap.josm.testutils.JOSMTestRules;
    4142
    42 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
    43 
    4443/**
    4544 * Unit tests of {@link Geometry} class.
     
    5150    @RegisterExtension
    5251    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    53     public JOSMTestRules test = new JOSMTestRules().preferences().projection();
     52    static JOSMTestRules test = new JOSMTestRules().preferences().projection();
    5453
    5554    /**
     
    6564        EastNorth intersectionPoint = Geometry.getLineLineIntersection(p1, p2, p3, p4);
    6665
     66        assertNotNull(intersectionPoint);
    6767        EastNorth d1 = p3.subtract(intersectionPoint);
    6868        EastNorth d2 = p1.subtract(p2);
     
    7272        Double len2 = d2.length();
    7373
    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);
    8581    }
    8682
     
    9692            Way closedWay = (Way) SubclassFilteredCollection.filter(ds.allPrimitives(),
    9793                    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);
    10096        }
    10197    }
     
    111107            DataSet ds = OsmReader.parseDataSet(in, null);
    112108            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);
    115111        }
    116112    }
     
    128124                    SearchCompiler.compile("landuse=forest")).iterator().next();
    129125            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);
    132128        }
    133129    }
     
    374370        mp2.put("type", "multipolygon");
    375371        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));
    377373
    378374        node4.setCoor(new LatLon(1.006, 0.99));
    379375        // now w1 is inside
    380376        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));
    383379        assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(w1));
    384380        assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(mp1));
     
    494490
    495491        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));
    498494    }
    499495
Note: See TracChangeset for help on using the changeset viewer.