001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2004, 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.cs;
021:
022: // J2SE dependencies
023: import java.util.List;
024: import java.util.Arrays;
025: import java.util.Collections;
026:
027: // OpenGIS dependencies
028: import org.opengis.referencing.cs.CoordinateSystem;
029: import org.opengis.referencing.cs.CoordinateSystemAxis;
030:
031: // Geotools dependencies
032: import org.geotools.referencing.AbstractIdentifiedObject;
033:
034: /**
035: * A coordinate system made of two or more independent coordinate systems.
036: *
037: * <TABLE CELLPADDING='6' BORDER='1'>
038: * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
039: * <TR><TD>
040: * {@link org.geotools.referencing.crs.DefaultCompoundCRS Compound}
041: * </TD></TR></TABLE>
042: *
043: * @since 2.1
044: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultCompoundCS.java $
045: * @version $Id: DefaultCompoundCS.java 20874 2006-08-07 10:00:01Z jgarnett $
046: * @author Martin Desruisseaux
047: */
048: public class DefaultCompoundCS extends AbstractCS {
049: /**
050: * Serial number for interoperability with different versions.
051: */
052: private static final long serialVersionUID = -5726410275278843372L;
053:
054: /**
055: * The coordinate systems.
056: */
057: private final CoordinateSystem[] cs;
058:
059: /**
060: * An immutable view of {@link #cs} as a list. Will be created only when first needed.
061: */
062: private transient List/*<CoordinateSystem>*/asList;
063:
064: /**
065: * Constructs a compound coordinate system. A name for this CS will
066: * be automatically constructed from the name of all specified CS.
067: *
068: * @param cs The set of coordinate syztem.
069: */
070: public DefaultCompoundCS(CoordinateSystem[] cs) {
071: super (getName(cs = clone(cs)), getAxis(cs));
072: this .cs = cs;
073: }
074:
075: /**
076: * Returns a clone of the specified array. This method would be bundle right
077: * into the constructor if RFE #4093999 was fixed.
078: */
079: private static CoordinateSystem[] clone(CoordinateSystem[] cs) {
080: ensureNonNull("cs", cs);
081: cs = (CoordinateSystem[]) cs.clone();
082: for (int i = 0; i < cs.length; i++) {
083: ensureNonNull("cs", cs, i);
084: }
085: return cs;
086: }
087:
088: /**
089: * Returns the axis of all coordinate systems.
090: */
091: private static CoordinateSystemAxis[] getAxis(
092: final CoordinateSystem[] cs) {
093: int count = 0;
094: for (int i = 0; i < cs.length; i++) {
095: count += cs[i].getDimension();
096: }
097: final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[count];
098: count = 0;
099: for (int i = 0; i < cs.length; i++) {
100: final CoordinateSystem c = cs[i];
101: final int dim = c.getDimension();
102: for (int j = 0; j < dim; j++) {
103: axis[count++] = c.getAxis(j);
104: }
105: }
106: assert count == axis.length;
107: return axis;
108: }
109:
110: /**
111: * Constructs a name from a merge of the name of all coordinate systems.
112: *
113: * @param cs The coordinate systems.
114: * @param locale The locale for the name.
115: */
116: private static String getName(final CoordinateSystem[] cs) {
117: final StringBuffer buffer = new StringBuffer();
118: for (int i = 0; i < cs.length; i++) {
119: if (buffer.length() != 0) {
120: buffer.append(" / ");
121: }
122: buffer.append(cs[i].getName().getCode());
123: }
124: return buffer.toString();
125: }
126:
127: /**
128: * Returns all coordinate systems in this compound CS.
129: */
130: public List/*<CoordinateSystem>*/getCoordinateSystems() {
131: if (asList == null) {
132: // No need to synchronize; this is not a big deal if two lists are created.
133: asList = Collections.unmodifiableList(Arrays.asList(cs));
134: }
135: return asList;
136: }
137:
138: /**
139: * Compares this coordinate system with the specified object for equality.
140: *
141: * @param object The object to compare to {@code this}.
142: * @param compareMetadata {@code true} for performing a strict comparaison, or
143: * {@code false} for comparing only properties relevant to transformations.
144: * @return {@code true} if both objects are equal.
145: */
146: public boolean equals(final AbstractIdentifiedObject object,
147: final boolean compareMetadata) {
148: if (object == this ) {
149: return true; // Slight optimization.
150: }
151: if (super .equals(object, compareMetadata)) {
152: final DefaultCompoundCS that = (DefaultCompoundCS) object;
153: return equals(this .cs, that.cs, compareMetadata);
154: }
155: return false;
156: }
157: }
|