/*
* Geotools 2 - OpenSource mapping toolkit
* (C) 2003, Geotools Project Management Committee (PMC)
* (C) 2001, Institut de Recherche pour le Développement
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* This package contains documentation from OpenGIS specifications.
* OpenGIS consortium's work is fully acknowledged here.
*/
package org.geotools.cv;
// J2SE dependencies
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.util.AbstractList;
import java.util.Locale;
import org.geotools.resources.Utilities;
import org.geotools.resources.XMath;
import org.geotools.units.Unit;
/**
* An immutable list of geophysics category. Elements are usually (but not always) instances
* of [@link GeophysicsCategory}. Exception to this rule includes categories wrapping an
* identity transforms.
*
* This list can transform geophysics values into sample values using
* the list of {@link Category}. This transform is thread safe if each
* {@link Category#getSampleToGeophysics} transform is thread-safe too.
*
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux
*
* @deprecated Replaced by {@link org.geotools.coverage.GeophysicsCategoryList}
* in the org.geotools.coverage
package.
*/
final class GeophysicsCategoryList extends CategoryList {
/**
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = 98602310176453958L;
/**
* Maximum value for {@link #ndigits}. This is the number of
* significant digits to allow when formatting a geophysics value.
*/
private static final int MAX_DIGITS = 6;
/**
* Unités des mesures géophysiques représentées par les catégories.
* Ce champ peut être nul s'il ne s'applique pas ou si les unités
* ne sont pas connues.
*/
private final Unit unit;
/**
* Nombre de chiffres significatifs après la virgule.
* Cette information est utilisée pour les écritures
* des valeurs géophysiques des catégories.
*/
private final int ndigits;
/**
* Locale used for creating {@link #format} last time.
* May be null
if default locale was requested.
*/
private transient Locale locale;
/**
* Format à utiliser pour écrire les
* valeurs géophysiques des thèmes.
*/
private transient NumberFormat format;
/**
* Objet temporaire pour {@link NumberFormat}.
*/
private transient FieldPosition dummy;
/**
* Construct a category list using the specified array of categories.
*
* @param categories The list of categories. Elements should be
* instances of {@link GeophysicsCategory}
* (most of the time, but not always).
* @param unit The unit information for all quantitative categories.
* May be null
if no category has units.
* @param inverse The {@link CategoryList} which is constructing this
* {@link GeophysicsCategoryList}.
*
* @throws IllegalArgumentException if two or more categories
* have overlapping sample value range.
*/
GeophysicsCategoryList(Category[] categories, final Unit unit, final CategoryList inverse) {
super(categories, unit, true, inverse);
this.unit = unit;
this.ndigits = getFractionDigitCount(categories);
assert isScaled(true);
}
/**
* Compute the smallest number of fraction digits necessary to resolve all
* quantitative values. This method assume that geophysics values in the range
* Category.geophysics(true).getRange
are stored as integer sample
* values in the range Category.geophysics(false).getRange
.
*/
private static int getFractionDigitCount(final Category[] categories) {
int ndigits = 0;
final double EPS = 1E-6;
for (int i=0; indigits) {
ndigits = Math.min(n, MAX_DIGITS);
}
}
}
return ndigits;
}
/**
* If toGeophysics
is false
, cancel the action of a previous
* call to geophysics(true)
. This method always returns a list of categories
* in which {@link Category#geophysics(boolean) Category.geophysics}(toGeophysics)
* has been invoked for each category.
*/
public CategoryList geophysics(final boolean toGeophysics) {
final CategoryList scaled = toGeophysics ? this : inverse;
assert scaled.isScaled(toGeophysics);
return scaled;
}
/**
* Returns the unit information for quantitative categories in this list.
* May returns null
if there is no quantitative categories
* in this list, or if there is no unit information.
*/
public Unit getUnits() {
return unit;
}
/**
* Formatte la valeur spécifiée selon les conventions locales. Le nombre sera
* écrit avec un nombre de chiffres après la virgule approprié pour la catégorie.
* Le symbole des unités sera ajouté après le nombre si writeUnit
* est true
.
*
* @param value Valeur du paramètre géophysique à formatter.
* @param writeUnit Indique s'il faut écrire le symbole des unités après le nombre.
* Cet argument sera ignoré si aucune unité n'avait été spécifiée au constructeur.
* @param locale Conventions locales à utiliser, ou null
pour les conventions par
* défaut.
* @param buffer Le buffer dans lequel écrire la valeur.
* @return Le buffer buffer
dans lequel auront été écrit la valeur et les unités.
*/
synchronized StringBuffer format(final double value, final boolean writeUnits,
final Locale locale, StringBuffer buffer)
{
if (format==null || !Utilities.equals(this.locale, locale)) {
this.locale = locale;
format=(locale!=null) ? NumberFormat.getNumberInstance(locale) :
NumberFormat.getNumberInstance();
format.setMinimumFractionDigits(ndigits);
format.setMaximumFractionDigits(ndigits);
dummy = new FieldPosition(0);
}
buffer = format.format(value, buffer, dummy);
if (writeUnits && unit!=null) {
final int position = buffer.length();
buffer.append('\u00A0'); // No-break space
buffer.append(unit);
if (buffer.length() == position+1) {
buffer.setLength(position);
}
}
return buffer;
}
/**
* Compares the specified object with this category list for equality.
* If the two objects are instances of {@link CategoryList}, then the
* test is a little bit stricter than the default {@link AbstractList#equals}.
*/
public boolean equals(final Object object) {
if (object instanceof GeophysicsCategoryList) {
final GeophysicsCategoryList that = (GeophysicsCategoryList) object;
return this.ndigits == that.ndigits &&
Utilities.equals(this.unit, that.unit) &&
super.equals(that);
}
return ndigits==0 && unit==null && super.equals(object);
}
}