Index: trunk/src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 15359)
+++ trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 15361)
@@ -12,4 +12,5 @@
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor;
@@ -540,12 +541,5 @@
      */
     public Set<String> getMemberRoles() {
-        Set<String> result = new HashSet<>();
-        for (RelationMember rm : members) {
-            String role = rm.getRole();
-            if (!role.isEmpty()) {
-                result.add(role);
-            }
-        }
-        return result;
+        return Stream.of(members).map(RelationMember::getRole).filter(role -> !role.isEmpty()).collect(Collectors.toSet());
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 15359)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 15361)
@@ -5,4 +5,5 @@
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -11,4 +12,5 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
@@ -26,5 +28,5 @@
 
     private interface AdditionalSorter {
-        boolean acceptsMember(RelationMember m);
+        boolean acceptsMember(List<RelationMember> relationMembers, RelationMember m);
 
         List<RelationMember> sortMembers(List<RelationMember> list);
@@ -35,5 +37,6 @@
         new AssociatedStreetRoleStreetSorter(),
         new AssociatedStreetRoleAddressHouseSorter(),
-        new PublicTransportRoleStopPlatformSorter()
+        new PublicTransportRoleStopPlatformSorter(),
+        new FromViaToSorter()
     );
 
@@ -45,5 +48,5 @@
 
         @Override
-        public boolean acceptsMember(RelationMember m) {
+        public boolean acceptsMember(List<RelationMember> relationMembers, RelationMember m) {
             return "street".equals(m.getRole());
         }
@@ -62,5 +65,5 @@
 
         @Override
-        public boolean acceptsMember(RelationMember m) {
+        public boolean acceptsMember(List<RelationMember> relationMembers, RelationMember m) {
             return "address".equals(m.getRole()) || "house".equals(m.getRole());
         }
@@ -90,5 +93,5 @@
 
         @Override
-        public boolean acceptsMember(RelationMember m) {
+        public boolean acceptsMember(List<RelationMember> relationMembers, RelationMember m) {
             return m.getRole() != null && (m.getRole().startsWith("platform") || m.getRole().startsWith("stop"));
         }
@@ -133,4 +136,25 @@
 
     /**
+     * Class that sorts the {@code from}, {@code via} and {@code to} members of
+     * {@code type=restriction} relations.
+     */
+    private static class FromViaToSorter implements AdditionalSorter {
+
+        private static final List<String> ROLES = Arrays.asList("from", "via", "to");
+
+        @Override
+        public boolean acceptsMember(List<RelationMember> relationMembers, RelationMember m) {
+            return ROLES.contains(m.getRole())
+                    && relationMembers.stream().map(RelationMember::getRole).collect(Collectors.toSet()).containsAll(ROLES);
+        }
+
+        @Override
+        public List<RelationMember> sortMembers(List<RelationMember> list) {
+            list.sort(Comparator.comparingInt(m -> ROLES.indexOf(m.getRole())));
+            return list;
+        }
+    }
+
+    /**
      * Sort a collection of relation members by the way they are linked.
      *
@@ -150,5 +174,5 @@
             boolean wasAdded = false;
             for (AdditionalSorter sorter : ADDITIONAL_SORTERS) {
-                if (sorter.acceptsMember(m)) {
+                if (sorter.acceptsMember(relationMembers, m)) {
                     wasAdded = customMap.computeIfAbsent(sorter, k -> new LinkedList<>()).add(m);
                     break;
