001 // License: GPL. Copyright 2007 by Immanuel Scholz and others
002 package org.openstreetmap.josm.data.osm;
003
004 import java.util.Comparator;
005 import java.util.HashMap;
006
007 import org.openstreetmap.josm.gui.DefaultNameFormatter;
008
009 /** Comparator, comparing by type and objects display names */
010 public class OsmPrimitiveComparator implements Comparator<OsmPrimitive> {
011 final private HashMap<OsmPrimitive, String> cache= new HashMap<OsmPrimitive, String>();
012 final private DefaultNameFormatter df = DefaultNameFormatter.getInstance();
013 public boolean relationsFirst = false;
014
015 private String cachedName(OsmPrimitive p) {
016 String name = cache.get(p);
017 if (name == null) {
018 name = p.getDisplayName(df);
019 cache.put(p, name);
020 }
021 return name;
022 }
023
024 private int compareName(OsmPrimitive a, OsmPrimitive b) {
025 String an = cachedName(a);
026 String bn = cachedName(b);
027 // make sure display names starting with digits are the end of the
028 // list
029 if (Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
030 return an.compareTo(bn);
031 else if (Character.isDigit(an.charAt(0)) && !Character.isDigit(bn.charAt(0)))
032 return 1;
033 else if (!Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
034 return -1;
035 return an.compareTo(bn);
036 }
037
038 private int compareType(OsmPrimitive a, OsmPrimitive b) {
039 if(relationsFirst) {
040 // show relations before ways, then nodes
041 if (a.getType().equals(OsmPrimitiveType.RELATION)) return -1;
042 if (a.getType().equals(OsmPrimitiveType.NODE)) return 1;
043 // a is a way
044 if (b.getType().equals(OsmPrimitiveType.RELATION)) return 1;
045 // b is a node
046 } else {
047 // show ways before relations, then nodes
048 if (a.getType().equals(OsmPrimitiveType.WAY)) return -1;
049 if (a.getType().equals(OsmPrimitiveType.NODE)) return 1;
050 // a is a relation
051 if (b.getType().equals(OsmPrimitiveType.WAY)) return 1;
052 // b is a node
053 }
054 return -1;
055 }
056
057 public int compare(OsmPrimitive a, OsmPrimitive b) {
058 if (a.getType().equals(b.getType()))
059 return compareName(a, b);
060 return compareType(a, b);
061 }
062 }