Ticket #10682: PT.diff
| File PT.diff, 21.3 KB (added by , 11 years ago) |
|---|
-
relcontext/RelContextDialog.java
88 88 import relcontext.actions.EditChosenRelationAction; 89 89 import relcontext.actions.FindRelationAction; 90 90 import relcontext.actions.ReconstructPolygonAction; 91 import relcontext.actions.ReconstructRouteAction; 91 92 import relcontext.actions.RelationHelpAction; 92 93 import relcontext.actions.SelectInRelationPanelAction; 93 94 import relcontext.actions.SelectMembersAction; … … 423 424 424 425 private static Map<String, List<String>> loadRoles() { 425 426 Map<String, List<String>> result = new HashMap<>(); 427 426 428 ClassLoader classLoader = RelContextDialog.class.getClassLoader(); 427 429 try ( 428 430 InputStream possibleRolesStream = classLoader.getResourceAsStream(POSSIBLE_ROLES_FILE); … … 525 527 add(new DeleteChosenRelationAction(chosenRelation)); 526 528 add(new DownloadParentsAction(chosenRelation)); 527 529 add(new ReconstructPolygonAction(chosenRelation)); 530 add(new ReconstructRouteAction(chosenRelation)); 528 531 addSeparator(); 529 532 add(new SelectInRelationPanelAction(chosenRelation)); 530 533 add(new RelationHelpAction(chosenRelation)); -
relcontext/actions/PublicTransportHelper.java
1 package relcontext.actions; 2 3 import org.openstreetmap.josm.data.osm.Node; 4 import org.openstreetmap.josm.data.osm.OsmPrimitive; 5 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 6 import org.openstreetmap.josm.data.osm.RelationMember; 7 import org.openstreetmap.josm.data.osm.Way; 8 9 /** 10 * @see http://wiki.openstreetmap.org/wiki/Key:public_transport 11 */ 12 13 /** 14 * 15 * @author freeExec 16 */ 17 public final class PublicTransportHelper { 18 19 public final static String PUBLIC_TRANSPORT = "public_transport"; 20 public final static String STOP_POSITION = "stop_position"; 21 public final static String STOP = "stop"; 22 public final static String STOP_AREA = "stop_area"; 23 public final static String PLATFORM = "platform"; 24 public final static String HIGHWAY = "highway"; 25 public final static String RAILWAY = "railway"; 26 public final static String BUS_STOP = "bus_stop"; 27 public final static String RAILWAY_HALT = "halt"; 28 public final static String RAILWAY_STATION = "station"; 29 30 private PublicTransportHelper() { 31 // Hide default constructor for utils classes 32 } 33 34 public static String getRoleByMember(RelationMember m) { 35 if (isMemberStop(m)) return STOP; 36 else if (isMemberPlatform(m)) return PLATFORM; 37 return null; 38 } 39 40 public static boolean isMemberStop(RelationMember m) { 41 return isNodeStop(m); // stop is only node 42 } 43 44 public static boolean isMemberPlatform(RelationMember m) { 45 return isNodePlatform(m) || isWayPlatform(m); 46 } 47 48 public static boolean isNodeStop(RelationMember m) { 49 return isNodeStop(m.getMember()); 50 } 51 52 public static boolean isNodeStop(OsmPrimitive p) { 53 if (p.getType() == OsmPrimitiveType.NODE && !p.isIncomplete()) { 54 if (p.hasKey(PUBLIC_TRANSPORT)) { 55 String pt = p.get(PUBLIC_TRANSPORT); 56 if (STOP_POSITION.equals(pt)) return true; 57 } 58 else if (p.hasKey(RAILWAY)) { 59 String rw = p.get(RAILWAY); 60 if (RAILWAY_HALT.equals(rw) || RAILWAY_STATION.equals(rw)) return true; 61 } 62 } 63 return false; 64 } 65 66 public static boolean isNodePlatform(RelationMember m) { 67 return isNodePlatform(m.getMember()); 68 } 69 70 public static boolean isNodePlatform(OsmPrimitive p) { 71 if (p.getType() == OsmPrimitiveType.NODE && !p.isIncomplete()) { 72 if (p.hasKey(PUBLIC_TRANSPORT)) { 73 String pt = p.get(PUBLIC_TRANSPORT); 74 if (PLATFORM.equals(pt)) return true; 75 } else if (p.hasKey(HIGHWAY)) { 76 String hw = p.get(HIGHWAY); 77 if (BUS_STOP.equals(hw)) return true; 78 else if (PLATFORM.equals(hw)) return true; 79 } else if (p.hasKey(RAILWAY)) { 80 String rw = p.get(RAILWAY); 81 if (PLATFORM.equals(rw)) return true; 82 } 83 } 84 return false; 85 } 86 public static boolean isWayPlatform(RelationMember m) { 87 return isWayPlatform(m.getMember()); 88 } 89 90 public static boolean isWayPlatform(OsmPrimitive p) { 91 if (p.getType() == OsmPrimitiveType.WAY && !p.isIncomplete()) { 92 if (p.hasKey(PUBLIC_TRANSPORT)) { 93 String pt = p.get(PUBLIC_TRANSPORT); 94 if (PLATFORM.equals(pt)) return true; 95 } else if (p.hasKey(HIGHWAY)) { 96 String hw = p.get(HIGHWAY); 97 if (PLATFORM.equals(hw)) return true; 98 } else if (p.hasKey(RAILWAY)) { 99 String rw = p.get(RAILWAY); 100 if (PLATFORM.equals(rw)) return true; 101 } 102 } 103 return false; 104 } 105 106 public static boolean isMemberRouteway(RelationMember m) { 107 return isWayRouteway(m.getMember()); 108 } 109 110 public static boolean isWayRouteway(OsmPrimitive p) { 111 if (p.getType() == OsmPrimitiveType.WAY && !p.isIncomplete()) { 112 return p.hasKey(HIGHWAY) || p.hasKey(RAILWAY); 113 } 114 return false; 115 } 116 117 public static String getNameViaStoparea(RelationMember m) { 118 return getNameViaStoparea(m.getMember()); 119 } 120 121 public static String getNameViaStoparea(OsmPrimitive prim) { 122 String result = prim.getName(); 123 if (result != null) return result; 124 // try to get name by stop_area 125 for (OsmPrimitive refOp : prim.getReferrers()) 126 if (refOp.getType() == OsmPrimitiveType.RELATION 127 && refOp.hasTag(PUBLIC_TRANSPORT, STOP_AREA)) { 128 result = refOp.getName(); 129 if (result != null) return result; 130 } 131 return result; 132 } 133 } -
relcontext/actions/ReconstructRouteAction.java
1 package relcontext.actions; 2 3 import java.awt.event.ActionEvent; 4 import java.util.ArrayList; 5 import java.util.LinkedHashMap; 6 import java.util.List; 7 import java.util.Map; 8 import javax.swing.AbstractAction; 9 import static javax.swing.Action.LONG_DESCRIPTION; 10 import static javax.swing.Action.SMALL_ICON; 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.command.ChangeCommand; 13 import org.openstreetmap.josm.command.Command; 14 import org.openstreetmap.josm.data.coor.EastNorth; 15 import org.openstreetmap.josm.data.osm.Node; 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 18 import org.openstreetmap.josm.data.osm.Relation; 19 import org.openstreetmap.josm.data.osm.RelationMember; 20 import org.openstreetmap.josm.data.osm.Way; 21 import org.openstreetmap.josm.gui.dialogs.relation.sort.RelationSorter; 22 import org.openstreetmap.josm.tools.Geometry; 23 import static org.openstreetmap.josm.tools.I18n.tr; 24 import org.openstreetmap.josm.tools.ImageProvider; 25 import relcontext.ChosenRelation; 26 import relcontext.ChosenRelationListener; 27 28 /** 29 * Build in order stop/platforms, stop/platforms ... route 30 * @author freeExec 31 */ 32 public class ReconstructRouteAction extends AbstractAction implements ChosenRelationListener { 33 private final ChosenRelation rel; 34 35 public ReconstructRouteAction (ChosenRelation rel) { 36 super(tr("Reconstruct route")); 37 putValue(SMALL_ICON, ImageProvider.get("dialogs", "filter")); 38 putValue(LONG_DESCRIPTION, "Reconstruct route relation to scheme of public_transport"); 39 this.rel = rel; 40 rel.addChosenRelationListener(this); 41 setEnabled(isSuitableRelation(rel.get())); 42 } 43 44 public void actionPerformed( ActionEvent e ) { 45 Relation r = rel.get(); 46 Relation recRel = new Relation(r); 47 recRel.removeMembersFor(recRel.getMemberPrimitives()); 48 49 Map<OsmPrimitive, RelationMember> stopMembers = new LinkedHashMap<>(); 50 Map<String, List<RelationMember>> platformMembers = new LinkedHashMap<>(); 51 52 List<RelationMember> routeMembers = new ArrayList<>(); 53 List<RelationMember> wtfMembers = new ArrayList<>(); 54 55 int mCount = r.getMembersCount(); 56 for (int i = 0; i < mCount; i++) { 57 RelationMember m = r.getMember(i); 58 if (PublicTransportHelper.isMemberStop(m)) { 59 RelationMember rm = new RelationMember( 60 m.hasRole() ? m.getRole() : PublicTransportHelper.STOP, 61 m.getMember()); 62 stopMembers.put(rm.getMember(), rm); 63 } 64 else if (PublicTransportHelper.isMemberPlatform(m)) { 65 RelationMember rm = new RelationMember( 66 m.hasRole() ? m.getRole() : PublicTransportHelper.PLATFORM, 67 m.getMember()); 68 String platformName = PublicTransportHelper.getNameViaStoparea(rm); 69 if (platformName == null) platformName = ""; 70 if (platformMembers.containsKey(platformName)) platformMembers.get(platformName).add(rm); 71 else { 72 List<RelationMember> nList = new ArrayList<>(); 73 nList.add(rm); 74 platformMembers.put(platformName, nList); 75 } 76 } 77 else if (PublicTransportHelper.isMemberRouteway(m)) routeMembers.add(new RelationMember(m)); 78 else wtfMembers.add(new RelationMember(m)); 79 } 80 81 routeMembers = RelationSorter.sortMembersByConnectivity(routeMembers); 82 83 Node lastNode = null; 84 for (int rIndex = 0; rIndex < routeMembers.size(); rIndex++) { 85 Way w = (Way)routeMembers.get(rIndex).getMember(); 86 boolean dirForward = false; 87 if (lastNode == null) { // first segment 88 if (routeMembers.size() > 2) { 89 Way nextWay = (Way)routeMembers.get(rIndex + 1).getMember(); 90 if (w.lastNode().equals(nextWay.lastNode()) || w.lastNode().equals(nextWay.firstNode())) { 91 dirForward = true; 92 lastNode = w.lastNode(); 93 } else lastNode = w.firstNode(); 94 } // else one segment - direction unknown 95 } else { 96 if (lastNode.equals(w.firstNode())) { dirForward = true; lastNode = w.lastNode(); } 97 else lastNode = w.firstNode(); 98 } 99 final int wayNodeBeginIndex = (dirForward ? 0 : w.getNodesCount() - 1); 100 final int wayNodeEndIndex = (dirForward ? w.getNodesCount() - 1 : 0); 101 final int increment = (dirForward ? 1 : -1); 102 for(int nIndex = wayNodeBeginIndex; 103 nIndex != wayNodeEndIndex; 104 nIndex += increment) { 105 Node refNode = w.getNode(nIndex); 106 if (PublicTransportHelper.isNodeStop(refNode)) { 107 if (stopMembers.containsKey(refNode)) { 108 recRel.addMember(stopMembers.get(refNode)); 109 stopMembers.remove(refNode); 110 String stopName = PublicTransportHelper.getNameViaStoparea(refNode); 111 if (stopName == null) stopName = ""; 112 boolean existsPlatform = platformMembers.containsKey(stopName); 113 if (!existsPlatform) { stopName = ""; } // find of the nameless 114 if (existsPlatform || platformMembers.containsKey(stopName)) { 115 List<RelationMember> lMember = platformMembers.get(stopName); 116 if (lMember.size() == 1) { 117 recRel.addMember(lMember.get(0)); 118 lMember.remove(0); 119 } else { 120 // choose closest 121 RelationMember candidat = getClosestPlatform(lMember, refNode); 122 if (candidat != null) { 123 recRel.addMember(candidat); 124 lMember.remove(candidat); 125 } 126 } 127 if (lMember.isEmpty()) platformMembers.remove(stopName); 128 } 129 } 130 } 131 } 132 } 133 134 for (RelationMember stop : stopMembers.values()) { 135 recRel.addMember(stop); 136 String stopName = PublicTransportHelper.getNameViaStoparea(stop); 137 boolean existsPlatform = platformMembers.containsKey(stopName); 138 if (!existsPlatform) { stopName = ""; } // find of the nameless 139 if (existsPlatform || platformMembers.containsKey(stopName)) { 140 List<RelationMember> lMember = platformMembers.get(stopName); 141 if (lMember.size() == 1) { 142 recRel.addMember(lMember.get(0)); 143 lMember.remove(0); 144 } else { 145 // choose closest 146 RelationMember candidat = getClosestPlatform(lMember, stop.getNode()); 147 if (candidat != null) { 148 recRel.addMember(candidat); 149 lMember.remove(candidat); 150 } 151 } 152 if (lMember.isEmpty()) platformMembers.remove(stopName); 153 } 154 } 155 156 for (List<RelationMember> lPlatforms : platformMembers.values()) 157 for (RelationMember platform : lPlatforms) 158 recRel.addMember(platform); 159 160 for (RelationMember route : routeMembers) 161 recRel.addMember(route); 162 for (RelationMember wtf : wtfMembers) 163 recRel.addMember(wtf); 164 Command command = new ChangeCommand(r, recRel); 165 Main.main.undoRedo.add(command); 166 } 167 168 private static final double maxSqrDistBetweenStopAndPlatform = 2000; // ~ 26m 169 private RelationMember getClosestPlatform(List<RelationMember> members, Node stop) { 170 if (stop == null || members.isEmpty()) return null; 171 double maxDist = maxSqrDistBetweenStopAndPlatform; 172 RelationMember result = null; 173 for (RelationMember member : members) { 174 if (member.getType() == OsmPrimitiveType.NODE) { 175 Node node = member.getNode(); 176 double sqrDist = stop.getEastNorth().distanceSq(node.getEastNorth()); 177 if (sqrDist < maxDist) { 178 maxDist = sqrDist; 179 result = member; 180 } 181 } else if (member.getType() == OsmPrimitiveType.WAY) { 182 Way way = member.getWay(); 183 EastNorth closest = Geometry.closestPointToSegment( 184 way.firstNode().getEastNorth(), 185 way.lastNode().getEastNorth(), 186 stop.getEastNorth() 187 ); 188 double sqrDist = stop.getEastNorth().distanceSq(closest); 189 if (sqrDist < maxDist) { 190 maxDist = sqrDist; 191 result = member; 192 } 193 } 194 } 195 return result; 196 } 197 198 public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) { 199 setEnabled(isSuitableRelation(newRelation)); 200 } 201 202 private boolean isSuitableRelation (Relation newRelation) { 203 return !(newRelation == null || !"route".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0); 204 } 205 } -
relcontext/actions/SortAndFixAction.java
21 21 import relcontext.relationfix.BoundaryFixer; 22 22 import relcontext.relationfix.MultipolygonFixer; 23 23 import relcontext.relationfix.NothingFixer; 24 import relcontext.relationfix.PublicTransportFixer; 24 25 import relcontext.relationfix.RelationFixer; 25 26 26 27 public class SortAndFixAction extends AbstractAction implements ChosenRelationListener { … … 43 44 fixers.add(new BoundaryFixer()); // boundary, multipolygon, boundary=administrative 44 45 fixers.add(new MultipolygonFixer()); // multipolygon 45 46 fixers.add(new AssociatedStreetFixer()); //associatedStreet 47 fixers.add(new PublicTransportFixer()); //public_transport 46 48 47 49 for(RelationFixer fix : fixers) { 48 50 fix.setFixAction(this); -
relcontext/possible_roles.txt
1 1 boundary: admin_centre, label, subarea 2 route: stop, platform, forward, backward, stop_exit_only, stop_entry_only, platform_exit_only, platform_entry_only 2 route: forward, backward, stop, platform, stop_exit_only, stop_entry_only, platform_exit_only, platform_entry_only 3 public_transport: stop, platform 3 4 restriction: from, to, via, location_hint 4 5 enforcement: device, from, to, force 5 6 destination_sign: to, from, intersection, sign -
relcontext/relationfix/PublicTransportFixer.java
1 package relcontext.relationfix; 2 3 import org.openstreetmap.josm.command.ChangeCommand; 4 import org.openstreetmap.josm.command.Command; 5 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 6 import org.openstreetmap.josm.data.osm.Relation; 7 import org.openstreetmap.josm.data.osm.RelationMember; 8 import static org.openstreetmap.josm.tools.I18n.tr; 9 import relcontext.actions.PublicTransportHelper; 10 11 /** 12 * @see http://wiki.openstreetmap.org/wiki/Key:public_transport 13 */ 14 15 /** 16 * Helper function for determinate role in public_transport relation 17 * @author freeExec 18 */ 19 public class PublicTransportFixer extends RelationFixer { 20 21 public PublicTransportFixer() { 22 super("route", "public_transport"); 23 } 24 25 /*protected PublicTransportFixer(String...types) { 26 super(types); 27 }*/ 28 29 @Override 30 public boolean isRelationGood(Relation rel) { 31 for (RelationMember m : rel.getMembers()) { 32 if (m.getType().equals(OsmPrimitiveType.NODE) 33 && !(m.getRole().startsWith(PublicTransportHelper.STOP) || m.getRole().startsWith(PublicTransportHelper.PLATFORM))) { 34 setWarningMessage(tr("Node without ''stop'' or ''platform'' role found")); 35 return false; 36 } 37 if (m.getType().equals(OsmPrimitiveType.WAY) 38 && PublicTransportHelper.isWayPlatform(m) 39 && !m.getRole().startsWith(PublicTransportHelper.PLATFORM)) { 40 setWarningMessage(tr("Way platform without ''platform'' role found") + " r" + m.getUniqueId()); 41 return false; 42 } 43 } 44 clearWarningMessage(); 45 return true; 46 } 47 48 /*@Override 49 public boolean isFixerApplicable(Relation rel) { 50 return true; 51 }*/ 52 53 @Override 54 public Command fixRelation(Relation rel) { 55 Relation r = rel; 56 Relation rr = fixStopPlatformRole(r); 57 boolean fixed = false; 58 if (rr != null) { 59 fixed = true; 60 r = rr; 61 } 62 return fixed ? new ChangeCommand(rel, r) : null; 63 } 64 65 private Relation fixStopPlatformRole(Relation source) { 66 Relation r = new Relation(source); 67 boolean fixed = false; 68 for( int i = 0; i < r.getMembersCount(); i++ ) { 69 RelationMember m = r.getMember(i); 70 String role = PublicTransportHelper.getRoleByMember(m); 71 72 if (role != null && !m.getRole().startsWith(role)) { 73 r.setMember(i, new RelationMember(role, m.getMember())); 74 fixed = true; 75 } 76 } 77 return fixed ? r : null; 78 } 79 }
