Changeset 5516 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2012-09-23T17:49:46+02:00 (12 years ago)
Author:
Don-vip
Message:

Relation editor: properly sort associatedStreet relations houses according to their addr:housenumber

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

    r5410 r5516  
    1212import java.util.Collection;
    1313import java.util.Collections;
     14import java.util.Comparator;
     15import java.util.HashMap;
    1416import java.util.HashSet;
    1517import java.util.Iterator;
    1618import java.util.LinkedList;
    1719import java.util.List;
     20import java.util.Map;
    1821import java.util.Set;
    1922import java.util.concurrent.CopyOnWriteArrayList;
     
    6063
    6164    private final int UNCONNECTED = Integer.MIN_VALUE;
     65   
     66    private static final Collection<AdditionalSorter> additionalSorters = new ArrayList<AdditionalSorter>();
     67   
     68    static {
     69        additionalSorters.add(new AssociatedStreetSorter());
     70    }
    6271
    6372    /**
     
    721730        }
    722731
    723         group = new LinkedList<Integer>();
    724         group.addAll(map.getNotSortableMembers());
    725         allGroups.add(group);
    726 
    727732        ArrayList<RelationMember> newMembers = new ArrayList<RelationMember>();
    728733        for (LinkedList<Integer> tmpGroup : allGroups) {
     
    731736            }
    732737        }
     738
     739        // Try to sort remaining members with custom mechanisms (relation-dependent)
     740        List<RelationMember> notSortableMembers = new LinkedList<RelationMember>();
     741        Map<AdditionalSorter, List<RelationMember>> additionalMap = new HashMap<AdditionalSorter, List<RelationMember>>();
     742
     743        // Dispatch members to correct sorters
     744        for (Integer i : map.getNotSortableMembers()) {
     745            RelationMember m = relationMembers.get(i);
     746            for (AdditionalSorter sorter : additionalSorters) {
     747                List<RelationMember> list = notSortableMembers;
     748                if (sorter.acceptsMember(m)) {
     749                    list = additionalMap.get(sorter);
     750                    if (list == null) {
     751                        additionalMap.put(sorter, list = new LinkedList<RelationMember>());
     752                    }
     753                }
     754                list.add(m);
     755            }
     756        }
     757       
     758        // Sort members and add them to result
     759        for (AdditionalSorter s : additionalMap.keySet()) {
     760            newMembers.addAll(s.sortMembers(additionalMap.get(s)));
     761        }
     762       
     763        // Finally, add members that have not been sorted at all
     764        newMembers.addAll(notSortableMembers);
     765       
    733766        return newMembers;
    734767    }
     
    11381171        return wct;
    11391172    }
     1173   
     1174    private static interface AdditionalSorter {
     1175        public boolean acceptsMember(RelationMember m);
     1176        public List<RelationMember> sortMembers(List<RelationMember> list);
     1177    }
     1178   
     1179    /**
     1180     * Class that sorts type=associatedStreet relation's houses.
     1181     */
     1182    private static class AssociatedStreetSorter implements AdditionalSorter {
     1183
     1184        @Override
     1185        public boolean acceptsMember(RelationMember m) {
     1186            return m != null
     1187                    && m.getRole() != null && m.getRole().equals("house")
     1188                    && m.getMember() != null && m.getMember().get("addr:housenumber") != null;
     1189        }
     1190
     1191        @Override
     1192        public List<RelationMember> sortMembers(List<RelationMember> list) {
     1193            Collections.sort(list, new Comparator<RelationMember>() {
     1194                @Override
     1195                public int compare(RelationMember a, RelationMember b) {
     1196                    if (a == b || a.getMember() == b.getMember()) return 0;
     1197                    String addrA = a.getMember().get("addr:housenumber").trim();
     1198                    String addrB = b.getMember().get("addr:housenumber").trim();
     1199                    if (addrA.equals(addrB)) return 0;
     1200                    // Strip non-digits (from "1B" addresses for example)
     1201                    String addrAnum = addrA.replaceAll("\\D+", "");
     1202                    String addrBnum = addrB.replaceAll("\\D+", "");
     1203                    // Compare only numbers
     1204                    try {
     1205                        Integer res = Integer.parseInt(addrAnum) - Integer.parseInt(addrBnum);
     1206                        if (res != 0) return res;
     1207                    } catch (NumberFormatException e) {
     1208                        // Ignore NumberFormatException. If the number is not composed of digits, strings are compared next
     1209                    }
     1210                    // Same number ? Compare full strings
     1211                    return addrA.compareTo(addrB);
     1212                }
     1213            });
     1214            return list;
     1215        }
     1216    }
    11401217}
Note: See TracChangeset for help on using the changeset viewer.