Ignore:
Timestamp:
2017-08-17T11:03:28+02:00 (7 years ago)
Author:
giackserva
Message:

[pt_assistant] #josm15088 - detecting the trivial fix

Location:
applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssistantValidatorTest.java

    r33467 r33502  
    4646    public static final int ERROR_CODE_FROM_TO_ROUTE_TAG = 3701;
    4747    public static final int ERROR_CODE_FIRST_LAST_STOP_WAY_TAG = 3702;
     48    public static final int ERROR_CODE_TRIVIAL_FIX = 3710;
    4849    public static final int ERROR_CODE_SORTING = 3711;
    4950    public static final int ERROR_CODE_PARTIAL_SORTING = 3712;
  • applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java

    r33484 r33502  
    1212import org.openstreetmap.josm.command.ChangeCommand;
    1313import org.openstreetmap.josm.command.Command;
     14import org.openstreetmap.josm.data.osm.Node;
    1415import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1516import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     
    2324import org.openstreetmap.josm.gui.dialogs.relation.sort.RelationSorter;
    2425import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType;
     26import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction;
    2527import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionTypeCalculator;
    2628import org.openstreetmap.josm.plugins.pt_assistant.data.PTRouteDataManager;
     
    2830import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
    2931import org.openstreetmap.josm.plugins.pt_assistant.utils.StopToWayAssigner;
     32import org.openstreetmap.josm.tools.Pair;
    3033
    3134/**
     
    7275        }
    7376
    74         int numOfGaps = countGaps(waysToCheck);
     77        List<Pair<Integer, Pair<Direction, Direction>>> gaps = getGaps(waysToCheck);
     78        int numOfGaps = gaps.size();
    7579
    7680        if (numOfGaps > 0) {
     
    9599                TestError e = builder.build();
    96100                this.errors.add(e);
    97             }
    98         }
     101            } else if (numOfGaps == numOfGapsAfterSort) {
     102                //if sorting doesn't help try to fix the gaps trivially
     103                //by adding one way
     104                for (Pair<Integer, Pair<Direction, Direction>> gap : gaps) {
     105                    Way before = waysToCheck.get(gap.a).getWay();
     106                    Way after = waysToCheck.get(gap.a + 1).getWay();
     107
     108                    Way fix = findTrivialFix(before, gap.b.a, after, gap.b.b);
     109                    if (fix != null) {
     110                        Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_TRIVIAL_FIX);
     111                        builder.message(tr("PT: Route gap can be closed by adding a single way"));
     112                        builder.primitives(relation, before, after, fix);
     113                        TestError e = builder.build();
     114                        this.errors.add(e);
     115                    }
     116                }
     117            }
     118        }
     119    }
     120
     121    //given two ways and the direction of the route on those two ways, it seeks
     122    //another way that connects the two given ones respecting the directions
     123    private Way findTrivialFix(Way before, Direction beforeDirection, Way after, Direction afterDirection) {
     124        Node startNode = beforeDirection == Direction.FORWARD ? before.lastNode() : before.firstNode();
     125        Node lastNode = afterDirection == Direction.FORWARD ? after.firstNode() : after.lastNode();
     126        List<Way> candidates = startNode.getParentWays();
     127        candidates.removeIf(w -> !RouteUtils.isWaySuitableForPublicTransport(w));
     128
     129        for (Way candidate : candidates) {
     130            if (candidate.equals(before)) continue;
     131            if ((candidate.firstNode().equals(startNode) && candidate.lastNode().equals(lastNode))
     132                    || (candidate.lastNode().equals(startNode) && candidate.firstNode().equals(lastNode))) {
     133                return candidate;
     134            }
     135        }
     136
     137        return null;
    99138    }
    100139
     
    222261     *
    223262     * @param waysToCheck ways to check
    224      * @return true if has gap (in the sense of continuity of ways in the
    225      *         Relation Editor), false otherwise
     263     * @return true if has gaps , false otherwise
    226264     */
    227265    public boolean hasGaps(List<RelationMember> waysToCheck) {
     
    230268
    231269    /**
    232      * Counts how many gaps there are for a given list of ways. It does not check if
    233      * the way actually stands for a public transport platform - that should be
    234      * checked beforehand.
     270     * Counts how many gaps there are for a given list of ways.
    235271     *
    236272     * @param waysToCheck ways to check
     
    238274     */
    239275    private int countGaps(List<RelationMember> waysToCheck) {
    240         int numberOfGaps = 0;
     276        return getGaps(waysToCheck).size();
     277    }
     278
     279    /**
     280     * Finds the gaps (in the sense of continuity of ways in the Relation
     281     * Editor) in a given list of ways. It does not check if the way actually
     282     * stands for a public transport platform - that should be checked beforehand.
     283     *
     284     * @param waysToCheck ways to check
     285     * @return It returns a list of gaps. a gap is a pair of an index (the index
     286     * of the way right before the gap) and a pair of directions of the two ways
     287     * around the gap.
     288     */
     289    private List<Pair<Integer, Pair<Direction, Direction>>> getGaps(List<RelationMember> waysToCheck) {
    241290
    242291        WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
    243292        final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
    244         for (int i = 0; i < links.size(); i++) {
    245             final WayConnectionType link = links.get(i);
    246             if (!(i == 0 || link.linkPrev)
    247                     || !(i == links.size() - 1
    248                     || link.linkNext)
    249                     || link.direction == null
    250                     || WayConnectionType.Direction.NONE.equals(link.direction)) {
    251                 numberOfGaps++;
    252                 i++;
    253             }
    254         }
    255 
    256         return numberOfGaps;
     293        List<Pair<Integer, Pair<Direction, Direction>>> gaps = new ArrayList<>();
     294
     295        for (int i = 0; i < links.size() -1; i++) {
     296            WayConnectionType link = links.get(i);
     297            if (!link.linkNext) {
     298                gaps.add(new Pair<>(i, new Pair<>(link.direction, links.get(i+1).direction)));
     299            }
     300        }
     301
     302        return gaps;
    257303    }
    258304
Note: See TracChangeset for help on using the changeset viewer.