Ticket #22453: 22453.patch

File 22453.patch, 9.1 KB (added by taylor.smock, 3 years ago)
  • src/org/openstreetmap/josm/data/coor/ILatLon.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/coor/ILatLon.java b/src/org/openstreetmap/josm/data/coor/ILatLon.java
    a b  
    143143        }
    144144        return bearing;
    145145    }
     146
     147    /**
     148     * Does a linear interpolation between two ILatLon instances.
     149     * @param ll2 The other ILatLon instance.
     150     * @param proportion The proportion the other instance influences the result.
     151     * @return The new {@link ILatLon} position.
     152     * @since xxx
     153     */
     154    default ILatLon interpolate(ILatLon ll2, double proportion) {
     155        // this is an alternate form of this.lat() + proportion * (ll2.lat() - this.lat()) that is slightly faster
     156        return new LatLon((1 - proportion) * this.lat() + proportion * ll2.lat(),
     157                (1 - proportion) * this.lon() + proportion * ll2.lon());
     158    }
     159
     160    /**
     161     * Returns the square of euclidean distance from this {@code Coordinate} to a specified coordinate.
     162     *
     163     * @param lon the X coordinate of the specified point to be measured against this {@code Coordinate}
     164     * @param lat the Y coordinate of the specified point to be measured against this {@code Coordinate}
     165     * @return the square of the euclidean distance from this {@code Coordinate} to a specified coordinate
     166     * @since xxx
     167     */
     168    default double distanceSq(final double lon, final double lat) {
     169        final double dx = this.lon() - lon;
     170        final double dy = this.lat() - lat;
     171        return dx * dx + dy * dy;
     172    }
     173
     174    /**
     175     * Returns the euclidean distance from this {@code ILatLon} to a specified {@code ILatLon}.
     176     *
     177     * @param other the specified coordinate to be measured against this {@code ILatLon}
     178     * @return the euclidean distance from this {@code ILatLon} to a specified {@code ILatLon}
     179     * @since xxx
     180     */
     181    default double distanceSq(final ILatLon other) {
     182        return this.distanceSq(other.lon(), other.lat());
     183    }
    146184}
  • src/org/openstreetmap/josm/data/coor/LatLon.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/coor/LatLon.java b/src/org/openstreetmap/josm/data/coor/LatLon.java
    a b  
    258258    }
    259259
    260260    /**
    261      * Interpolate between this and a other latlon
     261     * Interpolate between this and a other latlon. If you don't care about the return type, use {@link ILatLon#interpolate(ILatLon, double)}
     262     * instead.
    262263     * @param ll2 The other lat/lon object
    263264     * @param proportion The proportion to interpolate
    264265     * @return a new latlon at this position if proportion is 0, at the other position it proportion is 1 and linearly interpolated otherwise.
    265266     */
    266267    public LatLon interpolate(LatLon ll2, double proportion) {
    267         // this is an alternate form of this.lat() + proportion * (ll2.lat() - this.lat()) that is slightly faster
    268         return new LatLon((1 - proportion) * this.lat() + proportion * ll2.lat(),
    269                 (1 - proportion) * this.lon() + proportion * ll2.lon());
     268        ILatLon interpolated = ILatLon.super.interpolate(ll2, proportion);
     269        if (interpolated instanceof LatLon) {
     270            return (LatLon) interpolated;
     271        }
     272        return new LatLon(interpolated);
    270273    }
    271274
    272275    /**
  • src/org/openstreetmap/josm/tools/Geometry.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/tools/Geometry.java b/src/org/openstreetmap/josm/tools/Geometry.java
    a b  
    502502            return p1.interpolate(p2, offset);
    503503    }
    504504
     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();
     527
     528        double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy);
     529
     530        if (segmentOnly && offset <= 0)
     531            return p1;
     532        else if (segmentOnly && offset >= 1)
     533            return p2;
     534        else
     535            return p1.interpolate(p2, offset);
     536    }
     537
    505538    /**
    506539     * Calculates closest point to a line segment.
    507540     * @param segmentP1 First point determining line segment
     
    15001533            return Double.NaN;
    15011534
    15021535        double smallest = Double.MAX_VALUE;
    1503         EastNorth en0 = node.getEastNorth();
    15041536        // go through the nodes as if they were paired
    15051537        Iterator<Node> iter = way.getNodes().iterator();
    1506         EastNorth en1 = iter.next().getEastNorth();
     1538        Node en1 = iter.next();
    15071539        while (iter.hasNext()) {
    1508             EastNorth en2 = iter.next().getEastNorth();
    1509             double distance = getSegmentNodeDistSq(en1, en2, en0);
     1540            Node en2 = iter.next();
     1541            double distance = getSegmentNodeDistSq(en1, en2, node);
    15101542            if (distance < smallest)
    15111543                smallest = distance;
    15121544            en1 = en2;
     
    15601592        double rValue = Double.MAX_VALUE;
    15611593        Iterator<Node> iter1 = w1.getNodes().iterator();
    15621594        Node w1N1 = iter1.next();
     1595        List<Node> w2Nodes= w2.getNodes();
    15631596        while (iter1.hasNext()) {
    15641597            Node w1N2 = iter1.next();
    1565             Iterator<Node> iter2 = w2.getNodes().iterator();
     1598            Iterator<Node> iter2 = w2Nodes.iterator();
    15661599            Node w2N1 = iter2.next();
    15671600            while (iter2.hasNext()) {
    15681601                Node w2N2 = iter2.next();
     
    16011634     * @since 15035
    16021635     */
    16031636    public static double getDistanceSegmentSegment(Node ws1Node1, Node ws1Node2, Node ws2Node1, Node ws2Node2) {
    1604         EastNorth enWs1Node1 = ws1Node1.getEastNorth();
    1605         EastNorth enWs1Node2 = ws1Node2.getEastNorth();
    1606         EastNorth enWs2Node1 = ws2Node1.getEastNorth();
    1607         EastNorth enWs2Node2 = ws2Node2.getEastNorth();
    1608         if (enWs1Node1 == null || enWs1Node2 == null || enWs2Node1 == null || enWs2Node2 == null)
     1637        if (!ws1Node1.isLatLonKnown() || !ws1Node2.isLatLonKnown() || !ws2Node1.isLatLonKnown() || !ws2Node2.isLatLonKnown()) {
    16091638            return Double.NaN;
    1610         if (getSegmentSegmentIntersection(enWs1Node1, enWs1Node2, enWs2Node1, enWs2Node2) != null)
     1639        }
     1640        if (getSegmentSegmentIntersection(ws1Node1, ws1Node2, ws2Node1, ws2Node2) != null)
    16111641            return 0;
    16121642
    1613         double dist1sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node1);
    1614         double dist2sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node2);
    1615         double dist3sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node1);
    1616         double dist4sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node2);
     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);
    16171647        double smallest = Math.min(Math.min(dist1sq, dist2sq), Math.min(dist3sq, dist4sq));
    16181648        return smallest != Double.MAX_VALUE ? Math.sqrt(smallest) : Double.NaN;
    16191649    }
     
    16481678     * @param p the point
    16491679     * @return the square of the euclidean distance from p to the closest point on the segment
    16501680     */
    1651     private static double getSegmentNodeDistSq(EastNorth s1, EastNorth s2, EastNorth p) {
    1652         EastNorth c1 = closestPointTo(s1, s2, p, true);
    1653         return c1.distanceSq(p);
     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());
    16541684    }
    16551685}