/* * GeoTools java GIS tookit (c) The Centre for Computational Geography 2002 * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation version 2.1 */ package uk.ac.leeds.ccg.geotools; import uk.ac.leeds.ccg.geotools.classification.*; import java.awt.*; import java.util.*; import java.io.*; import java.net.*; /** * Unlike RampShaders, DiscreteShaders have a set number of categories. * This class is the base from which percentile, quantile and look-up * are extended. * Their biggest distinction will come from the way they produce keys. * This shader is constructed using a set of ranges, colours and names * to be used as the classifications. These can either be supplied in a * key file referenced via a URL or as a set of three vectors. * * $Log: DiscreteShader.java,v $ * Revision 1.14 2002/03/09 20:05:21 loxnard * Fixed JavaDoc comments. * * * @author James Macgill * @author Ian Turton * @version $Revision: 1.14 $ $Date: 2002/03/09 20:05:21 $ * @since before 0.8.0 */ public class DiscreteShader extends uk.ac.leeds.ccg.geotools.SimpleShader { /** * Holds the keys for each item. */ protected Vector keys = new Vector(); /** * Default constructor. Should only be used by subclasses. * TODO: make protected? */ public DiscreteShader(){ //only for use by descendents } /** * Constructs a DiscreteShader which allows almost total control over the classifications used when * shading.

* The key file format is as follows: * integer,'#XXXXXX','description'

* Note: the quote marks are necessary.
* The integer will be checked against any values passed into getColor. The description * will be used to label the key, and #XXXXXX is a hexidecimal * colour code.

* e.g.

* 1,'#ff3333',A-Roads
* 2,'#993333',B-Roads
* 3,'#ffff33',C-Roads
* 4,'#cccccc',Unclassified

* If a - is used in the value column, then a range is assumed.

* e.g.

* 0-49,'#0000ff',Cold
* 50-100,'#ff0000',Hot
* * TODO: Bug? How are negative values handled in ranges? * @param keyFile A URL reference to a key file. * @throws IOException Thrown if any errors occur during the reading of the file. */ public DiscreteShader(URL keyFile) throws IOException{ Reader reader = new InputStreamReader(keyFile.openStream()); StreamTokenizer st = new StreamTokenizer(reader); st.whitespaceChars(',',','); st.wordChars('-','-'); st.wordChars('*','*'); st.wordChars(' ',' '); st.parseNumbers(); int token; int code; Color color; String name; Bin value; token = st.nextToken(); while(token!=st.TT_EOF){ if(st.sval!=null) { //System.out.println("Using Range key"); String range = st.sval; int split = range.indexOf('-'); String low = range.substring(0, split); String high = range.substring(split+1,range.length()); //System.out.println("range "+range); int a,b; if(low.equals("*")){ a = Integer.MIN_VALUE; } else{ a = (new Integer(low)).intValue(); } if(high.equals("*")){ b = Integer.MAX_VALUE; } else{ b = (new Integer(high)).intValue(); } value = new Bin(a,b); } else { code=(int)st.nval; //value = new Bin(code,code+Double.MIN_VALUE); value = new Bin(code,code+0.5); } st.nextToken(); //System.out.println("ds "+st.sval); color = Color.decode(st.sval); st.nextToken(); name = st.sval; token = st.nextToken(); RangeItem k = new RangeItem(value,color,name); keys.addElement(k); // System.out.println(k); } } /** * An alternative constructor for building a DiscreteShader that does not rely on * the use of a key file. Instead, the values, colours and descriptions are supplied in the * form of three vectors. * @param values A vector of Integer objects which represent the value for each classification. * @param colours A vector of Color objects which represent the colour for each classification. * @param descriptions A vector of Strings with which to label each of the classifications. */ public DiscreteShader(Vector values,Vector colours,Vector descriptions){ Bin value; int code; for(int i=0;i