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.operation;
021:
022: // J2SE dependencies
023: import java.util.Map;
024:
025: // OpenGIS dependencies
026: import org.opengis.referencing.crs.CoordinateReferenceSystem;
027: import org.opengis.referencing.operation.MathTransform;
028: import org.opengis.referencing.operation.MathTransformFactory;
029: import org.opengis.referencing.operation.PassThroughOperation;
030: import org.opengis.referencing.operation.Operation;
031:
032: // Geotools dependencies
033: import org.geotools.referencing.operation.transform.PassThroughTransform;
034: import org.geotools.referencing.wkt.Formatter;
035: import org.geotools.util.UnsupportedImplementationException;
036:
037: /**
038: * A pass-through operation specifies that a subset of a coordinate tuple is subject to a specific
039: * coordinate operation.
040: *
041: * @since 2.1
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultPassThroughOperation.java $
043: * @version $Id: DefaultPassThroughOperation.java 24607 2007-02-26 22:05:40Z desruisseaux $
044: * @author Martin Desruisseaux
045: */
046: public class DefaultPassThroughOperation extends DefaultSingleOperation
047: implements PassThroughOperation {
048: /**
049: * Serial number for interoperability with different versions.
050: */
051: private static final long serialVersionUID = 4308173919747248695L;
052:
053: /**
054: * The operation to apply on the subset of a coordinate tuple.
055: */
056: protected final Operation operation;
057:
058: /**
059: * Constructs a single operation from a set of properties. The properties given in argument
060: * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
061: * Affected ordinates will range from {@code firstAffectedOrdinate}
062: * inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
063: *
064: * @param properties Set of properties. Should contains at least <code>"name"</code>.
065: * @param sourceCRS The source CRS.
066: * @param targetCRS The target CRS.
067: * @param operation The operation to apply on the subset of a coordinate tuple.
068: * @param firstAffectedOrdinate Index of the first affected ordinate.
069: * @param numTrailingOrdinates Number of trailing ordinates to pass through.
070: */
071: public DefaultPassThroughOperation(final Map properties,
072: final CoordinateReferenceSystem sourceCRS,
073: final CoordinateReferenceSystem targetCRS,
074: final Operation operation, final int firstAffectedOrdinate,
075: final int numTrailingOrdinates) {
076: // TODO: Uncomment if Sun fix RFE #4093999
077: // ensureNonNull("operation", operation);
078: this (properties, sourceCRS, targetCRS, operation,
079: PassThroughTransform.create(firstAffectedOrdinate,
080: operation.getMathTransform(),
081: numTrailingOrdinates));
082: }
083:
084: /**
085: * Constructs a single operation from a set of properties and the given transform.
086: * The properties given in argument follow the same rules than for the
087: * {@link AbstractCoordinateOperation} constructor.
088: *
089: * @param properties Set of properties. Should contains at least <code>"name"</code>.
090: * @param sourceCRS The source CRS.
091: * @param targetCRS The target CRS.
092: * @param operation The operation to apply on the subset of a coordinate tuple.
093: * @param transform The {@linkplain MathTransformFactory#createPassThroughTransform
094: * pass through transform}.
095: */
096: public DefaultPassThroughOperation(final Map properties,
097: final CoordinateReferenceSystem sourceCRS,
098: final CoordinateReferenceSystem targetCRS,
099: final Operation operation, final MathTransform transform) {
100: super (properties, sourceCRS, targetCRS, transform);
101: this .operation = operation;
102: ensureNonNull("operation", operation);
103: ensureValidDimension(operation.getSourceCRS(), transform
104: .getSourceDimensions());
105: ensureValidDimension(operation.getTargetCRS(), transform
106: .getTargetDimensions());
107: }
108:
109: /**
110: * Ensure that the dimension of the specified CRS is not greater than the specified value.
111: */
112: private static void ensureValidDimension(
113: final CoordinateReferenceSystem crs, final int dim) {
114: if (crs.getCoordinateSystem().getDimension() > dim) {
115: throw new IllegalArgumentException(); // TODO: provides a localized message.
116: }
117: }
118:
119: /**
120: * Returns the operation to apply on the subset of a coordinate tuple.
121: *
122: * @return The operation.
123: */
124: public Operation getOperation() {
125: return operation;
126: }
127:
128: /**
129: * Ordered sequence of positive integers defining the positions in a coordinate
130: * tuple of the coordinates affected by this pass-through operation. The returned
131: * index are for source coordinates.
132: *
133: * @return The modified coordinates.
134: *
135: * @todo Current version work only with Geotools implementation.
136: */
137: public int[] getModifiedCoordinates() {
138: if (!(transform instanceof PassThroughTransform)) {
139: throw new UnsupportedImplementationException(transform
140: .getClass());
141: }
142: return ((PassThroughTransform) transform)
143: .getModifiedCoordinates();
144: }
145:
146: /**
147: * {@inheritDoc}
148: */
149: protected String formatWKT(final Formatter formatter) {
150: final String name = super .formatWKT(formatter);
151: try {
152: final int[] ordinates = getModifiedCoordinates();
153: for (int i = 0; i < ordinates.length; i++) {
154: formatter.append(ordinates[i]);
155: }
156: } catch (UnsupportedOperationException exception) {
157: // Ignore: no indices will be formatted.
158: formatter.setInvalidWKT(PassThroughOperation.class);
159: }
160: formatter.append(operation);
161: return name;
162: }
163: }
|