Package org.geotools.renderer.lite.gridcoverage2d

Source Code of org.geotools.renderer.lite.gridcoverage2d.BandSelectionNode

/*
*    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.renderer.lite.gridcoverage2d;

import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.util.List;

import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.processing.CoverageProcessor;
import org.geotools.coverage.processing.operation.SelectSampleDimension;
import org.geotools.factory.Hints;
import org.geotools.renderer.i18n.ErrorKeys;
import org.geotools.renderer.i18n.Errors;
import org.geotools.renderer.i18n.Vocabulary;
import org.geotools.renderer.i18n.VocabularyKeys;
import org.geotools.styling.SelectedChannelType;
import org.geotools.util.SimpleInternationalString;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.util.InternationalString;

/**
* This  {@link CoverageProcessingNode}  has been built for taking care of the band select operation within the context of applying SLD 1.0.
* @author  Simone Giannecchini, GeoSolutions.
*/
class BandSelectionNode extends StyleVisitorCoverageProcessingNodeAdapter
    implements CoverageProcessingNode {

  /*
   * (non-Javadoc)
   * @see CoverageProcessingNode#getName()
   */
  public InternationalString getName() {
    return Vocabulary.formatInternational(VocabularyKeys.BAND_SELECTION);
  }
 
  /**
     * Index of the band we want to select.
     * @uml.property  name="bandIndex"
     */
  private int bandIndex = -1;

  /**
   * Default constructor.
   *
   * <p>
   * A band selection node can have at most one source node.
   */
  public BandSelectionNode() {
    this(null);
  }

  /**
   * Default constructor.
   *
   * <p>
   * A band selection node can have at most one source node.
   *
   * @param hints
   *            {@link Hints} to contro internal machinery for factories,
   */
  public BandSelectionNode(Hints hints) {
    super(
        1,
        hints,
        SimpleInternationalString.wrap("BandSelectionNode"),
        SimpleInternationalString
            .wrap("Node which applies a BandSelection following SLD 1.0 spec."));
  }

  /*
   * (non-Javadoc)
   *
   * @see org.geotools.renderer.lite.gridcoverage2d.BaseCoverageProcessingNode#execute()
   */
  protected GridCoverage2D execute() {
    // preconditions
    assert this.getSources().size() <= 1;

    // /////////////////////////////////////////////////////////////////////
    //
    // Get the sources and see what we got to do. Note that if we have more
    // than once source we'll use only the first one but we'll
    //
    // /////////////////////////////////////////////////////////////////////
    final List<CoverageProcessingNode> sources = this.getSources();
    if (sources != null && !sources.isEmpty()) {
      final GridCoverage2D source = (GridCoverage2D) getSource(0).getOutput();
      GridCoverageRendererUtilities.ensureSourceNotNull(source, this.getName().toString());
      GridCoverage2D output = null;
      if (bandIndex != -1) {
        // /////////////////////////////////////////////////////////////////////
        //
        // We have a valid band index, go ahead and to a band select
        //
        // /////////////////////////////////////////////////////////////////////

        // //
        //
        // Is the index correct?
        //
        // //
        final int numSampleDimensions = source.getNumSampleDimensions();
        if (bandIndex < 1 || bandIndex > numSampleDimensions)
          throw new IllegalArgumentException(
              Errors.format(ErrorKeys.BAD_BAND_NUMBER_$1,Integer.valueOf(bandIndex)));

        // //
        //
        // SHORTCUT
        //
        // Are we trying to do a band select on a single band coverage?
        // Note that we already checked that the index is valid.
        //
        // //
        if (bandIndex == 1 && numSampleDimensions == 1) {
          output = source;

        } else {
          // //
          //
          // Do the actual band selection.
          //
          // //
          final CoverageProcessor processor = new CoverageProcessor(
              this.getHints());
          // get the source
          final ParameterValueGroup parameters = processor
              .getOperation("SelectSampleDimension")
              .getParameters();
          parameters.parameter("SampleDimensions").setValue(
              new int[] { bandIndex - 1 });
          parameters.parameter("Source").setValue(source);

          // //
          //
          // Save the output
          //
          // //
          final Hints hints = new Hints(getHints());
          final ImageLayout layout = new ImageLayout();
          final RenderedImage sourceRaster = source
              .getRenderedImage();
          final SampleModel oldSM = sourceRaster.getSampleModel();
          final ColorModel cm = new ComponentColorModel(ColorSpace
              .getInstance(ColorSpace.CS_GRAY), false, false,
              Transparency.OPAQUE, oldSM.getDataType());
          layout.setColorModel(cm);
          layout.setSampleModel(cm.createCompatibleSampleModel(oldSM
              .getWidth(), oldSM.getHeight()));
          hints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
          output = (GridCoverage2D) new SelectSampleDimension()
              .doOperation(parameters, hints);
        }

        // postcondition
        assert output.getNumSampleDimensions() == 1;
      } else
        // /////////////////////////////////////////////////////////////////////
        //
        // We do not have a valid band index, let's try with a
        // conservative approach that is, let's forward the source
        // coverage intact.
        // TODO better throwing an error?
        // /////////////////////////////////////////////////////////////////////
        output = source;


      return output;

    }
    throw new IllegalStateException("No source was set for this Node.");

  }

  public void visit(SelectedChannelType sct) {
    // /////////////////////////////////////////////////////////////////////
    //
    // If a SelectedChannelType was provided, let's try to parse it.
    //
    // /////////////////////////////////////////////////////////////////////
    if (sct != null) {
      final String name = sct.getChannelName();
      try {
        bandIndex = Integer.parseInt(name);
      } catch (NumberFormatException e) {
        // something bad happened
        final IllegalArgumentException iee = new IllegalArgumentException(
            Errors.format(ErrorKeys.BAD_BAND_NUMBER_$1,Integer.valueOf(bandIndex)));
        iee.initCause(e);
        throw iee;
      }
      return;
    }

    // /////////////////////////////////////////////////////////////////////
    //
    // If no SelectedChannelType was provided, let's just forward the
    // source.
    //
    // /////////////////////////////////////////////////////////////////////
    // do nothing
  }

  /**
     * Retrieves the band index we use for this  {@link BandSelectionNode} . <p> <code>-1</code> warns about a possible error.
     * @return  the bandIndex
     * @uml.property  name="bandIndex"
     */
  public int getBandIndex() {
    return bandIndex;
  }

}
TOP

Related Classes of org.geotools.renderer.lite.gridcoverage2d.BandSelectionNode

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.