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