@Override
    public void end() {
        checkSegment(lonLast, latLast, lonTarget, latTarget);
        if (anyUpdate) {
            for (MatchedWaypoint mwp : waypoints) {
                if (mwp.hasUpdate) {
                    double angle = CheapAngleMeter.getDirection(lonStart, latStart, lonTarget, latTarget);
                    double diff = CheapAngleMeter.getDifferenceFromDirection(mwp.directionToNext, angle);

                    mwp.hasUpdate = false;

                    MatchedWaypoint mw = new MatchedWaypoint();
                    mw.waypoint = new OsmNode();
                    mw.waypoint.ilon = mwp.waypoint.ilon;
                    mw.waypoint.ilat = mwp.waypoint.ilat;
                    mw.crosspoint = new OsmNode();
                    mw.crosspoint.ilon = mwp.crosspoint.ilon;
                    mw.crosspoint.ilat = mwp.crosspoint.ilat;
                    mw.node1 = new OsmNode(lonStart, latStart);
                    mw.node2 = new OsmNode(lonTarget, latTarget);
                    mw.name = mwp.name + "_w_" + mwp.crosspoint.hashCode();
                    mw.radius = mwp.radius;
                    mw.directionDiff = diff;
                    mw.directionToNext = mwp.directionToNext;

                    updateWayList(mwp.wayNearest, mw);

                    // revers
                    angle = CheapAngleMeter.getDirection(lonTarget, latTarget, lonStart, latStart);
                    diff = CheapAngleMeter.getDifferenceFromDirection(mwp.directionToNext, angle);
                    mw = new MatchedWaypoint();
                    mw.waypoint = new OsmNode();
                    mw.waypoint.ilon = mwp.waypoint.ilon;
                    mw.waypoint.ilat = mwp.waypoint.ilat;
                    mw.crosspoint = new OsmNode();
                    mw.crosspoint.ilon = mwp.crosspoint.ilon;
                    mw.crosspoint.ilat = mwp.crosspoint.ilat;
                    mw.node1 = new OsmNode(lonTarget, latTarget);
                    mw.node2 = new OsmNode(lonStart, latStart);
                    mw.name = mwp.name + "_w2_" + mwp.crosspoint.hashCode();
                    mw.radius = mwp.radius;
                    mw.directionDiff = diff;
                    mw.directionToNext = mwp.directionToNext;

                    updateWayList(mwp.wayNearest, mw);

                    final MatchedWaypoint way = mwp.wayNearest.get(0);
                    mwp.crosspoint.ilon = way.crosspoint.ilon;
                    mwp.crosspoint.ilat = way.crosspoint.ilat;
                    mwp.node1 = new OsmNode(way.node1.ilon, way.node1.ilat);
                    mwp.node2 = new OsmNode(way.node2.ilon, way.node2.ilat);
                    mwp.directionDiff = way.directionDiff;
                    mwp.radius = way.radius;

                }
            }
        }
    }
the WaypointMatcher is feeded by the decoder with geoemtries of ways that are
already check for allowed access according to the current routing profile
<p>
It matches these geometries against the list of waypoints to find the best
match for each waypoint
main/src/main/java/cgeo/geocaching/brouter/mapaccess/WaypointMatcherImpl.java