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 }