001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2007, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * This package contains documentation from OpenGIS specifications.
017: * OpenGIS consortium's work is fully acknowledged here.
018: */
019: package org.geotools.metadata.iso.identification;
020:
021: // OpenGIS dependencies
022: import org.opengis.metadata.identification.RepresentativeFraction;
023:
024: // Geotools dependencies
025: import org.geotools.resources.i18n.ErrorKeys;
026: import org.geotools.resources.i18n.Errors;
027:
028: /**
029: * A scale where {@linkplain #getDenominator denominator} = {@code 1 / scale}.
030: * This implementation is set up as a {@linkplain Number number} - because it is.
031: *
032: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/metadata/iso/identification/RepresentativeFractionImpl.java $
033: * @version $Id: RepresentativeFractionImpl.java 25098 2007-04-10 18:32:18Z desruisseaux $
034: * @author Jody Garnett
035: *
036: * @since 2.4
037: */
038: public class RepresentativeFractionImpl extends Number implements
039: RepresentativeFraction {
040: /**
041: * Serial number for compatibility with different versions.
042: */
043: private static final long serialVersionUID = 7228422109144637537L;
044:
045: /**
046: * The number below the line in a vulgar fraction.
047: */
048: private final long denominator;
049:
050: /**
051: * Creates a new representative fraction from the specified denominator.
052: */
053: public RepresentativeFractionImpl(final long denominator) {
054: this .denominator = denominator;
055: }
056:
057: /**
058: * Creates a representative fraction from a scale as a {@code double} value.
059: * The {@linkplain #getDenominator denominator} will be set to {@code 1/scale}.
060: *
061: * @param scale The scale as a number between 0 and 1.
062: *
063: * @throws IllegalArgumentException if the condition {@code abs(scale) <= 1} is not meet.
064: */
065: public static RepresentativeFraction fromScale(final double scale)
066: throws IllegalArgumentException {
067: if (Math.abs(scale) <= 1 || scale == Double.POSITIVE_INFINITY) {
068: // Note: we accept positive infinity, but not negative infinity because
069: // we can't represent a negative zero using 'long' primitive type.
070: return new RepresentativeFractionImpl(Math
071: .round(1.0 / scale)); // flip!
072: } else {
073: throw new IllegalArgumentException(Errors.format(
074: ErrorKeys.ILLEGAL_ARGUMENT_$2, "scale", new Double(
075: scale)));
076: }
077: }
078:
079: /**
080: * Returns the scale. This is equivalent to {@link #doubleValue}.
081: */
082: public double toScale() {
083: return doubleValue();
084: }
085:
086: /**
087: * Returns the scale in a form usable for computation.
088: *
089: * @return <code>1.0 / {@linkplain #getDenominator() denominator}</code>
090: */
091: public double doubleValue() {
092: return 1.0 / (double) denominator;
093: }
094:
095: /**
096: * Returns the scale as a {@code float} type.
097: */
098: public float floatValue() {
099: return 1.0f / (float) denominator;
100: }
101:
102: /**
103: * Returns 0 since the scale is a fraction between 0 and 1. Such value can not
104: * be represented as an integer.
105: */
106: public long longValue() {
107: return 0;
108: }
109:
110: /**
111: * Returns 0 since the scale is a fraction between 0 and 1. Such value can not
112: * be represented as an integer.
113: */
114: public int intValue() {
115: return 0;
116: }
117:
118: /**
119: * Returns the number below the line in a vulgar fraction.
120: */
121: public int getDenominator() {
122: if (denominator < Integer.MIN_VALUE
123: || denominator > Integer.MAX_VALUE) {
124: throw new IllegalStateException(); // API change required.
125: }
126: return (int) denominator;
127: }
128:
129: /**
130: * Compares this object with the specified value for equality.
131: */
132: public boolean equals(final Object object) {
133: /*
134: * Note: 'equals(Object)' and 'hashCode()' implementations are defined in the interface,
135: * in order to ensure that the following requirements hold:
136: *
137: * - a.equals(b) == b.equals(a) (reflexivity)
138: * - a.equals(b) implies (a.hashCode() == b.hashCode())
139: */
140: if (object instanceof RepresentativeFraction) {
141: final RepresentativeFraction that = (RepresentativeFraction) object;
142: return denominator == that.getDenominator();
143: }
144: return false;
145: }
146:
147: /**
148: * Returns a hash value for this representative fraction.
149: */
150: public int hashCode() {
151: return (int) denominator;
152: }
153: }
|