001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2001, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * This package contains documentation from OpenGIS specifications.
018: * OpenGIS consortium's work is fully acknowledged here.
019: */
020: package org.geotools.referencing.crs;
021:
022: // J2SE dependencies and extensions
023: import java.util.Collections;
024: import java.util.Date;
025: import java.util.Map;
026: import javax.units.Converter;
027: import javax.units.SI;
028: import javax.units.Unit;
029:
030: // OpenGIS dependencies
031: import org.opengis.referencing.cs.TimeCS;
032: import org.opengis.referencing.crs.TemporalCRS;
033: import org.opengis.referencing.datum.TemporalDatum;
034:
035: // Geotools dependencies
036: import org.geotools.referencing.AbstractReferenceSystem;
037:
038: /**
039: * A 1D coordinate reference system used for the recording of time.
040: *
041: * <TABLE CELLPADDING='6' BORDER='1'>
042: * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
043: * <TR><TD>
044: * {@link TimeCS Time}
045: * </TD></TR></TABLE>
046: *
047: * @since 2.1
048: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultTemporalCRS.java $
049: * @version $Id: DefaultTemporalCRS.java 20874 2006-08-07 10:00:01Z jgarnett $
050: * @author Martin Desruisseaux
051: */
052: public class DefaultTemporalCRS extends AbstractSingleCRS implements
053: TemporalCRS {
054: /**
055: * Serial number for interoperability with different versions.
056: */
057: private static final long serialVersionUID = 3000119849197222007L;
058:
059: /**
060: * Unit for milliseconds. Usefull for conversion from and to {@link Date} objects.
061: */
062: public static Unit MILLISECOND = SI.MILLI(SI.SECOND);
063:
064: /**
065: * A converter from values in this CRS to values in milliseconds.
066: * Will be constructed only when first needed.
067: */
068: private transient Converter toMillis;
069:
070: /**
071: * The {@linkplain TemporalDatum#getOrigin origin} in milliseconds since January 1st, 1970.
072: * This field could be implicit in the {@link #toMillis} converter, but we still handle it
073: * explicitly in order to use integer arithmetic.
074: */
075: private transient long origin;
076:
077: /**
078: * Constructs a new temporal CRS with the same values than the specified one.
079: * This copy constructor provides a way to wrap an arbitrary implementation into a
080: * Geotools one or a user-defined one (as a subclass), usually in order to leverage
081: * some implementation-specific API. This constructor performs a shallow copy,
082: * i.e. the properties are not cloned.
083: *
084: * @since 2.2
085: *
086: * @see #wrap
087: */
088: public DefaultTemporalCRS(final TemporalCRS crs) {
089: super (crs);
090: }
091:
092: /**
093: * Constructs a temporal CRS from a name.
094: *
095: * @param name The name.
096: * @param datum The datum.
097: * @param cs The coordinate system.
098: */
099: public DefaultTemporalCRS(final String name,
100: final TemporalDatum datum, final TimeCS cs) {
101: this (Collections.singletonMap(NAME_KEY, name), datum, cs);
102: }
103:
104: /**
105: * Constructs a temporal CRS from a set of properties. The properties are given unchanged to
106: * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
107: *
108: * @param properties Set of properties. Should contains at least <code>"name"</code>.
109: * @param cs The coordinate system.
110: * @param datum The datum.
111: */
112: public DefaultTemporalCRS(final Map properties,
113: final TemporalDatum datum, final TimeCS cs) {
114: super (properties, datum, cs);
115: }
116:
117: /**
118: * Wraps an arbitrary temporal CRS into a Geotools implementation. This method is usefull
119: * if the user wants to take advantage of {@link #toDate} and {@link #toValue} methods.
120: * If the supplied CRS is already an instance of {@code DefaultTemporalCRS} or is {@code null},
121: * then it is returned unchanged.
122: */
123: public static DefaultTemporalCRS wrap(final TemporalCRS crs) {
124: if (crs == null || crs instanceof DefaultTemporalCRS) {
125: return (DefaultTemporalCRS) crs;
126: }
127: return new DefaultTemporalCRS(crs);
128: }
129:
130: /**
131: * Initialize the fields required for {@link #toDate} and {@link #toValue} operations.
132: */
133: private void initializeConverter() {
134: origin = ((TemporalDatum) datum).getOrigin().getTime();
135: toMillis = coordinateSystem.getAxis(0).getUnit()
136: .getConverterTo(MILLISECOND);
137: }
138:
139: /**
140: * Convert the given value into a {@link Date} object.
141: * This method is the converse of {@link #toValue}.
142: *
143: * @param value A value in this axis unit.
144: * @return The value as a {@linkplain Date date}.
145: */
146: public Date toDate(final double value) {
147: if (toMillis == null) {
148: initializeConverter();
149: }
150: return new Date(Math.round(toMillis.convert(value)) + origin);
151: }
152:
153: /**
154: * Convert the given {@linkplain Date date} into a value in this axis unit.
155: * This method is the converse of {@link #toDate}.
156: *
157: * @param time The value as a {@linkplain Date date}.
158: * @return value A value in this axis unit.
159: */
160: public double toValue(final Date time) {
161: if (toMillis == null) {
162: initializeConverter();
163: }
164: return toMillis.inverse().convert(time.getTime() - origin);
165: }
166:
167: /**
168: * Returns a hash value for this geographic CRS.
169: *
170: * @return The hash code value. This value doesn't need to be the same
171: * in past or future versions of this class.
172: */
173: public int hashCode() {
174: return (int) serialVersionUID ^ super.hashCode();
175: }
176: }
|