Package org.geotools.coverage.processing

Source Code of org.geotools.coverage.processing.BaseStatisticsOperationJAI

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
*
*    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;
*    version 2.1 of the License.
*
*    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.
*/
package org.geotools.coverage.processing;

import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

import javax.media.jai.JAI;
import javax.media.jai.OperationDescriptor;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.ROIShape;
import javax.media.jai.StatisticsOpImage;
import javax.media.jai.registry.RenderedRegistryMode;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.metadata.iso.citation.Citations;
import org.geotools.parameter.DefaultParameterDescriptor;
import org.geotools.parameter.ImagingParameterDescriptors;
import org.geotools.parameter.ImagingParameters;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.transform.ProjectiveTransform;
import org.geotools.util.logging.Logging;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Polygon;

/**
* This class is the root class for the Statistics operations based on
* {@link JAI}'s {@link StatisticsOpImage} like Extrema and Histogram. It
* provides basic capabilities for management of geospatial parameters like
* {@link javax.media.jai.ROI}s and subsampling factors.
*
* @author Simone Giannecchini
* @since 2.4.x
*
*
*
*
* @source $URL$
*/
public abstract class BaseStatisticsOperationJAI extends
    OperationJAI {
 
  /**
   *
   */
  private static final long serialVersionUID = 6830028735162290160L;

  /** {@link Logger} for this class. */
  public final static Logger LOGGER = Logging.getLogger("org.geotools.coverage.processing");

  /**
   * The parameter descriptor for the SPATIAL_SUBSAMPLING_X
   */
  public static final ParameterDescriptor<Double> SPATIAL_SUBSAMPLING_X = new DefaultParameterDescriptor<Double>(
      Citations.JAI, "xPeriod", Double.class, // Value class (mandatory)
      null, // Array of valid values
      null, // Default value
      null, // Minimal value
      null, // Maximal value
      null, // Unit of measure
      true);

  /**
   * The parameter descriptor for the SPATIAL_SUBSAMPLING_Y
   */
  public static final ParameterDescriptor<Double> SPATIAL_SUBSAMPLING_Y = new DefaultParameterDescriptor<Double>(
      Citations.JAI, "yPeriod", Double.class, // Value class (mandatory)
      null, // Array of valid values
      null, // Default value
      null, // Minimal value
      null, // Maximal value
      null, // Unit of measure
      true);

  /**
   * The parameter descriptor for the Region Of Interest.
   */
  public static final ParameterDescriptor<Polygon> ROI = new DefaultParameterDescriptor<Polygon>(
      Citations.JAI, "roi", Polygon.class, // Value class (mandatory)
      null, // Array of valid values
      null, // Default value
      null, // Minimal value
      null, // Maximal value
      null, // Unit of measure
      true);

  private static Set<ParameterDescriptor> REPLACED_DESCRIPTORS;

  static {
    final Set<ParameterDescriptor> replacedDescriptors = new HashSet<ParameterDescriptor>();
    replacedDescriptors.add( SPATIAL_SUBSAMPLING_X);
    replacedDescriptors.add( SPATIAL_SUBSAMPLING_Y);
    replacedDescriptors.add( ROI);
    REPLACED_DESCRIPTORS = Collections.unmodifiableSet(replacedDescriptors);
  }

  /**
   * Constructor for {@link BaseStatisticsOperationJAI}.
   *
   * @param operationDescriptor
   *            {@link OperationDescriptor} for the underlying JAI operation.
   */
  public BaseStatisticsOperationJAI(OperationDescriptor operationDescriptor) {
    super(operationDescriptor, new ImagingParameterDescriptors(
        getOperationDescriptor(operationDescriptor.getName()),
        REPLACED_DESCRIPTORS));
  }

  /**
   * Constructor for {@link BaseStatisticsOperationJAI}.
   *
   * @param operationDescriptor
   *            {@link OperationDescriptor} for the underlying JAI operation.
   * @param replacements
   *            {@link ImagingParameterDescriptors} that should replace the
   *            correspondent {@link ImagingParameters} in order to change the
   *            default behavior they have inside JAI.
   */
  public BaseStatisticsOperationJAI(
      OperationDescriptor operationDescriptor,
      ImagingParameterDescriptors replacements) {
    super(operationDescriptor, new ImagingParameterDescriptors(
        ImagingParameterDescriptors.properties(operationDescriptor),
        operationDescriptor, RenderedRegistryMode.MODE_NAME,
        ImagingParameterDescriptors.DEFAULT_SOURCE_TYPE_MAP, REPLACED_DESCRIPTORS));
  }
    /**
   * Constructor for {@link BaseStatisticsOperationJAI}.
   * @param name of the underlying JAI operation.
   */
  public BaseStatisticsOperationJAI(String name) {
    super(getOperationDescriptor(name),new ImagingParameterDescriptors(
        getOperationDescriptor(name),
        new HashSet<ParameterDescriptor>(REPLACED_DESCRIPTORS)));
  }

  /**
     * Copies parameter values from the specified {@link ParameterValueGroup} to the
     * {@link ParameterBlockJAI}
     *
     * @param parameters
     *            The {@link ParameterValueGroup} to be copied.
     * @return A copy of the provided {@link ParameterValueGroup} as a JAI block.
     *
     * @see org.geotools.coverage.processing.OperationJAI#prepareParameters(org.opengis.parameter.ParameterValueGroup)
   */
  protected ParameterBlockJAI prepareParameters(ParameterValueGroup parameters) {
    // /////////////////////////////////////////////////////////////////////
    //
    // Make a copy of the input parameters.
    //
    // ///////////////////////////////////////////////////////////////////
    final ImagingParameters copy = (ImagingParameters) descriptor
        .createValue();
    final ParameterBlockJAI block = (ParameterBlockJAI) copy.parameters;
    try {

      // /////////////////////////////////////////////////////////////////////
      //
      //
      // Now transcode the parameters as needed by this operation.
      //
      //
      // ///////////////////////////////////////////////////////////////////
      // XXX make it robust
      final GridCoverage2D source = (GridCoverage2D) parameters
          .parameter(operation.getSourceNames()[PRIMARY_SOURCE_INDEX])
          .getValue();
      final AffineTransform gridToWorldTransformCorrected = new AffineTransform(
          (AffineTransform) ((GridGeometry2D) source
              .getGridGeometry())
              .getGridToCRS2D(PixelOrientation.UPPER_LEFT));
      final MathTransform worldToGridTransform;
      try {
        worldToGridTransform = ProjectiveTransform
            .create(gridToWorldTransformCorrected.createInverse());
      } catch (NoninvertibleTransformException e) {
        // //
        //
        // Something bad happened here, namely the transformation to go
        // from grid to world was not invertible. Let's wrap and
        // propagate the error.
        //
        // //
        final CoverageProcessingException ce = new CoverageProcessingException(
            e);
        throw ce;
      }
     
      // //
      //
      // get the original envelope and the crs
      //
      // //
      final CoordinateReferenceSystem crs = source
          .getCoordinateReferenceSystem2D();
      final Envelope2D envelope = source.getEnvelope2D();     

      // /////////////////////////////////////////////////////////////////////
      //
      // Transcode the xPeriod and yPeriod parameters by applying the
      // WorldToGrid transformation for the source coverage.
      //
      // I am assuming that the supplied values are in the same CRS as the
      // source coverage. We here apply
      //
      // /////////////////////////////////////////////////////////////////////
      final double xPeriod = parameters.parameter("xPeriod")
          .doubleValue();
      final double yPeriod = parameters.parameter("yPeriod")
          .doubleValue();
      if(!Double.isNaN(xPeriod)&&!Double.isNaN(yPeriod)){

        // build the new one that spans over the requested area
        // NOTE:
        final DirectPosition2D LLC = new DirectPosition2D(crs, envelope.x,
            envelope.y);
        LLC.setCoordinateReferenceSystem(crs);
        final DirectPosition2D URC = new DirectPosition2D(crs, envelope.x
            + xPeriod, envelope.y + yPeriod);
        URC.setCoordinateReferenceSystem(crs);
        final Envelope2D shrinkedEnvelope = new Envelope2D(LLC, URC);
 
        // transform back into raster space
        final Rectangle2D transformedEnv = CRS.transform(
            worldToGridTransform, shrinkedEnvelope).toRectangle2D();
 
        // block settings
        block.setParameter("xPeriod", Integer.valueOf((int) transformedEnv
            .getWidth()));
        block.setParameter("yPeriod", Integer.valueOf((int) transformedEnv
            .getHeight()));
      }
      // /////////////////////////////////////////////////////////////////////
      //
      // Transcode the polygon parameter into a roi.
      //
      // I am assuming that the supplied values are in the same
      // CRS as the source coverage. We here apply
      //
      // /////////////////////////////////////////////////////////////////////
      final Object o = parameters.parameter("roi").getValue();
      if (o != null && o instanceof Polygon) {
        final Polygon roiInput = (Polygon) o;
        if (new ReferencedEnvelope(roiInput.getEnvelopeInternal(),
            source.getCoordinateReferenceSystem2D())
            .intersects((Envelope) new ReferencedEnvelope(envelope))) {
          final java.awt.Polygon shapePolygon = convertPolygon(
              roiInput, worldToGridTransform);

          block.setParameter("roi", new ROIShape(shapePolygon));
        }
      }
      return block;
    } catch (Exception e) {
      // //
      //
      // Something bad happened here Let's wrap and propagate the error.
      //
      // //
      final CoverageProcessingException ce = new CoverageProcessingException(
          e);
      throw ce;
    }
  }

  /**
   * Converte a JTS {@link Polygon}, which represents a ROI, into an AWT
   * {@link java.awt.Polygon} by means of the provided {@link MathTransform}.
   *
   * @param roiInput
   *            the input ROI as a JTS {@link Polygon}.
   * @param worldToGridTransform
   *            the {@link MathTransform} to apply to the input ROI.
   * @return an AWT {@link java.awt.Polygon}.
   * @throws TransformException
   *             in case the provided {@link MathTransform} chokes.
   */
  private static java.awt.Polygon convertPolygon(final Polygon roiInput,
      MathTransform worldToGridTransform) throws TransformException {
    final boolean isIdentity = worldToGridTransform.isIdentity();
    final java.awt.Polygon retValue = new java.awt.Polygon();
    final double coords[] = new double[2];
    final LineString exteriorRing = roiInput.getExteriorRing();
    final CoordinateSequence exteriorRingCS = exteriorRing
        .getCoordinateSequence();
    final int numCoords = exteriorRingCS.size();
    for (int i = 0; i < numCoords; i++) {
      // get the actual coord
      coords[0] = exteriorRingCS.getX(i);
      coords[1] = exteriorRingCS.getY(i);

      // transform it
      if (!isIdentity)
        worldToGridTransform.transform(coords, 0, coords, 0, 1);

      // send it back to the returned polygon
      retValue.addPoint((int) (coords[0] + 0.5d),
          (int) (coords[1] + 0.5d));

    }

    // return the created polygon.
    return retValue;
  }
}
TOP

Related Classes of org.geotools.coverage.processing.BaseStatisticsOperationJAI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.