/* * Geotools 2 - OpenSource mapping toolkit * (C) 2003, Geotools Project Management Committee (PMC) * (C) 2002, Institut de Recherche pour le Développement * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.geotools.cv; // J2SE dependencies import java.awt.Color; import java.lang.ref.Reference; import java.rmi.RemoteException; import java.util.Locale; import javax.media.jai.PropertySource; import org.geotools.pt.CoordinatePoint; import org.geotools.pt.Envelope; import org.geotools.resources.RemoteProxy; import org.geotools.resources.i18n.ErrorKeys; import org.geotools.resources.i18n.Errors; import org.geotools.units.Unit; import org.opengis.coverage.CannotEvaluateException; import org.opengis.cv.CV_ColorInterpretation; import org.opengis.cv.CV_Coverage; import org.opengis.cv.CV_PaletteInterpretation; import org.opengis.cv.CV_SampleDimension; import org.opengis.cv.CV_SampleDimensionType; /** * Provide methods for interoperability with OpenGIS CV package. * All methods accept null argument. This class has no default instance, since the * {@link org.geotools.gp.Adapters org.geotools.gp.Adapters} * implementation cover this case. * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux * * @see org.geotools.gp.Adapters#getDefault() * * @deprecated The legacy OpenGIS CV package is deprecated. * There is no replacement at this time for RMI objects. */ public class Adapters { /** * The adapters from Coordinate Transformation Services * (package org.geotools.ct). */ public final org.geotools.ct.Adapters CTS; /** * Default constructor. A shared instance of Adapters can * be obtained with {@link org.geotools.gp.Adapters#getDefault()}. * * @param CTS The adapters from Coordinate Transformation Services * (package org.geotools.ct). */ protected Adapters(final org.geotools.ct.Adapters CTS) { this.CTS = CTS; } /** * Returns an OpenGIS enumeration for a color interpretation. * * @param colors The Geotools object. * @return The OpenGIS object. */ public CV_ColorInterpretation export(final ColorInterpretation colors) { if (colors == null) { return null; } return new CV_ColorInterpretation(colors.getValue()); } /** * Returns an OpenGIS enumeration for a color interpretation. * * @param type The Geotools object. * @return The OpenGIS object. */ public CV_SampleDimensionType export(final SampleDimensionType type) { if (type == null) { return null; } return new CV_SampleDimensionType(type.getValue()); } /** * Returns an OpenGIS interface for a sample dimension. * * @param dimension The Geotools object. * @return The OpenGIS object. * @throws RemoteException if the OpenGIS object can't be exported. */ public CV_SampleDimension export(final SampleDimension dimension) throws RemoteException { if (dimension == null) { return null; } return (CV_SampleDimension) dimension.toOpenGIS(this); } /** * Returns an OpenGIS interface for a coverage. * * @param coverage The Geotools object. * @return The OpenGIS object. * @throws RemoteException if the OpenGIS object can't be exported. */ public CV_Coverage export(final Coverage coverage) throws RemoteException { if (coverage == null) { return null; } Object proxy = coverage.proxy; if (proxy instanceof Reference) { proxy = ((Reference) proxy).get(); } if (proxy != null) { return (CV_Coverage) proxy; } return doExport(coverage); } /** * Performs the wrapping of a Geotools object. This method is invoked by * {@link #export(Coverage)} if an OpenGIS object is not already presents * in the cache. Subclasses should override this method instead of * {@link #export(Coverage)}. * * @param coverage The Geotools object. * @return The OpenGIS object. * @throws RemoteException if the OpenGIS object can't be exported. */ protected CV_Coverage doExport(final Coverage coverage) throws RemoteException { return coverage.new Export(this); } /** * Returns a color interpretation from an OpenGIS's enumeration. * * @param colors The OpenGIS object. * @return The Geotools object. */ public ColorInterpretation wrap(final CV_ColorInterpretation colors) { return (colors!=null) ? ColorInterpretation.getEnum(colors.value) : null; } /** * Returns a sample type from an OpenGIS's enumeration. * * @param type The OpenGIS object. * @return The Geotools object. */ public SampleDimensionType wrap(final CV_SampleDimensionType type) { return (type!=null) ? SampleDimensionType.getEnum(type.value) : null; } /** * Returns a sample dimension from an OpenGIS's interface. * * @param sd The OpenGIS object. * @return The Geotools object. * @throws RemoteException if an operation failed while querying the OpenGIS object. */ public SampleDimension wrap(final CV_SampleDimension sd) throws RemoteException { if (sd == null) { return null; } if (sd instanceof RemoteProxy) { return (SampleDimension) ((RemoteProxy) sd).getImplementation(); } return doWrap(sd); } /** * Returns a sample dimension from an OpenGIS's interface. This implementation is made * available separatly from {@link #wrap(CV_SampleDimension)} in order to allow tests * with JUnit. * * @param sd The OpenGIS object. * @return The Geotools object. * @throws RemoteException if an operation failed while querying the OpenGIS object. */ final SampleDimension doWrap(final CV_SampleDimension sd) throws RemoteException { if (sd.getPaletteInterpretation().value != CV_PaletteInterpretation.CV_RGB) { throw new UnsupportedOperationException("Not yet implemented"); } String description = sd.getDescription(); SampleDimensionType type = SampleDimensionType.getEnum(sd.getSampleDimensionType().value); ColorInterpretation color = ColorInterpretation.getEnum(sd.getColorInterpretation().value); int[][] palette = sd.getPalette(); String[] categories = sd.getCategoryNames(); double[] nodata = sd.getNoDataValue(); double minimum = sd.getMinimumValue(); double maximum = sd.getMaximumValue(); double scale = sd.getScale(); double offset = sd.getOffset(); Unit units = CTS.wrap(sd.getUnits()); Color[] colors = null; if (palette != null) { colors = new Color[palette.length]; for (int i=0; iand this * Adapters is an instance of the {@link org.geotools.gc.Adapters * org.geotools.gc.Adapters} class, then the returned coverage * implementation will be an instance of {@link org.geotools.gc.GridCoverage}. * * @param coverage The OpenGIS object. * @return The Geotools object. * @throws RemoteException if an operation failed while querying the OpenGIS object. */ public Coverage wrap(final CV_Coverage coverage) throws RemoteException { if (coverage == null) { return null; } if (coverage instanceof Coverage.Export) { return ((Coverage.Export) coverage).getImplementation(); } final Coverage wrapped = doWrap(coverage); wrapped.proxy = coverage; return wrapped; } /** * Performs the wrapping of an OpenGIS's interface. This method is invoked by * {@link #wrap(CV_Coverage)} if a Geotools object is not already presents in * the cache. Subclasses should override this method instead of * {@link #wrap(CV_Coverage)}. * * @param coverage The OpenGIS object. * @return The Geotools object. * @throws RemoteException if an operation failed while querying the OpenGIS object. */ protected Coverage doWrap(final CV_Coverage coverage) throws RemoteException { try { return new CoverageProxy(coverage); } catch (RuntimeException exception) { final Throwable cause = exception.getCause(); if (cause instanceof RemoteException) { // May occurs when the PropertySourceImpl constructor // fetch values from the CoverageProperties adapter. throw (RemoteException) cause; } throw exception; } } /** * Returns the {@link PropertySource} for the specified OpenGIS's coverage. If the * specified coverage already implements {@link PropertySource}, then it is returned. * Otherwise, the coverage is wrapped in an object with the following behaviour: * * * @param coverage The OpenGIS coverage. * @return The property source for the specified coverage. */ protected PropertySource getPropertySource(final CV_Coverage coverage) { if (coverage == null) { return null; } if (coverage instanceof PropertySource) { return (PropertySource) coverage; } return new CoverageProperties(coverage); } /** * An adapter class for {@link CV_Coverage}. Every call to an evaluate * method is delegates to the underlying {@link CV_Coverage}, which may be executed * on a remote machine. {@link RemoteException} are catched and rethrown as a * {@link CannotEvaluateException}. * * @version $Id$ * @author Martin Desruisseaux */ private final class CoverageProxy extends Coverage { /** * The wrapped OpenGIS coverage. This reference * must be the same than {@link Coverage#proxy}. */ private final CV_Coverage coverage; /** * The bounding box for the coverage domain in coordinate system coordinates. */ private final Envelope envelope; /** * The names of each dimension in this coverage. */ private final String[] dimensionNames; /** * The sample dimensions for this coverage. * Will be fetch only when first requested. */ private SampleDimension[] dimensions; /** * Construct a new coverage wrapping the specified OpenGIS object. * * @param coverage The OpenGIS coverage. * @throws RemoteException if a remote call failed. * @throws CannotEvaluateException if the construction failed for some other reason. * The cause for this exception may be a {@link RemoteException}. Callers * should check the cause and throw the underlying {@link RemoteException} * if applicable. */ CoverageProxy(CV_Coverage coverage) throws RemoteException { super(null, CTS.wrap(coverage.getCoordinateSystem()), getPropertySource(coverage), null); this.coverage = coverage; this.proxy = coverage; this.envelope = CTS.wrap(coverage.getEnvelope()); dimensionNames = coverage.getDimensionNames(); } /** * Returns the bounding box for the coverage domain in coordinate system coordinates. */ public Envelope getEnvelope() { return (Envelope) envelope.clone(); } /** * Returns the names of each dimension in this coverage. */ public String[] getDimensionNames(final Locale locale) { return (String[]) dimensionNames.clone(); } /** * Retrieve sample dimension information for the coverage. */ public synchronized SampleDimension[] getSampleDimensions() { if (dimensions == null) try { dimensions = new SampleDimension[coverage.getNumSampleDimensions()]; for (int i=0; i