Changeset 33411 in osm for applications/editors/josm/plugins/pt_assistant
- Timestamp:
- 2017-06-22T22:57:43+02:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutAction.java
r33409 r33411 40 40 * point to the exit point of the roundabout. 41 41 * 42 * 42 * @author giacomo 43 43 */ 44 44 public class SplitRoundaboutAction extends JosmAction { 45 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 46 private static final String actionName = "Split Roundabout"; 47 private static final long serialVersionUID = 8912249304286025356L; 48 49 /** 50 * Creates a new SplitRoundaboutAction 51 */ 52 public SplitRoundaboutAction() { 53 super(actionName, "icons/splitroundabout", actionName, null, true); 54 } 55 56 @Override 57 public void actionPerformed(ActionEvent e) { 58 59 Way roundabout = (Way) getLayerManager().getEditDataSet().getSelected().iterator().next(); 60 61 //download the bbox around the roundabout 62 DownloadOsmTask task = new DownloadOsmTask(); 63 63 task.setZoomAfterDownload(true); 64 64 BBox rbbox = roundabout.getBBox(); … … 66 66 double lonOffset = (rbbox.getBottomRightLon() - rbbox.getTopLeftLon()) / 10; 67 67 Bounds area = new Bounds( 68 69 70 71 68 rbbox.getBottomRightLat() - latOffset, 69 rbbox.getTopLeftLon() - lonOffset, 70 rbbox.getTopLeftLat() + latOffset, 71 rbbox.getBottomRightLon() + lonOffset); 72 72 Future<?> future = task.download(false, area, null); 73 73 Main.worker.submit(() -> { 74 75 76 77 78 79 80 74 try { 75 future.get(); 76 continueAfterDownload(roundabout); 77 } catch (InterruptedException | ExecutionException e1) { 78 Main.error(e1); 79 return; 80 } 81 81 }); 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 82 } 83 84 private void continueAfterDownload(Way roundabout) 85 { 86 //make the roundabout round, if requested 87 if(Main.pref.getBoolean("pt_assistant.roundabout-splitter.alignalways") || 88 JOptionPane.YES_OPTION == JOptionPane.showOptionDialog(Main.parent, 89 tr("Do you want to make the roundabout round?"), tr("Roundabout round"), 90 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, 91 null, null, null)) { 92 new AlignInCircleAction().actionPerformed(null); 93 } 94 95 //save the position of the roundabout inside each relation 96 Map<Relation, Integer> savedPositions = getSavedPositions(roundabout); 97 97 98 98 //split the roundabout on the designed nodes 99 100 101 102 99 List<Node> splitNodes = getSplitNodes(roundabout); 100 getLayerManager().getEditDataSet().setSelected(splitNodes); 101 new SplitWayAction().actionPerformed(null); 102 Collection<Way> splitWays = getLayerManager().getEditDataSet().getSelectedWays(); 103 103 104 104 //update the relations. 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 105 updateRelations(savedPositions, splitNodes, splitWays); 106 } 107 108 public void updateRelations(Map<Relation, Integer> savedPositions, 109 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 }); 154 } 155 156 //split only on the nodes which might be the 157 //entry or exit point for some public transport route 158 public List<Node> getSplitNodes(Way roundabout) { 159 Set<Node> noDuplicateSplitNodes = new HashSet<>(roundabout.getNodes()); 160 List<Node> splitNodes = new ArrayList<>(noDuplicateSplitNodes); 161 162 splitNodes.removeIf(n -> { 163 List<Way> parents = n.getParentWays(); 164 if(parents.size() == 1) 165 return true; 166 parents.remove(roundabout); 167 for(Way parent: parents) { 168 for(OsmPrimitive prim : parent.getReferrers()) { 169 if(prim.getType() == OsmPrimitiveType.RELATION && 170 RouteUtils.isTwoDirectionRoute((Relation) prim)) 171 return false; 172 } 173 } 174 175 return true; 176 }); 177 return splitNodes; 178 } 179 180 //save the position of the roundabout inside each public transport route 181 //it is contained in 182 public Map<Relation, Integer> getSavedPositions(Way roundabout) { 183 184 Map<Relation, Integer> savedPositions = new HashMap<>(); 185 List <OsmPrimitive> referrers = roundabout.getReferrers(); 186 referrers.removeIf(r -> r.getType() != OsmPrimitiveType.RELATION 187 || !RouteUtils.isTwoDirectionRoute((Relation) r)); 188 for(OsmPrimitive currPrim : referrers) { 189 Relation curr = (Relation) currPrim; 190 for(int j = 0; j < curr.getMembersCount(); j++) { 191 if(curr.getMember(j).getUniqueId() == roundabout.getUniqueId()) { 192 savedPositions.put(curr, j); 193 curr.removeMember(j); 194 break; 195 } 196 } 197 } 198 199 return savedPositions; 200 } 201 202 @Override 203 protected void updateEnabledState( 204 Collection<? extends OsmPrimitive> selection) { 205 205 setEnabled(false); 206 206 if (selection == null || selection.size() != 1) 207 207 return; 208 209 210 208 OsmPrimitive selected = selection.iterator().next(); 209 if(selected.getType() != OsmPrimitiveType.WAY) 210 return; 211 211 if(((Way)selected).isClosed() && selected.hasTag("junction", "roundabout")) { 212 213 212 setEnabled(true); 213 return; 214 214 } 215 215 } 216 216 }
Note:
See TracChangeset
for help on using the changeset viewer.