Changeset 4070 in josm


Ignore:
Timestamp:
2011-05-03T08:02:54+02:00 (10 years ago)
Author:
jttt
Message:

Fix #6275 Sort relations numerically

Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/NameFormatter.java

    r3083 r4070  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.osm;
     3
     4import java.util.Comparator;
    35
    46public interface NameFormatter {
     
    79    String format(Relation relation);
    810    String format(Changeset changeset);
     11
     12    Comparator<Node> getNodeComparator();
     13    Comparator<Way> getWayComparator();
     14    Comparator<Relation> getRelationComparator();
    915}
  • trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java

    r3918 r4070  
    99import java.util.Arrays;
    1010import java.util.Collections;
     11import java.util.Comparator;
    1112import java.util.HashSet;
    1213import java.util.List;
     
    5152    /** the default list of tags which are used as naming tags in relations */
    5253    static public final String[] DEFAULT_NAMING_TAGS_FOR_RELATIONS = {"name", "ref", "restriction", "landuse", "natural",
    53     "public_transport", ":LocationCode", "note"};
     54        "public_transport", ":LocationCode", "note"};
    5455
    5556    /** the current list of tags used as naming tags in relations */
     
    138139    }
    139140
     141    private final Comparator<Node> nodeComparator = new Comparator<Node>() {
     142        @Override
     143        public int compare(Node n1, Node n2) {
     144            return format(n1).compareTo(format(n2));
     145        }
     146    };
     147
     148    public Comparator<Node> getNodeComparator() {
     149        return nodeComparator;
     150    }
     151
     152
    140153    /**
    141154     * Formats a name for a way
     
    189202                nodesNo--;
    190203            }
    191             if(name == null || name.length() == 0)
     204            if(name == null || name.length() == 0) {
    192205                name = String.valueOf(way.getId());
     206            }
    193207            /* note: length == 0 should no longer happen, but leave the bracket code
    194208               nevertheless, who knows what future brings */
     
    201215    }
    202216
     217    private final Comparator<Way> wayComparator = new Comparator<Way>() {
     218        @Override
     219        public int compare(Way w1, Way w2) {
     220            return format(w1).compareTo(format(w2));
     221        }
     222    };
     223
     224    public Comparator<Way> getWayComparator() {
     225        return wayComparator;
     226    }
     227
     228
    203229    /**
    204230     * Formats a name for a relation
     
    212238            name = tr("incomplete");
    213239        } else {
    214             name = trc("Relation type", relation.get("type"));
    215             if (name == null) {
    216                 name = (relation.get("public_transport") != null) ? tr("public transport") : "";
    217             }
    218             if (name == null) {
    219                 String building  = relation.get("building");
    220                 if(OsmUtils.isTrue(building))
    221                     name = tr("building");
    222                 else if(building != null)
    223                     name = tr(building); // translate tag!
    224             }
    225             if (name == null) {
    226                 name = trc("Place type", relation.get("place"));
    227             }
    228             if (name == null) {
    229                 name = tr("relation");
    230             }
    231             String admin_level = relation.get("admin_level");
    232             if (admin_level != null) {
    233                 name += "["+admin_level+"]";
    234             }
    235 
    236             name += " (";
    237             String nameTag = null;
    238             for (String n : getNamingtagsForRelations()) {
    239                 if (n.equals("name")) {
    240                     if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
    241                         nameTag = relation.getLocalName();
    242                     } else {
    243                         nameTag = relation.getName();
    244                     }
    245                 } else if (n.equals(":LocationCode")) {
    246                     for (String m : relation.keySet()) {
    247                         if (m.endsWith(n)) {
    248                             nameTag = relation.get(m);
    249                             break;
    250                         }
    251                     }
    252                 } else {
    253                     String str = relation.get(n);
    254                     if(str != null)
    255                         nameTag = tr(str);
    256                 }
    257                 if (nameTag != null) {
    258                     break;
    259                 }
    260             }
    261             if (nameTag == null) {
    262                 name += Long.toString(relation.getId()) + ", ";
     240            name = getRelationTypeName(relation);
     241            String relationName = getRelationName(relation);
     242            if (relationName == null) {
     243                relationName = Long.toString(relation.getId());
    263244            } else {
    264                 name += "\"" + nameTag + "\", ";
    265             }
     245                relationName = "\"" + relationName + "\"";
     246            }
     247            name += " (" + relationName + ", ";
    266248
    267249            int mbno = relation.getMembersCount();
    268250            name += trn("{0} member", "{0} members", mbno, mbno);
    269251
    270             boolean incomplete = false;
    271             for (RelationMember m : relation.getMembers()) {
    272                 if (m.getMember().isIncomplete()) {
    273                     incomplete = true;
    274                     break;
    275                 }
    276             }
    277             if (incomplete) {
     252            if (relationHasIncompleteMember(relation)) {
    278253                name += ", "+tr("incomplete");
    279254            }
     
    283258        name = decorateNameWithId(name, relation);
    284259        return name;
     260    }
     261
     262    private final Comparator<Relation> relationComparator = new Comparator<Relation>() {
     263        @Override
     264        public int compare(Relation r1, Relation r2) {
     265            String type1 = getRelationTypeName(r1);
     266            String type2 = getRelationTypeName(r2);
     267
     268            int comp = type1.compareTo(type2);
     269            if (comp != 0)
     270                return comp;
     271
     272            String name1 = getRelationName(r1);
     273            String name2 = getRelationName(r2);
     274
     275            if (name1 == null && name2 == null)
     276                return (r1.getUniqueId() > r2.getUniqueId())?1:-1;
     277            else if (name1 == null)
     278                return -1;
     279            else if (name2 == null)
     280                return 1;
     281            else if (!name1.isEmpty() && !name2.isEmpty() && Character.isDigit(name1.charAt(0)) && Character.isDigit(name2.charAt(0))) {
     282                //Compare numerically
     283                String ln1 = getLeadingNumber(name1);
     284                String ln2 = getLeadingNumber(name2);
     285
     286                comp = Long.valueOf(ln1).compareTo(Long.valueOf(ln2));
     287                if (comp != 0)
     288                    return comp;
     289
     290                // put 1 before 0001
     291                comp = ln1.compareTo(ln2);
     292                if (comp != 0)
     293                    return comp;
     294
     295                comp = name1.substring(ln1.length()).compareTo(name2.substring(ln2.length()));
     296                if (comp != 0)
     297                    return comp;
     298            } else {
     299                comp = name1.compareToIgnoreCase(name2);
     300                if (comp != 0)
     301                    return comp;
     302            }
     303
     304            if (r1.getMembersCount() != r2.getMembersCount())
     305                return (r1.getMembersCount() > r2.getMembersCount())?1:-1;
     306
     307            comp = Boolean.valueOf(relationHasIncompleteMember(r1)).compareTo(Boolean.valueOf(relationHasIncompleteMember(r2)));
     308            if (comp != 0)
     309                return comp;
     310
     311            return r1.getUniqueId() > r2.getUniqueId()?1:-1;
     312        }
     313    };
     314
     315    public Comparator<Relation> getRelationComparator() {
     316        return relationComparator;
     317    }
     318
     319    private String getLeadingNumber(String s) {
     320        int i = 0;
     321        while (i < s.length() && Character.isDigit(s.charAt(i))) {
     322            i++;
     323        }
     324        return s.substring(0, i);
     325    }
     326
     327    private String getRelationTypeName(Relation relation) {
     328        String name = trc("Relation type", relation.get("type"));
     329        if (name == null) {
     330            name = (relation.get("public_transport") != null) ? tr("public transport") : null;
     331        }
     332        if (name == null) {
     333            String building  = relation.get("building");
     334            if(OsmUtils.isTrue(building)) {
     335                name = tr("building");
     336            } else if(building != null)
     337            {
     338                name = tr(building); // translate tag!
     339            }
     340        }
     341        if (name == null) {
     342            name = trc("Place type", relation.get("place"));
     343        }
     344        if (name == null) {
     345            name = tr("relation");
     346        }
     347        String admin_level = relation.get("admin_level");
     348        if (admin_level != null) {
     349            name += "["+admin_level+"]";
     350        }
     351
     352        return name;
     353    }
     354
     355    private String getNameTagValue(Relation relation, String nameTag) {
     356        if (nameTag.equals("name")) {
     357            if (Main.pref.getBoolean("osm-primitives.localize-name", true))
     358                return relation.getLocalName();
     359            else
     360                return relation.getName();
     361        } else if (nameTag.equals(":LocationCode")) {
     362            for (String m : relation.keySet()) {
     363                if (m.endsWith(nameTag))
     364                    return relation.get(m);
     365            }
     366            return null;
     367        } else
     368            return relation.get(nameTag);
     369    }
     370
     371    private String getRelationName(Relation relation) {
     372        String nameTag = null;
     373        for (String n : getNamingtagsForRelations()) {
     374            nameTag = getNameTagValue(relation, n);
     375            if (nameTag != null)
     376                return nameTag;
     377        }
     378        return null;
     379    }
     380
     381    private boolean relationHasIncompleteMember(Relation relation) {
     382        for (RelationMember m : relation.getMembers()) {
     383            if (m.getMember().isIncomplete())
     384                return true;
     385        }
     386        return false;
    285387    }
    286388
     
    407509        int nodesNo = way.isClosed() ? way.getNumNodes() -1 : way.getNumNodes();
    408510        String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
    409         if(sb.length() == 0 )
     511        if(sb.length() == 0 ) {
    410512            sb.append(way.getId());
     513        }
    411514        /* note: length == 0 should no longer happen, but leave the bracket code
    412515           nevertheless, who knows what future brings */
  • trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

    r3719 r4070  
    3434
    3535import org.openstreetmap.josm.Main;
    36 import org.openstreetmap.josm.data.osm.NameFormatter;
    3736import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3837import org.openstreetmap.josm.data.osm.Relation;
     
    4241import org.openstreetmap.josm.data.osm.event.DataSetListener;
    4342import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
     43import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
    4444import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
    4545import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
     
    4848import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
    4949import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    50 import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
    5150import org.openstreetmap.josm.gui.DefaultNameFormatter;
    5251import org.openstreetmap.josm.gui.MapView;
     52import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
    5353import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    5454import org.openstreetmap.josm.gui.SideButton;
    55 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
    5655import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask;
    5756import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationTask;
     
    9190        super(tr("Relations"), "relationlist", tr("Open a list of all relations."),
    9291                Shortcut.registerShortcut("subwindow:relations", tr("Toggle: {0}", tr("Relations")), KeyEvent.VK_R,
    93                     Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
     92                        Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
    9493
    9594        // create the list of relations
     
    578577            Collections.sort(
    579578                    relations,
    580                     new Comparator<Relation>() {
    581                         NameFormatter formatter = DefaultNameFormatter.getInstance();
    582 
    583                         public int compare(Relation r1, Relation r2) {
    584                             return r1.getDisplayName(formatter).compareTo(r2.getDisplayName(formatter));
    585                         }
    586                     }
     579                    DefaultNameFormatter.getInstance().getRelationComparator()
    587580            );
    588581        }
Note: See TracChangeset for help on using the changeset viewer.