Changeset 18316 in josm for trunk/src/org


Ignore:
Timestamp:
2021-11-08T09:19:36+01:00 (3 years ago)
Author:
GerdP
Message:

fix #20982: Douglas-Peucker implementation is wrong
The Douglas-Peucker implementation should calculate the distance to the segment between the end nodes, not the distance to the line through those nodes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java

    r18014 r18316  
    3737import org.openstreetmap.josm.data.SystemOfMeasurement;
    3838import org.openstreetmap.josm.data.UndoRedoHandler;
     39import org.openstreetmap.josm.data.coor.EastNorth;
    3940import org.openstreetmap.josm.data.osm.DataSet;
    4041import org.openstreetmap.josm.data.osm.Node;
     
    405406        Node fromN = wnew.get(from);
    406407        Node toN = wnew.get(to);
    407 
     408        EastNorth p1 = fromN.getEastNorth();
     409        EastNorth p2 = toN.getEastNorth();
    408410        // Get max xte
    409411        int imax = -1;
     
    411413        for (int i = from + 1; i < to; i++) {
    412414            Node n = wnew.get(i);
     415            EastNorth p = n.getEastNorth();
     416            double ldx = p2.getX() - p1.getX();
     417            double ldy = p2.getY() - p1.getY();
     418            double offset;
     419            //segment zero length
     420            if (ldx == 0 && ldy == 0)
     421                offset = 0;
     422            else {
     423                double pdx = p.getX() - p1.getX();
     424                double pdy = p.getY() - p1.getY();
     425                offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy);
     426            }
     427            final double distRad;
    413428            // CHECKSTYLE.OFF: SingleSpaceSeparator
    414             double xte = Math.abs(Ellipsoid.WGS84.a
    415                     * xtd(fromN.lat() * Math.PI / 180, fromN.lon() * Math.PI / 180, toN.lat() * Math.PI / 180,
    416                             toN.lon() * Math.PI / 180,     n.lat() * Math.PI / 180,   n.lon() * Math.PI / 180));
     429            if (offset <= 0) {
     430                distRad = dist(fromN.lat() * Math.PI / 180, fromN.lon() * Math.PI / 180,
     431                                   n.lat() * Math.PI / 180,     n.lon() * Math.PI / 180);
     432            } else if (offset >= 1) {
     433                distRad = dist(toN.lat() * Math.PI / 180, toN.lon() * Math.PI / 180,
     434                                 n.lat() * Math.PI / 180,   n.lon() * Math.PI / 180);
     435            } else {
     436                distRad = xtd(fromN.lat() * Math.PI / 180, fromN.lon() * Math.PI / 180,
     437                                toN.lat() * Math.PI / 180,   toN.lon() * Math.PI / 180,
     438                                  n.lat() * Math.PI / 180,     n.lon() * Math.PI / 180);
     439            }
    417440            // CHECKSTYLE.ON: SingleSpaceSeparator
     441            double xte = Math.abs(distRad);
    418442            if (xte > xtemax) {
    419443                xtemax = xte;
     
    421445            }
    422446        }
    423 
    424         if (imax != -1 && xtemax >= threshold) {
     447        if (imax != -1 && Ellipsoid.WGS84.a * xtemax >= threshold) {
    425448            // Segment cannot be simplified - try shorter segments
    426449            buildSimplifiedNodeList(wnew, from, imax, threshold, simplifiedNodes);
Note: See TracChangeset for help on using the changeset viewer.