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; either
010: * version 2.1 of the License, or (at your option) any later version.
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: package org.geotools.coverage.processing;
018:
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import org.opengis.parameter.ParameterDescriptor;
023: import org.opengis.parameter.ParameterDescriptorGroup;
024: import org.opengis.parameter.ParameterValueGroup;
025: import org.opengis.parameter.ParameterNotFoundException;
026: import org.opengis.parameter.InvalidParameterValueException;
027: import org.opengis.referencing.IdentifiedObject;
028:
029: import org.geotools.factory.Hints;
030: import org.geotools.coverage.FactoryFinder;
031: import org.geotools.coverage.grid.GridCoverage2D;
032: import org.geotools.coverage.grid.GridCoverageFactory;
033: import org.geotools.coverage.grid.ViewType;
034: import org.geotools.metadata.iso.citation.Citations;
035: import org.geotools.parameter.DefaultParameterDescriptor;
036: import org.geotools.referencing.NamedIdentifier;
037: import org.geotools.resources.Utilities;
038: import org.geotools.resources.i18n.Errors;
039: import org.geotools.resources.i18n.ErrorKeys;
040:
041: /**
042: * An operation working on {@link GridCoverage2D} sources.
043: *
044: * @since 2.1
045: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/coverage/processing/Operation2D.java $
046: * @version $Id: Operation2D.java 26799 2007-08-31 21:31:21Z desruisseaux $
047: * @author Martin Desruisseaux
048: */
049: public abstract class Operation2D extends AbstractOperation {
050: /**
051: * Serial number for interoperability with different versions.
052: */
053: private static final long serialVersionUID = 574096338873406394L;
054:
055: /**
056: * Index of the source {@link GridCoverage2D} to use as a model. The destination grid coverage
057: * will reuse the same coordinate reference system, envelope and qualitative categories than
058: * this primary source.
059: * <p>
060: * For operations expecting only one source, there is no ambiguity. But for operations
061: * expecting more than one source, the choice of a primary source is somewhat arbitrary.
062: * This constant is used merely as a flag for spotting those places in the code.
063: *
064: * @since 2.4
065: */
066: protected static final int PRIMARY_SOURCE_INDEX = 0;
067:
068: /**
069: * Convenience constant for the first source {@link GridCoverage2D}. The parameter name
070: * is {@code "Source"} (as specified in OGC implementation specification) and the alias
071: * is {@code "source0"} (for compatibility with <cite>Java Advanced Imaging</cite>).
072: */
073: public static final ParameterDescriptor SOURCE_0;
074: static {
075: final Map properties = new HashMap(4);
076: properties.put(IdentifiedObject.NAME_KEY, new NamedIdentifier(
077: Citations.OGC, "Source"));
078: properties.put(IdentifiedObject.ALIAS_KEY, new NamedIdentifier(
079: Citations.JAI, "source0"));
080: SOURCE_0 = new DefaultParameterDescriptor(properties,
081: GridCoverage2D.class, null, null, null, null, null,
082: true);
083: }
084:
085: /**
086: * Constructs an operation. The operation name will be the same than the
087: * parameter descriptor name.
088: *
089: * @param descriptor The parameters descriptor.
090: */
091: public Operation2D(final ParameterDescriptorGroup descriptor) {
092: super (descriptor);
093: }
094:
095: /**
096: * Returns {@code true} if grid coverage content should be converted from sample values
097: * to geophysics value before to apply an operation. This method is invoked automatically
098: * by {@link OperationJAI#doOperation doOperation}. If this method returns {@code true},
099: * then the computation will be performed on the <cite>geophysics</cite> view as returned
100: * by <code>{@linkplain GridCoverage2D#geophysics GridCoverage2D.geophysics}(true)</code>.
101: * If this method returns {@code false}, then the view will <strong>not</strong> be changed
102: * before the operation is applied (i.e. the {@code geophysics} method is not invoked at all).
103: * The default implementation always returns {@code true}.
104: *
105: * @param parameters The parameters supplied by the user to the {@code doOperation} method.
106: * @return {@code true} if this operation should be applied on geophysics values.
107: *
108: * @see GridCoverage2D#geophysics
109: *
110: * @since 2.4
111: */
112: protected boolean computeOnGeophysicsValues(
113: final ParameterValueGroup parameters) {
114: return true;
115: }
116:
117: /**
118: * Extracts and prepares the sources for this {@code Operation2D}, taking into account the
119: * need for going to the geophysics view of the data in case this operation requires so.
120: * <p>
121: * This method fills the {@code sources} array with needed sources, changing to their
122: * geophysics view if needed.
123: *
124: * @param parameters Parameters that will control this operation.
125: * @param sourceNames Names of the sources to extract from {@link ParameterValueGroup}.
126: * @param sources On input, an array with the same length than {@code sourceNames}.
127: * On output, the {@link GridCoverage2D} to be used as sources for
128: * this operation.
129: * @return The type of the {@linkplain #PRIMARY_SOURCE_INDEX primary source},
130: * or {@code null} if unknow or if the type should not be changed.
131: *
132: * @throws IllegalArgumentException
133: * if an argument is {@code null}, or if {@code sources} and
134: * {@code sourceNames} doesn't have length.
135: * @throws ParameterNotFoundException
136: * if a required source has not been found.
137: * @throws InvalidParameterValueException
138: * if a source doesn't contain a value of type {@link GridCoverage2D}.
139: *
140: * @since 2.4
141: */
142: protected ViewType extractSources(
143: final ParameterValueGroup parameters,
144: final String[] sourceNames, final GridCoverage2D[] sources)
145: throws ParameterNotFoundException,
146: InvalidParameterValueException {
147: ensureNonNull("parameters", parameters);
148: ensureNonNull("sourceNames", sourceNames);
149: ensureNonNull("sources", sources);
150: if (sources.length != sourceNames.length) {
151: throw new IllegalArgumentException(Errors
152: .format(ErrorKeys.MISMATCHED_ARRAY_LENGTH));
153: }
154: ViewType type = null;
155: final boolean computeOnGeophysicsValues = computeOnGeophysicsValues(parameters);
156: for (int i = 0; i < sourceNames.length; i++) {
157: Object candidate = parameters.parameter(sourceNames[i])
158: .getValue();
159: if (!(candidate instanceof GridCoverage2D)) {
160: throw new InvalidParameterValueException(Errors.format(
161: ErrorKeys.ILLEGAL_CLASS_$2, Utilities
162: .getShortClassName(candidate),
163: Utilities.getShortName(GridCoverage2D.class)),
164: sourceNames[i], candidate);
165: }
166: GridCoverage2D source = (GridCoverage2D) candidate;
167: if (computeOnGeophysicsValues) {
168: final GridCoverage2D old = source;
169: source = source.geophysics(true);
170: if (i == PRIMARY_SOURCE_INDEX) {
171: type = (old == source) ? ViewType.GEOPHYSICS
172: : ViewType.DISPLAYABLE;
173: }
174: }
175: sources[i] = source;
176: }
177: return type;
178: }
179:
180: /**
181: * Returns the factory to use for creating new {@link GridCoverage2D} objects.
182: *
183: * @since 2.2
184: */
185: protected static GridCoverageFactory getFactory(final Hints hints) {
186: return FactoryFinder.getGridCoverageFactory(hints);
187: }
188: }
|