ConversionCalculator.java [src/usda/weru/util] Revision: default Date:
/*
* ConversionCalculator.java
*
* Created on January 30, 2006, 12:50 PM
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package usda.weru.util;
import java.io.File;
import java.util.Hashtable;
/**
* Stores a table of units and conversion to simplify unit conversions.
* @author Joseph Levin
*/
public class ConversionCalculator {
/**
* Stores the units avaliable to use in conversions.
*/
private static Hashtable <String, ConversionUnit> c_unitCatalog;
/**
* Table of conversions.
*/
private static Hashtable <ConversionUnit, Hashtable <ConversionUnit, Double>> c_table;
static{
c_unitCatalog = new Hashtable <String, ConversionUnit> ();
c_table = new Hashtable <ConversionUnit, Hashtable <ConversionUnit, Double>> ();
loadUnitCatalog(null);
}
/**
* Loads the unit catalog. Currently the files are not read and only hardcoded
* units and conversions and uses.
* @param file File to load
*/
public static void loadUnitCatalog(File file){
//LENGTH
addUnit(new ConversionUnit("meter", "m"));
addUnit(new ConversionUnit("centimeter", "cm"));
addUnit(new ConversionUnit("milimeter", "mm"));
addUnit(new ConversionUnit("foot","ft"));
addUnit(new ConversionUnit("inch","in"));
addUnit(new ConversionUnit("yard","yd"));
addUnit(new ConversionUnit("mile","mi"));
addUnit(new ConversionUnit("pound","lb"));
addUnit(new ConversionUnit("ton","tn"));
//AREA
addUnit(new ConversionUnit("squaremeter", "m\u00B2", "m^2"));
addUnit(new ConversionUnit("hectare","ha"));
addUnit(new ConversionUnit("acre","acres", "ac"));
//Special
addUnit(new ConversionUnit("kilogrampermetersquared","kg/m\u00B2","kg/m^2"));
addUnit(new ConversionUnit("tonperacre", "t/ac", "tn/ac", "tons/acre"));
addUnit(new ConversionUnit("poundperacre", "lbs/acre", "lb/ac"));
addUnit(new ConversionUnit("kilogrampermeter","kg/m"));
addUnit(new ConversionUnit("tonperthousandfeet", "tons/1000ft","tn/1000ft"));
addUnit(new ConversionUnit("percent","%"));
addUnit(new ConversionUnit("ratio","ratio"));
addUnit(new ConversionUnit("meterpermeter","m/m"));
addUnit(new ConversionUnit("footperfoot","ft/ft"));
addUnit(new ConversionUnit("fraction","fraction"));
addUnit(new ConversionUnit("degree","degrees"));
addUnit(new ConversionUnit("ln(J/m^2)","ln(J/m\u00B2)","ln(J/m^2)"));
addUnit(new ConversionUnit("KJ/m^2/day","KJ/m\u00B2/day"));
addUnit(new ConversionUnit("m^2/m^2", "m\u00B2/m\u00B2"));
addUnit(new ConversionUnit("ft^2/ft^2", "ft\u00B2/ft\u00B2"));
addUnit(new ConversionUnit("#/m^2", "#/m\u00B2"));
addUnit(new ConversionUnit("#/ac", "#/ac"));
addUnit(new ConversionUnit("liter/hectare", "L/ha"));
addUnit(new ConversionUnit("gallon/acre", "gal/ac"));
addUnit(new ConversionUnit("Mg/m^3", "Mg/m\u00B3"));
addUnit(new ConversionUnit("lb/ft^3", "lb/ft\u00B3"));
addUnit(new ConversionUnit("Mg/m^2", "Mg/m\u00B2"));
addUnit(new ConversionUnit("lb/ft^2", "lb/ft\u00B2"));
addUnit(new ConversionUnit("1/m", "1/m"));
addUnit(new ConversionUnit("1/ft", "1/ft"));
addUnit(new ConversionUnit("m^3/m^3", "m\u00B3/m\u00B3"));
addUnit(new ConversionUnit("ft^3/ft^3", "ft\u00B3/ft\u00B3"));
//Lookup units for the conversions
try{
//LENGTH
addConversion("m", "ft", 3.2808399, true);
addConversion("1/m", "1/ft", 3.2808399, true);
addConversion("m", "in", 39.3700787, true);
addConversion("mm", "in", 0.0393700787, true);
//AREA
addConversion("m^2", "ac", 0.000247105381, true);
addConversion("m^2", "ha", 0.0001, true);
addConversion("ha", "ac", 2.47105381, true);
//Special
addConversion("kg/m^2", "lb/ft^2", 0.204816144, true);
addConversion("kg/m^2", "t/ac", 4.46089561, true);
addConversion("kg/m^2", "lb/ac", 8921.79122, true);
addConversion("ratio", "percent", 100, true);
addConversion("m/m", "ft/ft", 1, true);
addConversion("kg/m", "tn/1000ft", 0.335984488, true);
addConversion("m^2/m^2", "ft^2/ft^2", 1, true);
addConversion("#/m^2", "#/ac", 4046.85642, true);
addConversion("L/ha", "gal/ac", 0.106906637, true);
addConversion("Mg/m^3", "lb/ft^3", 62.4279606, true);
addConversion("Mg/m^2", "lb/ft^2", 204.816144, true);
addConversion("m^3/m^3", "ft^3/ft^3", 1, true);
}
catch(Exception e){
e.printStackTrace();
}
}
public static double convert(double value, String from, String to) throws ConversionNotFoundException, UnitNotFoundException{
double factor = getConversionFactor(from, to);
return value * factor;
}
public static double convert(double value, ConversionUnit from, ConversionUnit to) throws ConversionNotFoundException{
double factor = getConversionFactor(from, to);
return value * factor;
}
/**
* Adds a ConversionUnit object to the catalog.
* @param unit ConversionUnit to add.
*/
public static void addUnit(ConversionUnit unit){
c_unitCatalog.put(unit.getName(), unit);
}
/**
* Helper method for adding conversions by string names of units.
* @param from Name of the unit intial unit
* @param to Name of the final unit
* @param factor Conversion factor
* @param reverse If true, a reverse conversion will be added.
*/
public static void addConversion(String from, String to, double factor, boolean reverse){
try{
ConversionUnit fromUnit = getUnitFromTag(from);
ConversionUnit toUnit = getUnitFromTag(to);
addConversion(fromUnit, toUnit, factor, reverse);
}
catch(Exception e){
e.printStackTrace();
}
}
/**
* Adds a converion to the table.
* @param from intial ConversionUnit object
* @param to final ConversionUnit object
* @param factor conversion factor
* @param reverse If true, a reverse conversion will be added.
*/
public static void addConversion(ConversionUnit from, ConversionUnit to, double factor, boolean reverse){
getFirstTable(from).put(to, factor);
if (reverse){
addConversion(to, from, 1/factor, false);
}
}
/**
* Returns the conversion factor between two units.
* @param from Unit to convert from.
* @param to Unit to convert to.
* @throws usda.weru.util.ConversionCalculator.ConversionNotFoundException If the conversion is not in the conversion table.
* @throws usda.weru.util.ConversionCalculator.UnitNotFoundException If a unit is not found in the catalog
* @return Conversion factor
*/
public static double getConversionFactor(Object from, Object to) throws ConversionNotFoundException, UnitNotFoundException{
ConversionUnit uFrom = getUnitFromTag(from.toString());
ConversionUnit uTo = getUnitFromTag(to.toString());
return getConversionFactor(uFrom, uTo);
}
/**
* Returns the conversion factor between two units.
* @param from Unit to convert from.
* @param to Unit to convert to.
* @throws usda.weru.util.ConversionCalculator.ConversionNotFoundException If the conversion is not in the table.
* @return Conversino factor.
*/
public static double getConversionFactor(ConversionUnit from, ConversionUnit to) throws ConversionNotFoundException{
if (from.equals(to)) return 1; //Easy factor
Double factor = getFirstTable(from).get(to);
if (factor != null){
return factor.doubleValue();
}
else{
throw new ConversionNotFoundException(from, to);
}
}
/**
* Returns the inner table used to store conversions.
* @param unit Unit to return the table for.
* @return Table of conversinons from the unit.
*/
private static Hashtable <ConversionUnit, Double> getFirstTable(ConversionUnit unit){
Hashtable <ConversionUnit, Double> table = c_table.get(unit);
if (table != null){
return table;
}
else{
table = new Hashtable <ConversionUnit, Double> ();
c_table.put(unit, table);
return table;
}
}
/**
* Looksup ConversionUnits from a string tag. The tag can be the full name or
* abbreviation as stored in the catalog.
* @param tag Tag to lookup.
* @throws usda.weru.util.ConversionCalculator.UnitNotFoundException If the tag does not represent a unit in the catalog.
* @return ConversionUnit object
*/
public static ConversionUnit getUnitFromTag(String tag) throws UnitNotFoundException{
ConversionUnit result;
result = c_unitCatalog.get(tag);
if (result == null){
for (ConversionUnit unit : c_unitCatalog.values()){
if (unit.accept(tag)) return unit;
}
}
if (result != null){
return result;
}
else{
throw new UnitNotFoundException(tag);
}
}
/**
* Exception for trapping unknown unit tags
*/
static public class UnitNotFoundException extends Exception{
/**
* ConversionUnit object
*/
private String c_unit;
/**
* Constructor for the exception.
* @param unit Tag not found
*/
UnitNotFoundException(String unit){
super("Unit Not Found In Table: " + unit);
c_unit = unit;
}
/**
* Getter method for the unknown unit tag.
* @return Unknown unit tag
*/
public String getUnitTag(){
return c_unit;
}
}
/**
* Exception for trapping undefined conversions
*/
static public class ConversionNotFoundException extends Exception{
/**
* ConversionUnit object
*/
private ConversionUnit c_fromUnit;
/**
* ConversionUnit object
*/
private ConversionUnit c_toUnit;
/**
* Constructor for the conversion not found exception.
* @param from intial ConversionUnit
* @param to final ConversionUnit
*/
ConversionNotFoundException(ConversionUnit from, ConversionUnit to){
super("Conversion Not Found In Table: from " + from.toString() + " to " + to.toString());
c_fromUnit = from;
c_toUnit = to;
}
/**
* Getter method for the from unit
* @return ConversionUnit object
*/
public ConversionUnit getFromUnit(){
return c_fromUnit;
}
/**
* Getter method for the to ConversionUnit object
* @return ConversionUnit object
*/
public ConversionUnit getToUnit(){
return c_toUnit;
}
}
}