Changeset 18963 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2024-01-30T14:33:14+01:00 (10 months ago)
Author:
taylor.smock
Message:

Fix #23444: NPE in org.openstreetmap.josm.gui.MapViewState$MapViewEastNorthPoint.<init>

This occurs when an incomplete way is loaded into JOSM (by an .osm file, for
example). This is fixed by checking to see if the way is usable (not incomplete,
not deleted, and more importantly for this ticket, no nodes are incomplete).

This additionally fixes some pmd issues and sonarlint issues.

Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

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

    r16438 r18963  
    4444
    4545        if (node != null) {
    46             Optional<Way> candidate = node.referrers(Way.class).findFirst();
     46            Optional<Way> candidate = node.referrers(Way.class).filter(Way::isUsable).findFirst();
    4747            if (candidate.isPresent()) {
    4848                return candidate.get();
     
    7070        EastNorth pEN = mv.getEastNorth(p.x, p.y);
    7171
    72         Double bestDistance = Double.MAX_VALUE;
    73         Double currentDistance;
     72        double bestDistance = Double.MAX_VALUE;
     73        double currentDistance;
    7474        List<Pair<Node, Node>> wpps = w.getNodePairs(false);
    7575
    7676        Node result = null;
    7777
    78         mainLoop:
    7978        for (Node n : w.getNodes()) {
    8079            EastNorth nEN = n.getEastNorth();
     
    8786            currentDistance = pEN.distance(nEN);
    8887
    89             if (currentDistance < bestDistance) {
    90                 // Making sure this candidate is not behind any segment.
    91                 for (Pair<Node, Node> wpp : wpps) {
    92                     if (!wpp.a.equals(n)
    93                             && !wpp.b.equals(n)
    94                             && Geometry.getSegmentSegmentIntersection(
    95                             wpp.a.getEastNorth(), wpp.b.getEastNorth(),
    96                             pEN, nEN) != null) {
    97                         continue mainLoop;
    98                     }
    99                 }
     88            if (currentDistance < bestDistance && ensureCandidateIsNotBehindSegments(wpps, n, pEN, nEN)) {
    10089                result = n;
    10190                bestDistance = currentDistance;
     
    10796
    10897    /**
     98     * Check to see if a candidate node is underneath a way segment
     99     *
     100     * @param wpps The pairs of nodes to check for crossing way segments
     101     * @param n The current node to check
     102     * @param pEN The cursor east-north position
     103     * @param nEN The node east-north position
     104     * @return {@code true} if the candidate node is underneath a way segment
     105     */
     106    private static boolean ensureCandidateIsNotBehindSegments(Iterable<Pair<Node, Node>> wpps, Node n, EastNorth pEN, EastNorth nEN) {
     107        // Making sure this candidate is not behind any segment.
     108        for (Pair<Node, Node> wpp : wpps) {
     109            if (!wpp.a.equals(n)
     110                    && !wpp.b.equals(n)
     111                    && Geometry.getSegmentSegmentIntersection(
     112                    wpp.a.getEastNorth(), wpp.b.getEastNorth(),
     113                    pEN, nEN) != null) {
     114                return false;
     115            }
     116        }
     117        return true;
     118    }
     119
     120    /**
    109121     * Returns the nearest way segment to cursor. The distance to segment ab is
    110122     * the length of altitude from p to ab (say, c) or the minimum distance from
    111123     * p to a or b if c is out of ab.
    112      *
     124     * <p>
    113125     * The priority is given to segments where c is in ab. Otherwise, a segment
    114126     * with the largest angle apb is chosen.
     
    126138        EastNorth pEN = mv.getEastNorth(p.x, p.y);
    127139
    128         Double currentDistance;
    129         Double currentAngle;
    130         Double bestDistance = Double.MAX_VALUE;
    131         Double bestAngle = 0.0;
     140        double bestDistance = Double.MAX_VALUE;
     141        double bestAngle = 0.0;
    132142
    133143        int candidate = -1;
     
    144154            // Finding intersection of the segment with its altitude from p
    145155            EastNorth altitudeIntersection = Geometry.closestPointToSegment(a, b, pEN);
    146             currentDistance = pEN.distance(altitudeIntersection);
     156            final double currentDistance = pEN.distance(altitudeIntersection);
    147157
     158            final double currentAngle;
    148159            if (!altitudeIntersection.equals(a) && !altitudeIntersection.equals(b)) {
    149160                // If the segment intersects with the altitude from p,
  • trunk/src/org/openstreetmap/josm/data/validation/ValidationTask.java

    r18960 r18963  
    112112
    113113    }
     114
    114115    protected ValidationTask(ProgressMonitor progressMonitor,
    115116            Collection<Test> tests,
  • trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java

    r18962 r18963  
    354354        return selection;
    355355    }
     356
    356357    static boolean isCoastline(OsmPrimitive w) {
    357358        return w.hasTag("natural", "water", "coastline") || w.hasTag(LANDUSE, "reservoir");
Note: See TracChangeset for help on using the changeset viewer.