Ignore:
Timestamp:
2017-06-23T22:52:03+02:00 (7 years ago)
Author:
giackserva
Message:

[pt_assistant] #josm14933 - now supports multiple instances of the roundabout inside the same relation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutAction.java

    r33411 r33413  
    77import java.util.ArrayList;
    88import java.util.Collection;
     9import java.util.Collections;
    910import java.util.HashMap;
    1011import java.util.HashSet;
     
    2122import org.openstreetmap.josm.actions.JosmAction;
    2223import org.openstreetmap.josm.actions.SplitWayAction;
     24import org.openstreetmap.josm.actions.SplitWayAction.SplitWayResult;
    2325import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
    2426import org.openstreetmap.josm.data.Bounds;
     
    3133import org.openstreetmap.josm.data.osm.Way;
    3234import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
     35import org.openstreetmap.josm.tools.Pair;
    3336
    3437/**
     
    9497
    9598        //save the position of the roundabout inside each relation
    96         Map<Relation, Integer> savedPositions = getSavedPositions(roundabout);
     99        Map<Relation, List<Integer>> savedPositions = getSavedPositions(roundabout);
    97100
    98101        //split the roundabout on the designed nodes
    99102        List<Node> splitNodes = getSplitNodes(roundabout);
    100         getLayerManager().getEditDataSet().setSelected(splitNodes);
    101         new SplitWayAction().actionPerformed(null);
    102         Collection<Way> splitWays = getLayerManager().getEditDataSet().getSelectedWays();
     103        SplitWayResult result = SplitWayAction.split(getLayerManager().getEditLayer(),
     104                        roundabout, splitNodes, Collections.emptyList());
     105        result.getCommand().executeCommand();
     106        Collection<Way> splitWays = result.getNewWays();
     107        splitWays.add(result.getOriginalWay());
    103108
    104109        //update the relations.
     
    106111    }
    107112
    108     public void updateRelations(Map<Relation, Integer> savedPositions,
     113    public void updateRelations(Map<Relation, List<Integer>> savedPositions,
    109114            List<Node> splitNodes, Collection<Way> splitWays) {
    110         savedPositions.forEach((r, i) -> {
    111             Way previous = r.getMember(i-1).getWay();
    112             Way subsequent = r.getMember(i).getWay();
    113             Node entryNode;
    114             Node exitNode;
    115 
    116             //checking if the previous way enters the roundabout and the
    117             //subsequent exits it
    118             if(splitNodes.contains(previous.lastNode()))
    119                 entryNode = previous.lastNode();
    120             else if(splitNodes.contains(previous.firstNode()))
    121                 entryNode = previous.firstNode();
    122             else
    123                 entryNode = null;
    124 
    125             if(splitNodes.contains(subsequent.firstNode()))
    126                 exitNode = subsequent.firstNode();
    127             else if (splitNodes.contains(subsequent.lastNode()))
    128                 exitNode = subsequent.lastNode();
    129             else
    130                 exitNode = null;
    131 
    132             //if not, exit
    133             if(entryNode == null || exitNode == null)
    134                 return;
    135 
    136             //starting from the entry node, add split ways until the
    137             //exit node is reached
    138             List<Way> parents = entryNode.getParentWays();
    139             parents.removeIf(w -> !w.firstNode().equals(entryNode));
    140             parents.removeIf(w -> w.equals(previous));
    141 
    142             Way curr = parents.get(0);
    143             int j = 0;
    144 
    145             while(!curr.lastNode().equals(exitNode)) {
    146                 r.addMember(i + j++, new RelationMember(null, curr));
    147                 parents = curr.lastNode().getParentWays();
    148                 parents.remove(curr);
    149                 parents.removeIf(w -> !splitWays.contains(w));
    150                 curr = parents.get(0);
    151             }
    152             r.addMember(i + j++, new RelationMember(null, curr));
    153         });
     115        Map<Relation, Integer> memberOffset = new HashMap<>();
     116        savedPositions.forEach((r, positions) ->
     117                positions.forEach(i -> {
     118
     119                    if(!memberOffset.containsKey(r))
     120                        memberOffset.put(r, 0);
     121                    int offset = memberOffset.get(r);
     122
     123                    Pair<Way, Way> entryExitWays= getEntryExitWays(r, i + offset);
     124                    Way entryWay = entryExitWays.a;
     125                    Way exitWay = entryExitWays.b;
     126
     127                    //get the entry and exit nodes, exit if not found
     128                    Node entryNode = getNodeInCommon(splitNodes, entryWay);
     129                    Node exitNode = getNodeInCommon(splitNodes, exitWay);
     130
     131                    if(entryNode == null || exitNode == null)
     132                        return;
     133
     134                    //starting from the entry node, add split ways until the
     135                    //exit node is reached
     136                    List<Way> parents = entryNode.getParentWays();
     137                    parents.removeIf(w -> !w.firstNode().equals(entryNode));
     138                    parents.removeIf(w -> w.equals(entryWay));
     139
     140                    Way curr = parents.get(0);
     141
     142                    while(!curr.lastNode().equals(exitNode)) {
     143                        r.addMember(i + offset++, new RelationMember(null, curr));
     144                        parents = curr.lastNode().getParentWays();
     145                        parents.remove(curr);
     146                        parents.removeIf(w -> !splitWays.contains(w));
     147                        curr = parents.get(0);
     148                    }
     149                    r.addMember(i + offset++, new RelationMember(null, curr));
     150                    memberOffset.put(r, offset);
     151                }));
     152    }
     153
     154    private Node getNodeInCommon(List<Node> nodes, Way way) {
     155        if(nodes.contains(way.lastNode()))
     156            return way.lastNode();
     157        else if(nodes.contains(way.firstNode()))
     158            return way.firstNode();
     159
     160        return null;
     161    }
     162
     163    //given a relation and the position where the roundabout was, it returns
     164    //the entry and exit ways of that occurrence of the roundabout
     165    private Pair<Way, Way> getEntryExitWays(Relation r, Integer position) {
     166
     167        //the ways returned are the one exactly before and after the roundabout
     168        Pair<Way, Way> ret = new Pair<>(null, null);
     169        ret.a = r.getMember(position-1).getWay();
     170        ret.b = r.getMember(position).getWay();
     171        return ret;
    154172    }
    155173
     
    180198    //save the position of the roundabout inside each public transport route
    181199    //it is contained in
    182     public Map<Relation, Integer> getSavedPositions(Way roundabout) {
    183 
    184         Map<Relation, Integer> savedPositions = new HashMap<>();
     200    public Map<Relation, List<Integer>> getSavedPositions(Way roundabout) {
     201
     202        Map<Relation, List<Integer>> savedPositions = new HashMap<>();
    185203        List <OsmPrimitive> referrers = roundabout.getReferrers();
    186204        referrers.removeIf(r -> r.getType() != OsmPrimitiveType.RELATION
    187205                || !RouteUtils.isTwoDirectionRoute((Relation) r));
     206
    188207        for(OsmPrimitive currPrim : referrers) {
    189208            Relation curr = (Relation) currPrim;
    190209            for(int j = 0; j < curr.getMembersCount(); j++) {
    191210                if(curr.getMember(j).getUniqueId() == roundabout.getUniqueId()) {
    192                     savedPositions.put(curr, j);
    193                     curr.removeMember(j);
    194                     break;
     211                    if(!savedPositions.containsKey(curr))
     212                        savedPositions.put(curr, new ArrayList<>());
     213                        List<Integer> positions = savedPositions.get(curr);
     214                        positions.add(j - positions.size());
    195215                }
    196216            }
     217
     218            if(savedPositions.containsKey(curr))
     219                curr.removeMembersFor(roundabout);
    197220        }
    198221
Note: See TracChangeset for help on using the changeset viewer.