Changeset 32217 in osm for applications/editors/josm/plugins/pt_assistant
- Timestamp:
- 2016-06-04T11:30:23+02:00 (9 years ago)
- Location:
- applications/editors/josm/plugins/pt_assistant
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/GapTest.java
r32209 r32217 6 6 import java.util.List; 7 7 8 import org.openstreetmap.josm.command.ChangeCommand; 9 import org.openstreetmap.josm.command.Command; 10 import org.openstreetmap.josm.command.SequenceCommand; 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 8 12 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 9 13 import org.openstreetmap.josm.data.osm.Relation; 10 14 import org.openstreetmap.josm.data.osm.RelationMember; 15 import org.openstreetmap.josm.data.osm.Way; 11 16 import org.openstreetmap.josm.data.validation.Severity; 12 17 import org.openstreetmap.josm.data.validation.Test; … … 15 20 import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType; 16 21 import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionTypeCalculator; 22 import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils; 17 23 18 24 public class GapTest extends Test { 19 25 20 26 public static final int ERROR_CODE_SORTING = 3711; 21 public static final int ERROR_CODE_OTHER_GAP = 3712; 27 public static final int ERROR_CODE_OVERSHOOT = 3712; 28 public static final int ERROR_CODE_OTHER_GAP = 3719; 29 30 private List<RelationMember> overshootList = new ArrayList<>(); 22 31 23 32 public GapTest() { … … 28 37 public void visit(Relation r) { 29 38 30 if (r.hasKey("route")) { 31 39 if (RouteUtils.isTwoDirectionRoute(r)) { 32 40 List<RelationMember> members = r.getMembers(); 33 41 final List<RelationMember> waysToCheck = new ArrayList<>(); 34 42 for (RelationMember member : members) { 35 43 if (member.hasRole("") && OsmPrimitiveType.WAY.equals(member.getType())) { 36 waysToCheck.add(member); 44 Way way = member.getWay(); 45 if (!way.hasTag("public_transport", "platform") && !way.hasTag("highway", "platform") 46 && !way.hasTag("railway", "platform")) { 47 waysToCheck.add(member); 48 } 37 49 } 38 50 } … … 45 57 RelationSorter sorter = new RelationSorter(); 46 58 List<RelationMember> correctedList = sorter.sortMembers(waysToCheck); 47 if (hasGap(correctedList)) { 48 System.out.println("other error type"); 49 errors.add(new TestError(this, Severity.WARNING, 50 tr("PT: Route contains a gap that cannot be fixed by sorting the ways."), ERROR_CODE_OTHER_GAP, r)); 51 } else { 52 System.out.println("sorting error"); 59 60 if (!hasGap(correctedList)) { 53 61 errors.add(new TestError(this, Severity.WARNING, 54 62 tr("PT: Route contains a gap that can be fixed by sorting"), ERROR_CODE_SORTING, r)); 55 } 63 } else { 64 List<RelationMember> overshoots = this.getOvershoots(correctedList); 65 if (!overshoots.isEmpty()) { 66 // TODO: make sure that duplicates are removed first 67 overshootList = overshoots; 68 errors.add(new TestError(this, Severity.WARNING, tr("PT: Route contains an overshoot"), 69 ERROR_CODE_OVERSHOOT, r)); 70 } else { 71 errors.add(new TestError(this, Severity.WARNING, 72 tr("PT: Route contains a gap that cannot be fixed by sorting the ways"), 73 ERROR_CODE_OTHER_GAP, r)); 74 } 75 } 76 56 77 } 57 78 … … 82 103 } 83 104 105 /** 106 * Checks if there is a single "hanging" way (perhaps left after a way 107 * split) that can be easily removed. 108 * 109 * @param sortedWays 110 * is a list of ways only that should be sorted with the 111 * RelationSorter before this method is called. No error occurs 112 * if they are unsorted, but the method call is pointless if they 113 * are in a wrong order. 114 * @return true is there is such a way, false otherwise 115 */ 116 private List<RelationMember> getOvershoots(List<RelationMember> sortedWays) { 117 118 List<RelationMember> overshoots = new ArrayList<>(); 119 120 if (sortedWays.size() < 5) { 121 // the route has to have at least five ways to be able to have an 122 // overshoot. I assume that the overshoot cannot touch the very 123 // first or the very last way in a route because then it would not 124 // be clear which of the ways would be an overshoot. 125 /*- 126 * x x x 127 * \ A |D / G 128 * \ | / 129 * x-----------x----------x 130 * / C | F \ 131 * / B |E \ H 132 * x x x 133 * 134 * Example: ways D and E can be overshoots (from the point of 135 * view of this method), but ways A, B, G and H cannot. 136 * Therefore, a relation must have at least 4 "good" ways 137 * in order to be able to have an overshoot. 138 */ 139 140 return overshoots; 141 } 142 143 for (int i = 2; i < sortedWays.size() - 3; i++) { 144 Way prev = sortedWays.get(i - 1).getWay(); 145 Way curr = sortedWays.get(i).getWay(); 146 Way next = sortedWays.get(i + 1).getWay(); 147 boolean firstNodeConnectedToPrev = (curr.firstNode() == prev.firstNode() 148 || curr.firstNode() == prev.lastNode()); 149 boolean lastNodeConnectedToPrev = (curr.lastNode() == prev.firstNode() 150 || curr.lastNode() == prev.lastNode()); 151 boolean firstNodeConnectedToNext = (curr.firstNode() == next.firstNode() 152 || curr.firstNode() == next.lastNode()); 153 boolean lastNodeConnectedToNext = (curr.lastNode() == next.firstNode() 154 || curr.lastNode() == next.lastNode()); 155 if ((firstNodeConnectedToPrev && firstNodeConnectedToNext) 156 || (lastNodeConnectedToPrev && lastNodeConnectedToNext)) { 157 overshoots.add(sortedWays.get(i)); 158 } 159 160 } 161 162 return overshoots; 163 } 164 165 @Override 166 public Command fixError(TestError testError) { 167 168 List<Command> commands = new ArrayList<>(50); 169 170 if (testError.getTester().getClass().equals(GapTest.class) && testError.isFixable()) { 171 172 // If this is an error that can be fixed simply by sorting the ways: 173 if (testError.getCode() == ERROR_CODE_SORTING) { 174 for (OsmPrimitive primitive : testError.getPrimitives()) { 175 Relation relation = (Relation) primitive; 176 // separate ways from stops (because otherwise the order of 177 // stops/platforms can be messed up by the sorter: 178 List<RelationMember> members = relation.getMembers(); 179 final List<RelationMember> stops = new ArrayList<>(); 180 final List<RelationMember> ways = new ArrayList<>(); 181 for (RelationMember member : members) { 182 if (member.hasRole("") && OsmPrimitiveType.WAY.equals(member.getType())) { 183 ways.add(member); 184 } else { // stops (and if the relation has anything 185 // besides ways and stops: 186 stops.add(member); 187 } 188 } 189 190 // sort the ways: 191 RelationSorter sorter = new RelationSorter(); 192 List<RelationMember> sortedWays = sorter.sortMembers(ways); 193 194 // create a new relation to pass to the command: 195 Relation sortedRelation = new Relation(relation); 196 List<RelationMember> sortedRelationMembers = new ArrayList<>(members.size()); 197 for (RelationMember rm : stops) { 198 sortedRelationMembers.add(rm); 199 } 200 for (RelationMember rm : sortedWays) { 201 sortedRelationMembers.add(rm); 202 } 203 sortedRelation.setMembers(sortedRelationMembers); 204 205 ChangeCommand changeCommand = new ChangeCommand(relation, sortedRelation); 206 207 commands.add(changeCommand); 208 209 } 210 211 } 212 213 // if the error is a single overshoot: 214 if (testError.getCode() == ERROR_CODE_OVERSHOOT) { 215 // commands.add(testError.getFix()); 216 for (OsmPrimitive primitive : testError.getPrimitives()) { 217 Relation originalRelation = (Relation) primitive; 218 Relation modifiedRelation = new Relation(originalRelation); 219 List<RelationMember> modifiedMembers = new ArrayList<>(); 220 for (RelationMember rm : originalRelation.getMembers()) { 221 if (rm.getType().equals(OsmPrimitiveType.WAY) && !overshootList.contains(rm)) { 222 modifiedMembers.add(rm); 223 } 224 } 225 modifiedRelation.setMembers(modifiedMembers); 226 227 ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation); 228 commands.add(changeCommand); 229 } 230 231 } 232 } 233 234 if (commands.isEmpty()) { 235 return null; 236 } 237 238 if (commands.size() == 1) { 239 return commands.get(0); 240 } 241 242 return new SequenceCommand(tr("Fix gaps in public transport route"), commands); 243 244 } 245 246 /** 247 * Checks if the test error is fixable 248 */ 249 @Override 250 public boolean isFixable(TestError testError) { 251 if (testError.getCode() == ERROR_CODE_SORTING || testError.getCode() == ERROR_CODE_OVERSHOOT) { 252 return true; 253 } 254 return false; 255 } 84 256 85 257 }
Note:
See TracChangeset
for help on using the changeset viewer.