Index: render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/TestLinearClassifier.java =================================================================== --- render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/TestLinearClassifier.java (revision 37083) +++ render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/TestLinearClassifier.java (working copy) @@ -41,6 +41,9 @@ import junit.framework.TestCase; import org.geotools.TestData; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMap; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMapElement; +import org.geotools.renderer.lite.gridcoverage2d.colormap.RasterClassifier; import org.geotools.resources.image.ComponentColorModelJAI; import org.geotools.util.NumberRange; import org.junit.Before; Index: render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerTest.java =================================================================== --- render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerTest.java (revision 37083) +++ render/src/test/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerTest.java (working copy) @@ -70,6 +70,7 @@ import org.geotools.test.TestData; import org.junit.Test; import org.opengis.style.ContrastMethod; +import org.opengis.style.OverlapBehavior; import com.sun.media.jai.widget.DisplayJAI; @@ -178,7 +179,7 @@ chSel.setGrayChannel(chTypeGray); rsb_1.setChannelSelection(chSel); rsb_1.setOpacity(sldBuilder.literalExpression(1.0)); - rsb_1.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_1.setOverlapBehavior(OverlapBehavior.AVERAGE); // visit the RasterSymbolizer rsh_StyleBuilder.visit(rsb_1); @@ -238,7 +239,7 @@ final SelectedChannelType chTypeGray_2 = new SelectedChannelTypeImpl(); final ContrastEnhancement cntEnh_2 = new ContrastEnhancementImpl(); - cntEnh_2.setLogarithmic(); + cntEnh_2.setMethod(ContrastMethod.LOGARITHMIC); //cntEnh.setType(type); //cntEnh.setGammaValue(sldBuilder.literalExpression(0.50)); @@ -306,7 +307,7 @@ final SelectedChannelType chTypeGray_3 = new SelectedChannelTypeImpl(); final ContrastEnhancement cntEnh_3 = new ContrastEnhancementImpl(); - cntEnh_3.setExponential(); + cntEnh_3.setMethod(ContrastMethod.EXPONENTIAL); //cntEnh.setType(type); //cntEnh.setGammaValue(sldBuilder.literalExpression(0.50)); @@ -315,7 +316,7 @@ chSel_3.setGrayChannel(chTypeGray_3); rsb_3.setChannelSelection(chSel_3); rsb_3.setOpacity(sldBuilder.literalExpression(1.0)); - rsb_3.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_3.setOverlapBehavior(OverlapBehavior.AVERAGE); // visit the RasterSymbolizer rsh_StyleBuilder.visit(rsb_3); @@ -381,7 +382,7 @@ final ChannelSelection chSel = new ChannelSelectionImpl(); final SelectedChannelType chTypeGray = new SelectedChannelTypeImpl(); final ContrastEnhancement cntEnh = new ContrastEnhancementImpl(); - cntEnh.setLogarithmic(); + cntEnh.setMethod(ContrastMethod.LOGARITHMIC); chTypeGray.setChannelName("1"); chTypeGray.setContrastEnhancement(cntEnh); chSel.setGrayChannel(chTypeGray); @@ -472,7 +473,7 @@ rsb_1.setChannelSelection(chSel); rsb_1.setOpacity(sldBuilder.literalExpression(1.0)); - rsb_1.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_1.setOverlapBehavior(OverlapBehavior.AVERAGE); final ColorMap cm = sldBuilder.createColorMap( new String[] { // labels @@ -577,7 +578,7 @@ rsb_1.setChannelSelection(chSel); rsb_1.setOpacity(sldBuilder.literalExpression(1.0)); rsb_1.setContrastEnhancement(cntEnh); - rsb_1.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_1.setOverlapBehavior(OverlapBehavior.AVERAGE); // visit the RasterSymbolizer rsh.visit(rsb_1); @@ -670,7 +671,7 @@ rsb_1.setChannelSelection(chSel); rsb_1.setOpacity(sldBuilder.literalExpression(1.0)); rsb_1.setContrastEnhancement(cntEnh); - rsb_1.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_1.setOverlapBehavior(OverlapBehavior.AVERAGE); // visit the RasterSymbolizer rsh.visit(rsb_1); @@ -754,7 +755,7 @@ rsb_1.setChannelSelection(chSel); rsb_1.setOpacity(sldBuilder.literalExpression(1.0)); rsb_1.setContrastEnhancement(cntEnh); - rsb_1.setOverlap(sldBuilder.literalExpression("AVERAGE")); + rsb_1.setOverlapBehavior(OverlapBehavior.AVERAGE); final ColorMap cm = sldBuilder.createColorMap( new String[] { // labels Index: render/src/main/java/org/geotools/renderer/lite/OpacityFinder.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/OpacityFinder.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/OpacityFinder.java (working copy) @@ -33,7 +33,6 @@ import org.geotools.styling.LineSymbolizer; import org.geotools.styling.Mark; import org.geotools.styling.NamedLayer; -import org.geotools.styling.OverlapBehavior; import org.geotools.styling.PointPlacement; import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PolygonSymbolizer; @@ -50,6 +49,7 @@ import org.geotools.styling.UserLayer; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; +import org.opengis.style.OverlapBehavior; /** Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ConstantColorMapElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ConstantColorMapElement.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ConstantColorMapElement.java (working copy) @@ -1,95 +0,0 @@ -/* - * 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.Color; - -import org.geotools.util.NumberRange; - -/** - * The {@link ConstantColorMapElement} is a special type of - * {@link ColorMapTransformElement} that is used to render no data values. - * - * @author Simone Giannecchini, GeoSolutions. - * @todo simplify - */ -class ConstantColorMapElement extends LinearColorMapElement - implements ColorMapTransformElement { - - /** - * - */ - private static final long serialVersionUID = -4754147707013696371L; - - ConstantColorMapElement(CharSequence name, final Color color, - final NumberRange inRange, final int outVal) - throws IllegalArgumentException { - super(name, new Color[] { color }, inRange, NumberRange.create(outVal, - outVal)); - } - - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - ConstantColorMapElement(final CharSequence name, - final Color color, final short value, final int sample) - throws IllegalArgumentException { - this(name, color , NumberRange.create(value, value), - sample); - - } - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - ConstantColorMapElement(final CharSequence name, - final Color color, final int value, final int sample) - throws IllegalArgumentException { - this(name, color , NumberRange.create(value, value), - sample); - - } - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - ConstantColorMapElement(final CharSequence name, - final Color color, final float value, final int sample) - throws IllegalArgumentException { - this(name, color , NumberRange.create(value, value), - sample); - - } - - - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - ConstantColorMapElement(final CharSequence name, - final Color color, final double value, final int sample) - throws IllegalArgumentException { - this(name, color , NumberRange.create(value, value), - sample); - - } - - - - -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterClassifier.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterClassifier.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterClassifier.java (working copy) @@ -1,389 +0,0 @@ -/* - * 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.Rectangle; -import java.awt.RenderingHints; -import java.awt.image.ColorModel; -import java.awt.image.RenderedImage; -import java.awt.image.SampleModel; -import java.awt.image.WritableRaster; -import java.awt.image.renderable.ParameterBlock; -import java.awt.image.renderable.RenderedImageFactory; - -import javax.media.jai.CRIFImpl; -import javax.media.jai.ImageLayout; -import javax.media.jai.JAI; -import javax.media.jai.OperationDescriptorImpl; -import javax.media.jai.PlanarImage; -import javax.media.jai.PointOpImage; -import javax.media.jai.iterator.RectIterFactory; -import javax.media.jai.iterator.WritableRectIter; -import javax.media.jai.registry.RenderedRegistryMode; -import javax.media.jai.util.ImagingException; - -import org.geotools.image.TransfertRectIter; -import org.geotools.image.jai.Registry; -import org.geotools.referencing.piecewise.DefaultDomain1D; -import org.geotools.referencing.piecewise.Domain1D; -import org.geotools.referencing.piecewise.PiecewiseTransform1DElement; -import org.geotools.renderer.i18n.ErrorKeys; -import org.geotools.renderer.i18n.Errors; - -/** - * Images are created using the {@code LinearClassifier.CRIF} inner class, where "CRIF" stands for {@link java.awt.image.renderable.ContextualRenderedImageFactory} . The image operation name is "org.geotools.RasterClassifier". - * - * @source $URL$ - * @version $Id$ - * @author Simone Giannecchini - GeoSolutions - * @since 2.4 - */ -@SuppressWarnings("unchecked") -public class RasterClassifier extends PointOpImage { - - /** - * The operation name. - */ - public static final String OPERATION_NAME = "org.geotools.RasterClassifier"; - - /** - * DomainElement1D lists for each bands. The array length must matches the number - * of bands in source image. - */ - private final ColorMapTransform pieces; - - /** - * The index (zero based) of the band we are going to classify - */ - private int bandIndex; - - /** - * Constructs a new {@code RasterClassifier}. - * - * @param image - * The source image. - * @param lic - * The category lists, one for each image's band. - * @param bandIndex - * @param hints - * The rendering hints. - */ - private RasterClassifier(final RenderedImage image, - final ColorMapTransform lic, int bandIndex, - final RenderingHints hints) { - super(image, prepareLayout(image, (ImageLayout) hints - .get(JAI.KEY_IMAGE_LAYOUT), lic), hints, false); - this.pieces = lic; - this.bandIndex = bandIndex; - permitInPlaceOperation(); - } - - /** - * Prepare the {@link ImageLayout} for the final image by building the - * {@link ColorModel} from the input - * - * @param image - * the image to classify. - * @param layout - * a proposed layout. - * @param lic - * the pieces we are asked to use. - * @return a layout suitable for the image that we'll create after this - */ - private static ImageLayout prepareLayout(RenderedImage image, - ImageLayout layout, ColorMapTransform lic) { - // // - // - // Get the final color model from the pieces and from that one - // create the sample model - // - // /// - final ColorModel finalColorModel = lic.getColorModel(); - // create a good sample model for the output raster - final SampleModel finalSampleModel = lic.getSampleModel(image - .getWidth(), image.getHeight()); - if (layout == null) - layout = new ImageLayout(); - layout.setColorModel(finalColorModel); - layout.setSampleModel(finalSampleModel); - return layout; - } - - /** - * Computes one of the destination image tile. - * - * @todo There are two optimisations we could do here: - *
    - *
  • If source and destination are the same raster, then a single - * {@link WritableRectIter} object would be more efficient (the hard - * work is to detect if source and destination are the same).
  • - *
  • If the destination image is a single-banded, non-interleaved - * sample model, we could apply the transform directly in the - * {@link java.awt.image.DataBuffer}. We can even avoid to copy - * sample value if source and destination raster are the same.
  • - *
- * - * @param sources - * An array of length 1 with source image. - * @param dest - * The destination tile. - * @param destRect - * the rectangle within the destination to be written. - */ - protected void computeRect(final PlanarImage[] sources, - final WritableRaster dest, final Rectangle destRect) { - final PlanarImage source = sources[0]; - WritableRectIter iterator = RectIterFactory.createWritable(dest, - destRect); - if (true) { - // TODO: Detect if source and destination rasters are the same. If - // they are the same, we should skip this block. Iteration will then - // be faster. - iterator = TransfertRectIter.create(RectIterFactory.create(source, - destRect), iterator); - } - - // //////////////////////////////////////////////////////////////////// - // - // Prepare the iterator to work on the correct bands, if this is - // requested. - // - // //////////////////////////////////////////////////////////////////// - if (!iterator.finishedBands()) { - for (int i = 0; i < bandIndex; i++) - iterator.nextBand(); - } - - // //////////////////////////////////////////////////////////////////// - // - // Check if we can make good use of a no data category for filling gaps - // in the input range - // - // //////////////////////////////////////////////////////////////////// - double gapsValue = Double.NaN; - boolean hasGapsValue = false; - if (this.pieces.hasDefaultValue()) { - gapsValue = this.pieces.getDefaultValue(); - hasGapsValue = true; - } - - // //////////////////////////////////////////////////////////////////// - // - // Check if we can optimize this operation by reusing the last used - // category first. The speed up we get can be substantial since we avoid - // n explicit search in the category list for the fitting category given - // a certain sample value. - // - // This is not possible when the NoDataCategories range overlaps with - // the range of the valid values. In this case we have ALWAYS to check - // first the NoDataRange when applying transformations. If we optimized - // in this case we would get erroneous results given to the fact that we - // might be reusing a valid sample category while we should be using a - // no data one. - // - // //////////////////////////////////////////////////////////////////// - PiecewiseTransform1DElement last = null; - final boolean useLast = pieces instanceof DefaultDomain1D; - do { - try { - iterator.startLines(); - if (!iterator.finishedLines()) - do { - iterator.startPixels(); - if (!iterator.finishedPixels()) - do { - // // - // - // get the input value to be transformed - // - // // - final double value = iterator.getSampleDouble(); - // // - // - // get the correct category for this - // transformation - // - // // - final PiecewiseTransform1DElement transform; - if (useLast) { - if (last != null && last.contains(value)) - transform = last; - else { - last = transform = pieces.findDomainElement(value); - } - } else - transform = (PiecewiseTransform1DElement) pieces.findDomainElement(value); - - // // - // - // in case everything went fine let's apply the - // transform. - // - // // - if (transform != null) - iterator.setSample(transform.transform(value)); - else { - // // - // - // if we did not find one let's try to use - // one of the nodata ones to fill the gaps, - // if we are allowed to (see above). - // - // // - if (hasGapsValue) - iterator.setSample(gapsValue); - else - - // // - // - // if we did not find one let's throw a - // nice error message - // - // // - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, Double.toString(value))); - } - - } while (!iterator.nextPixelDone()); - } while (!iterator.nextLineDone()); - } catch (Throwable cause) { - throw new ImagingException( - cause.getLocalizedMessage(),cause); - } - if (bandIndex != -1) - break; - } while (iterator.finishedBands()); - } - - // /////////////////////////////////////////////////////////////////////////////// - // ////// //////// - // ////// REGISTRATION OF "SampleTranscode" IMAGE OPERATION //////// - // ////// //////// - // /////////////////////////////////////////////////////////////////////////////// - /** - * The operation descriptor for the "SampleTranscode" operation. This - * operation can apply the - * {@link GridSampleDimension#getSampleToGeophysics sampleToGeophysics} - * transform on all pixels in all bands of an image. The transformations are - * supplied as a list of {@link GridSampleDimension}s, one for each band. - * The supplied {@code GridSampleDimension} objects describe the pieces - * in the source image. The target image will matches - * sample dimension - * - * {@link GridSampleDimension#geophysics geophysics}(!isGeophysics), - * - * where {@code isGeophysics} is the previous state of the sample dimension. - */ - private static final class Descriptor extends OperationDescriptorImpl { - /** - * - */ - private static final long serialVersionUID = 7954257625240335874L; - - /** - * Construct the descriptor. - */ - public Descriptor() { - super( - new String[][] { - { "GlobalName", OPERATION_NAME }, - { "LocalName", OPERATION_NAME }, - { "Vendor", "Geotools 2" }, - { "Description", - "Transformation from sample to geophysics values" }, - { "DocURL", "http://www.geotools.org/" }, - { "Version", "1.0" } }, - new String[] { RenderedRegistryMode.MODE_NAME }, 1, - new String[] { "Domain1D", "bandIndex" }, // Argument - // names - new Class[] { ColorMapTransform.class, - Integer.class }, // Argument - // classes - new Object[] { NO_PARAMETER_DEFAULT, Integer.valueOf(-1) }, // Default - // values - // for parameters, - null // No restriction on valid parameter values. - ); - } - - /** - * Returns {@code true} if the parameters are valids. This - * implementation check that the number of bands in the source image is - * equals to the number of supplied sample dimensions, and that all - * sample dimensions has pieces. - * - * @param modeName - * The mode name (usually "Rendered"). - * @param param - * The parameter block for the operation to performs. - * @param message - * A buffer for formatting an error message if any. - */ - protected boolean validateParameters(final String modeName, - final ParameterBlock param, final StringBuffer message) { - if (!super.validateParameters(modeName, param, message)) { - return false; - } - final RenderedImage source = (RenderedImage) param.getSource(0); - final Domain1D lic = (Domain1D) param.getObjectParameter(0); - if (lic == null) - return false; - final int numBands = source.getSampleModel().getNumBands(); - final int bandIndex = param.getIntParameter(1); - if (bandIndex == -1) - return true; - if (bandIndex < 0 || bandIndex >= numBands) { - return false; - } - return true; - } - } - - /** - * The {@link RenderedImageFactory} for the "SampleTranscode" operation. - */ - private static final class CRIF extends CRIFImpl { - /** - * Creates a {@link RenderedImage} representing the results of an - * imaging operation for a given {@link ParameterBlock} and - * {@link RenderingHints}. - */ - public RenderedImage create(final ParameterBlock param, - final RenderingHints hints) { - final RenderedImage image = (RenderedImage) param.getSource(0); - final ColorMapTransform lic = (ColorMapTransform) param.getObjectParameter(0); - final int bandIndex = param.getIntParameter(1); - return new RasterClassifier(image, lic, bandIndex, hints); - } - - } - - /** - * Register the RasterClassifier operation to the operation registry of the - * specified JAI instance. This method is invoked by the static initializer - * of {@link GridSampleDimension}. - * - * @param jai - * JAI instance in which we want to register the RasterClassifier - * operation. - * @return true if everything goes fine, false - * otherwise. - */ - public static boolean register(final JAI jai) { - return Registry.registerRIF(jai, new Descriptor(), OPERATION_NAME, - new CRIF()); - } -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SubchainStyleVisitorCoverageProcessingAdapter.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SubchainStyleVisitorCoverageProcessingAdapter.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SubchainStyleVisitorCoverageProcessingAdapter.java (working copy) @@ -67,7 +67,7 @@ super(maxSources, hints, name, description); } - public synchronized void dispose(boolean force) { + public void dispose(boolean force) { // dispose the graph of operations we set up dispose(sink, force); @@ -96,7 +96,7 @@ * @param sink * @uml.property name="sink" */ - protected synchronized void setSink(CoverageProcessingNode sink) { + protected void setSink(CoverageProcessingNode sink) { ensureNotNull(sink, "sink"); if (this.sink != null) throw new IllegalStateException(Errors @@ -109,7 +109,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.StyleVisitorCoverageProcessingNodeAdapter#execute() */ - public synchronized GridCoverage execute() { + public GridCoverage execute() { if (sink != null) { return sink.getOutput(); } Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMap.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMap.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMap.java (working copy) @@ -1,859 +0,0 @@ -/* - * 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.Color; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.PixelInterleavedSampleModel; -import java.awt.image.RenderedImage; -import java.awt.image.SampleModel; -import java.math.BigInteger; -import java.util.AbstractList; - -import org.geotools.geometry.GeneralDirectPosition; -import org.geotools.referencing.operation.matrix.Matrix1; -import org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement; -import org.geotools.referencing.piecewise.DefaultPiecewiseTransform1D; -import org.geotools.referencing.piecewise.PiecewiseTransform1DElement; -import org.geotools.renderer.i18n.ErrorKeys; -import org.geotools.renderer.i18n.Errors; -import org.geotools.resources.image.ColorUtilities; -import org.geotools.util.NumberRange; -import org.geotools.util.SimpleInternationalString; -import org.geotools.util.Utilities; -import org.opengis.geometry.DirectPosition; -import org.opengis.geometry.MismatchedDimensionException; -import org.opengis.referencing.operation.MathTransform1D; -import org.opengis.referencing.operation.Matrix; -import org.opengis.referencing.operation.NoninvertibleTransformException; -import org.opengis.referencing.operation.TransformException; -import org.opengis.util.InternationalString; - -/** - * @author Simone Giannecchini, GeoSolutions. - * - * @source $URL$ - */ -public final class LinearColorMap extends AbstractList - implements ColorMapTransform { - - public final static class LinearColorMapType { - /** - * Values are displayed using a gradual ramp of colors. - */ - public static final int TYPE_RAMP = 1; - - /** - * Each value in the raster layer is to be displayed individually as - * single separate color. - */ - public static final int TYPE_VALUES = 3; - - /** - * Vales are grouped into classes in order to display each class with a - * single separate color. - */ - public static final int TYPE_INTERVALS = 2; - - - /** - * Validates the provided color map type. - * - * @param linearColorMapType - * @return false if we cannot valid the provided type, true otherwise. - */ - static public boolean validateColorMapTye(final int linearColorMapType){ - switch (linearColorMapType) { - case TYPE_RAMP:case TYPE_VALUES:case TYPE_INTERVALS: - return true; - default: - return false; - } - } - } - - /** - * @uml.property name="colorModel" - */ - private IndexColorModel colorModel; - - /** - * @uml.property name="standardElements" - * @uml.associationEnd multiplicity="(0 -1)" - */ - private final LinearColorMapElement[] standardElements; - - /** - * @uml.property name="preFilteringElements" - * @uml.associationEnd multiplicity="(0 -1)" - */ - private final LinearColorMapElement[] preFilteringElements; - - private final Color defaultColor; - - private DefaultPiecewiseTransform1D piecewise; - - private DefaultPiecewiseTransform1D preFilteringPiecewise; - - private Color preFilteringColor; - - /** - * @uml.property name="name" - */ - private InternationalString name; - - private int hashCode=-1; - - /** - * Constructor which creates a {@link LinearColorMap} without a - * {@link NoDataCategory}. Keep in mind that if the list has gaps, if you - * try to transform a value that falls into a gap you'll get a nice - * {@link TransformException}! - * - * @param categories - * the array of a categories to use for this - * {@link LinearColorMap}. - */ - public LinearColorMap( - final CharSequence name, - final LinearColorMapElement[] standardElements) { - this(name, standardElements, null); - - - } - - public LinearColorMap( - final CharSequence name, - final LinearColorMapElement[] standardElements, - final Color defColor) { - this(name, standardElements, null, defColor); - - - } - - public LinearColorMap( - final CharSequence name, - final LinearColorMapElement[] standardElements, - final LinearColorMapElement[] preFilteringElements, - final Color defaultColor) { - - - - ColorMapUtilities.ensureNonNull("name", name); - ColorMapUtilities.ensureNonNull("standardElements", standardElements); - this.name=SimpleInternationalString.wrap(name); - /////////////////////////////////////////////////////////////////////// - // - // Prefiltering transformation - // - //// - // - // All the prefiltering transformations must share the same color, hence - // they must point to the same int - // - // ///////////////////////////////////////////////////////////////////// - preliminarChecks(standardElements, preFilteringElements); - - /////////////////////////////////////////////////////////////////////// - // - // Checking that same int in output means same color - // - //// - // - // - // - // ///////////////////////////////////////////////////////////////////// - if(preFilteringElements!=null&&preFilteringElements.length>0) - { - this.preFilteringElements=(LinearColorMapElement[]) preFilteringElements.clone(); - Color color=this.preFilteringElements[0].getColors()[0]; - this.preFilteringColor=color; - - } - else - this.preFilteringElements=null; - - /////////////////////////////////////////////////////////////////////// - // - // Standard transformation - // - // ///////////////////////////////////////////////////////////////////// - this.standardElements=(LinearColorMapElement[]) standardElements.clone(); - - /////////////////////////////////////////////////////////////////////// - // - // Default color to fill gaps, if provided. - // - // ///////////////////////////////////////////////////////////////////// - this.defaultColor=defaultColor; - - - - } - - - - public LinearColorMap(String string, - LinearColorMapElement[] linearColorMapElements, - LinearColorMapElement[] linearColorMapElements2) { - this(string, linearColorMapElements, linearColorMapElements2, null); - } - - /** - * Performing additional check on the provided domain elements in order to - * control that we don't have any strange overlap in the output values which - * could leave to strange color effect. - * - * @param domainElements - * to check. - * @param nodata - * category if we have any. - * @return the original {@link LinearColorMapElement} if nothing went - * wrong. - */ - private static void preliminarChecks( - final LinearColorMapElement[] domainElements, - final LinearColorMapElement[] domainElementsToPreserve) { - - // ///////////////////////////////////////////////////////////////////// - // - // Cycle on all the domain elements to preserve - // - // ///////////////////////////////////////////////////////////////////// - ColorMapUtilities.checkPreservingElements(domainElementsToPreserve); - - // ///////////////////////////////////////////////////////////////////// - // - // Cycle on all the domain elements and compare them to all the others - // - // ///////////////////////////////////////////////////////////////////// - final int num = - domainElementsToPreserve != null ? - domainElements.length + domainElementsToPreserve.length - : domainElements.length; - for (int i = 0; i < num; i++) { - final DefaultLinearPiecewiseTransform1DElement c0 = - i >= domainElements.length ? - (DefaultLinearPiecewiseTransform1DElement) domainElementsToPreserve[i- domainElements.length]: - (DefaultLinearPiecewiseTransform1DElement) domainElements[i]; - final ColorMapTransformElement v0 = (ColorMapTransformElement) c0; - final NumberRange outRange0 = c0.getOutputRange(); - final Color[] colors0 = v0.getColors(); - final int minimum0 = (int) outRange0.getMinimum(); - final int maximum0 = (int) outRange0.getMaximum(); - // //////////////////////////////////////////////////////////////// - // - // Check the c0 categories with all the others - // - // //////////////////////////////////////////////////////////////// - for (int j = 0; j < num; j++) { - // don't check a category with itself. - if (j == i) - continue; - // // - // - // We allow two LinearColorMapElement output ranges to overlap only if they - // map to a single value and they use the same color for it. - // Every other case is marked as an error either because it is - // an error or because it was too hard to support. - // - // // - final DefaultLinearPiecewiseTransform1DElement c1 = - j >= domainElements.length ? ( - DefaultLinearPiecewiseTransform1DElement) domainElementsToPreserve[j- domainElements.length]: - (DefaultLinearPiecewiseTransform1DElement) domainElements[j]; - final ColorMapTransformElement v1 = (ColorMapTransformElement) c1; - final NumberRange outRange1 = c1.getOutputRange(); - if (outRange1.intersects(outRange0)) { - - // do they intersect? - if(!outRange0.intersects(outRange1)) - continue; - - // they intersect!!! - - - //check the values - final int minimum1 = (int) outRange1.getMinimum(); - final int maximum1 = (int) outRange1.getMaximum(); - final Color[] colors1 = v1.getColors(); - if (minimum1==maximum0&&colors0[colors0.length-1].equals(colors1[0])) - continue; - - if (minimum0==maximum1&&colors1[colors1.length-1].equals(colors0[0])) - continue; - - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, c0, c1)); - // now check the colors - -// if (colors1.length != colors0.length) -// throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, new Integer(colors0.length), new Integer(colors1.length))); -// if(!Arrays.equals(colors1, colors0)) -// throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, new Integer(colors1.length), new Integer(colors1.length))); - -// if (colors1.length != 1) -// throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, new Integer(colors1.length), new Integer(1))); -// -// if (!colors0[0].equals(colors1[0])) -// throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, colors0[0], colors1[0])); - - } - } - - } - } - - /** - * Returns a color model for this category list. This method builds up the color model from each category's colors (as returned by {@link #getColors} ). - * @param visibleBand The band to be made visible (usually 0). All other bands, if any will be ignored. - * @param numBands The number of bands for the color model (usually 1). The returned color model will renderer only the {@code visibleBand} and ignore the others, but the existence of all {@code numBands} will be at least tolerated. Supplemental bands, even invisible, are useful for processing with Java Advanced Imaging. - * @return The requested color model, suitable for {@link RenderedImage} objects with values in the {@link #getRange} range. - * @uml.property name="colorModel" - */ - public IndexColorModel getColorModel() { - initColorModel(); - return colorModel; - } - - private synchronized void initColorModel() { - if (colorModel == null) { - // ///////////////////////////////////////////////////////////////////// - // - // STEP 1 - // - ///// - // First of all let's create the palette for the standard values. - // Afterward we look for the right values for the default color and - // for the preserving values color if present since these could - // reuse the same colors used for the standard values. - // - // ///////////////////////////////////////////////////////////////////// - - // // - // - // Computes the number of entries required for the color - // palette. - // Note that in case the output range has non inclusive edges we - // have already taken that into account when building the outMax - // and outMin values hence we do not have to do that again. - // - // // - BigInteger bits = new BigInteger("0"); - final boolean preFilteringValuesPresent=preFilteringColor!=null; - int elementsCount = standardElements.length+(preFilteringValuesPresent?1:0); - int max=-1; - for (int i = 0; i < elementsCount; i++) { - final DefaultLinearPiecewiseTransform1DElement element = - i(preFilteringElements); - - // ///////////////////////////////////////////////////////////////////// - // - // STEP 2 - // - ///// - // Now, if we do not have any default color we can proceed, - // otherwise we got some work to do. First of all, we need to check - // if the colors we are asked to use for the special cases are - // already in use. In such a case we don't reserve another index in - // the palette for them. Otherwise we have to add the new colors and - // recreate the ASRGB array. - // - // ///////////////////////////////////////////////////////////////////// - final boolean lookForDefaultColor=defaultColor!=null; - boolean defaultColorFound=!lookForDefaultColor; - if(lookForDefaultColor){ - - //// - // - // Search in the color map if we have the requested colors - // - //// - int defaultColorIndex=-1; - for(int i=0;i(this.standardElements,defaultColorIndex); - else - { - //check the bit vector for the first place available - int i=0; - for(;i(this.standardElements,max-1); - } - - } - else - { - this.piecewise= new DefaultPiecewiseTransform1D(this.standardElements); - } - - colorModel = new IndexColorModel(ColorUtilities - .getBitCount(max), max, ARGB, 0, ColorUtilities - .getTransferType(max), bits); - } - - } - - /** - * Creates a {@link SampleModel} compatible with the underlying {@link ColorModel} having the specified width and height. - * @param width represents the width for the final {@link SampleModel} - * @param height represents the height for the final {@link SampleModel} - */ - public SampleModel getSampleModel(int width, int height) { - if(width<=0) - throw new IllegalArgumentException(org.geotools.resources.i18n.Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,"width",width)); - if(height<=0) - throw new IllegalArgumentException(org.geotools.resources.i18n.Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,"height",height)); - // // - // - // force color model computation - // - // // - initColorModel(); - - // // - // - // create a suitable color model - // NOTE: - // IndexColorModel seems to badly choose its sample model. As of JDK - // 1.4-rc1, it construct a ComponentSampleModel, which is drawn very - // slowly to the screen. A much faster sample model is - // PixelInterleavedSampleModel, which is the sample model used by - // BufferedImage for TYPE_BYTE_INDEXED. We should check if this is fixed - // in future J2SE release. - // - // // - return new PixelInterleavedSampleModel(this.colorModel - .getTransferType(), width, height, 1, width, new int[1]); - } - -// boolean canPiecewise() { -// checkOptimalJAIOps(); -// return canPiecewise; -// } -// -// boolean canRescale() { -// checkOptimalJAIOps(); -// return canRescale; -// } -// -// /** -// * Checks whether or not we can use the Rescale or Piecewise operation in -// * order to emulate the behavior of this {@link PiecewiseTransform1D}. -// */ -// private void checkOptimalJAIOps() { -// synchronized (scales) { -// if (offsets != null) -// return; -// -// /* -// * STEP 4 - Check if the transcoding could be done with a JAI's -// * "Rescale" or "Piecewise" operations. The "Rescale" operation -// * requires a completely linear relationship between the source and -// * the destination sample values. The "Piecewise" operation is less -// * strict: piecewise breakpoints are very similar to categories, but -// * the transformation for all categories still have to be linear. -// */ -// if (this.hasGaps() ) { -// // This is a shortcut that would lead us to avoid optimizations. -// // If we either have gaps in input or if the NoData set of -// // categories overlap the normal ones we avoid spending too much -// // in finding a way to since it might be counterproductive. At -// // latter time we could remove this simple checks and go a bit -// // deeper with the investigation. -// // Fallback on our "RasterClassifier". -// canPiecewise = canRescale = false; -// return; -// } -// final DomainElement1D[] elements = getDomainElements(); -// final int numCategories = elements.length; -// final LinearColorMapElement tcList[] = new LinearColorMapElement[numCategories]; -// System.arraycopy(elements, 0, tcList, 0, elements.length); -// Arrays.sort(tcList); -// float[] sourceBreakpoints = null; -// float[] targetBreakpoints = null; -// double expectedSource = Double.NaN; -// double expectedTarget = Double.NaN; -// int jbp = 0; // Break point index (vary with j) -// for (int j = 0; j < numCategories; j++) { -// final LinearColorMapElement element = tcList[j]; -// final MathTransform1D transform = element.accessTransform(); -// if (!(transform instanceof LinearTransform1D)) { -// -// // One category doesn't use a linear transformation. We -// // can't deal with that with "Rescale" or "Piecewise". -// // Fallback on our "RasterClassifier". -// canPiecewise = canRescale = false; -// break; -// } -// final LinearTransform1D lTransform = (LinearTransform1D) transform; -// double offset = lTransform.offset; -// double scale = lTransform.scale; -// if ((Double.isNaN(scale) || Double.isInfinite(scale)) -// && !Double.isNaN(offset)) { -// // One category doesn't use a linear transformation. We -// // can't deal with that with "Rescale" or "Piecewise". -// // Fallback on our "RasterClassifier". -// canRescale = false; -// canPiecewise = false; -// break; -// } else if (Double.isNaN(scale) || Double.isInfinite(scale)) -// scale = 0; -// // Allocates arrays the first time the loop is run up to this -// // point. Store scale and offset, and check if they still the -// // same. -// if (j == 0) { -// offsets = new double[1]; -// sourceBreakpoints = new float[numCategories * 2]; -// targetBreakpoints = new float[numCategories * 2]; -// breakpoints[0] = new float[][] { sourceBreakpoints, -// targetBreakpoints }; -// offsets[0] = offset; -// scales[0] = scale; -// } -// //@todo this is not always correct, especially when single valued classes falls in between -// if (offset != offsets[0] || scale != scales[0]) { -// canRescale = false; -// } -// // Compute breakpoints. -// final NumberRange range = (NumberRange) element -// .getRange(); -// final double minimum = range.getMinimum(true); -// final double maximum = range.getMaximum(true); -// final float sourceMin = (float) minimum; -// final float sourceMax = (float) maximum; -// final float targetMin = (float) (minimum * scale + offset); -// final float targetMax = (float) (maximum * scale + offset); -// assert sourceMin <= sourceMax : range; -// if (!Double.isNaN(expectedSource) -// && ColorMapUtilities.compare(minimum, expectedSource) <= 0) { -// if (!Double.isNaN(expectedTarget) -// && ColorMapUtilities.compare(targetMin, -// expectedTarget) <= 0) { -// // This breakpoint is identical to the previous one. Do -// // not duplicate; overwrites the previous one since this -// // one is likely to be more accurate. -// jbp--; -// } else { -// // Found a discontinuity!!! The "piecewise" operation is -// // not really designed for such case. The behavior -// // between the last breakpoint and the current one may -// // not be what the user expected. -// assert sourceBreakpoints[jbp - 1] < sourceMin : expectedSource; -// canPiecewise = false; -// -// } -// } else if (j != 0) { -// // Found a gap between the last category and the current -// // one. The "piecewise" operation may not behave as the user -// // expected for sample values falling in this gap. -// assert !(expectedSource > sourceMin) : expectedSource; -// canPiecewise = false; -// -// } -// sourceBreakpoints[jbp] = sourceMin; -// sourceBreakpoints[jbp + 1] = sourceMax; -// targetBreakpoints[jbp] = targetMin; -// targetBreakpoints[jbp + 1] = targetMax; -// jbp += 2; -// expectedSource = range.getMaximum(false); -// expectedTarget = expectedSource * scale + offset; -// -// } -// -// breakpoints[0][0] = sourceBreakpoints = XArray.resize( -// sourceBreakpoints, jbp); -// breakpoints[0][1] = targetBreakpoints = XArray.resize( -// targetBreakpoints, jbp); -// assert XArray.isSorted(sourceBreakpoints); -// } -// -// } -// -// /** -// * @return -// * @uml.property name="breakpoints" -// */ -// float[][][] getBreakpoints() { -// checkOptimalJAIOps(); -// return (float[][][]) breakpoints.clone(); -// } -// -// /** -// * @return -// * @uml.property name="offsets" -// */ -// double[] getOffsets() { -// checkOptimalJAIOps(); -// return (double[]) offsets.clone(); -// } -// -// /** -// * @return -// * @uml.property name="scales" -// */ -// double[] getScales() { -// checkOptimalJAIOps(); -// return (double[]) scales.clone(); -// } - - public LinearColorMapElement get(int index) { - if(index getApproximateDomainRange() { - initColorModel(); - return this.piecewise.getApproximateDomainRange(); - } - - public LinearColorMapElement findDomainElement(double sample) { - initColorModel(); - final boolean prefiltering=this.preFilteringElements != null; - LinearColorMapElement retValue=null; - if(prefiltering) - retValue= preFilteringPiecewise.findDomainElement(sample); - if(retValue==null) - retValue= piecewise.findDomainElement(sample); - return retValue; - } - - public LinearColorMapElement[] getDomainElements() { - return (LinearColorMapElement[]) this.standardElements.clone(); - } - - /** - * @return - * @uml.property name="name" - */ - public InternationalString getName() { - initColorModel(); - return this.name; - } - - public boolean hasGaps() { - initColorModel(); - return this.piecewise.hasGaps(); - } - - public double derivative(double value) throws TransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "derivate")); - } - - public double transform(double value) throws TransformException { - initColorModel(); - PiecewiseTransform1DElement transform=(PiecewiseTransform1DElement) findDomainElement(value); - if(transform!=null) - return transform.transform(value); - return this.preFilteringPiecewise.transform(value); - } - - public Matrix derivative(DirectPosition point) - throws MismatchedDimensionException, TransformException { - ColorMapUtilities.checkDimension(point); - return new Matrix1(derivative(point.getOrdinate(0))); - } - - /* - * (non-Javadoc) - * @see org.opengis.referencing.operation.MathTransform#getSourceDimensions() - */ - public int getSourceDimensions() { - return 1; - } - - /* - * (non-Javadoc) - * @see org.opengis.referencing.operation.MathTransform#getTargetDimensions() - */ - public int getTargetDimensions() { - return 1; - } - - public MathTransform1D inverse() throws NoninvertibleTransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - } - - public boolean isIdentity() { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - } - - public String toWKT() throws UnsupportedOperationException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - } - - public DirectPosition transform(DirectPosition ptSrc, DirectPosition ptDst) - throws MismatchedDimensionException, TransformException { - // ///////////////////////////////////////////////////////////////////// - // - // input checks - // - // ///////////////////////////////////////////////////////////////////// - ColorMapUtilities.ensureNonNull("ptSrc", ptSrc); - ColorMapUtilities.checkDimension(ptSrc); - if (ptDst == null) { - ptDst = new GeneralDirectPosition(1); - } else { - ColorMapUtilities.checkDimension(ptDst); - } - ptDst.setOrdinate(0, transform(ptSrc.getOrdinate(0))); - return ptDst; - } - - public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, - int numPts) throws TransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - - } - - public void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, - int numPts) throws TransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - - } - - public void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, - int numPts) throws TransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - - } - - public void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, - int numPts) throws TransformException { - throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1, "transform")); - - } - - @Override - public boolean equals(Object o) { - if(this==o) - return true; - if(!(o instanceof LinearColorMap)) - return false; - final LinearColorMap that=(LinearColorMap) o; - if(!Utilities.equals(name, that.name)) - return false; - if(!Utilities.equals(defaultColor, that.defaultColor)) - return false; - if(preFilteringColor!=that.preFilteringColor) - return false; - if(!Utilities.equals(preFilteringElements, that.preFilteringElements)) - return false; - if(!Utilities.equals(standardElements, that.standardElements)) - return false; - return piecewise.equals(that.piecewise); - - } - - @Override - public int hashCode() { - if(hashCode>=0) - return hashCode; - hashCode=37; - hashCode=Utilities.hash( name,hashCode); - hashCode=Utilities.hash( defaultColor,hashCode); - hashCode=Utilities.hash( preFilteringColor,hashCode); - hashCode=Utilities.hash( preFilteringElements,hashCode); - hashCode=Utilities.hash( standardElements,hashCode); - hashCode=Utilities.hash( piecewise,hashCode); - return hashCode; - - - } - } Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransform.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransform.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransform.java (working copy) @@ -1,55 +0,0 @@ -/* - * 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.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.SampleModel; - -import org.geotools.referencing.piecewise.PiecewiseTransform1D; - - - - -/** - * A {@link ColorMapTransform} is a special sub-interface of - * {@link PiecewiseTransform1D} that can be used to render raw data. - * - * @author Simone Giannecchini, GeoSolutions. - * - * - * @source $URL$ - */ -public interface ColorMapTransform extends PiecewiseTransform1D { - /** - * Retrieve the {@link ColorModel} associated to this - * {@link ColorMapTransform}. - * - * @return - */ - public IndexColorModel getColorModel(); - - /** - * Retrieve the {@link SampleModel} associated to this - * {@link ColorMapTransform}. - * - * @return - */ - public SampleModel getSampleModel(final int width, final int height); - - -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapUtilities.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapUtilities.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapUtilities.java (working copy) @@ -1,229 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-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.Color; - -import org.geotools.referencing.piecewise.DefaultPiecewiseTransform1DElement; -import org.geotools.renderer.i18n.ErrorKeys; -import org.geotools.renderer.i18n.Errors; -import org.opengis.geometry.DirectPosition; -import org.opengis.geometry.MismatchedDimensionException; - -class ColorMapUtilities { - - /** - * Codes ARGB par d�faut. On utilise un exemplaire unique pour toutes les - * cr�ation d'objets {@link LinearColorMapElement}. - */ - static final int[] DEFAULT_ARGB = { 0xFF000000, 0xFFFFFFFF }; - - /** - * Makes sure that an argument is non-null. - * - * @param name - * Argument name. - * @param object - * User argument. - * @throws IllegalArgumentException - * if {@code object} is null. - */ - static void ensureNonNull(final String name, - final Object object) throws IllegalArgumentException { - if (object == null) { - throw new IllegalArgumentException(Errors.format( - ErrorKeys.NULL_ARGUMENT_$1, name)); - } - } - - /** - * Compare deux valeurs de type {@code double}. Cette m�thode est similaire - * � {@link Double#compare(double,double)}, except� qu'elle ordonne aussi - * les diff�rentes valeurs NaN. - */ - static int compare(final double v1, final double v2) { - if (Double.isNaN(v1) && Double.isNaN(v2)) { - final long bits1 = Double.doubleToRawLongBits(v1); - final long bits2 = Double.doubleToRawLongBits(v2); - if (bits1 < bits2) - return -1; - if (bits1 > bits2) - return +1; - } - return Double.compare(v1, v2); - } - -// /** -// * Returns a linear transform with the supplied scale and offset values. -// * -// * @param scale -// * The scale factor. May be 0 for a constant transform. -// * @param offset -// * The offset value. May be NaN if this method is invoked from a -// * constructor for initializing {@link #transform} for a -// * qualitative category. -// */ -// static MathTransform1D createLinearTransform( -// final double scale, final double offset) { -// return LinearTransform1D.create(scale, offset); -// } -// -// /** -// * Create a linear transform mapping values from {@code sampleValueRange} to -// * {@code geophysicsValueRange}. -// */ -// static MathTransform1D createLinearTransform( -// final NumberRange sourceRange, final NumberRange destinationRange) { -// final Class sType = sourceRange.getElementClass(); -// final Class dType = destinationRange.getElementClass(); -// /* -// * First, find the direction of the adjustment to apply to the ranges if -// * we wanted all values to be inclusives. Then, check if the adjustment -// * is really needed: if the values of both ranges are inclusive or -// * exclusive, then there is no need for an adjustment before computing -// * the coefficient of a linear relation. -// */ -// int sMinInc = sourceRange.isMinIncluded() ? 0 : +1; -// int sMaxInc = sourceRange.isMaxIncluded() ? 0 : -1; -// int dMinInc = destinationRange.isMinIncluded() ? 0 : +1; -// int dMaxInc = destinationRange.isMaxIncluded() ? 0 : -1; -// -// /* -// * Now, extracts the minimal and maximal values and computes the linear -// * coefficients. -// */ -// final double minSource = doubleValue(sType, sourceRange.getMinValue(), -// sMinInc); -// final double maxSource = doubleValue(sType, sourceRange.getMaxValue(), -// sMaxInc); -// final double minDestination = doubleValue(dType, destinationRange -// .getMinValue(), dMinInc); -// final double maxDestination = doubleValue(dType, destinationRange -// .getMaxValue(), dMaxInc); -// -// // ///////////////////////////////////////////////////////////////// -// // -// // optimizations -// // -// // ///////////////////////////////////////////////////////////////// -// // // -// // -// // If the output range is a single value let's create a constant -// // transform -// // -// // // -// if (ColorMapUtilities.compare(minDestination, maxDestination) == 0) -// return LinearTransform1D.create(0, minDestination); -// -// // // -// // -// // If the input range is a single value this transform ca be created -// // only if we map to another single value -// // -// // // -// if (ColorMapUtilities.compare(minSource, maxSource) == 0) -// throw new IllegalArgumentException("Impossible to map a single value to a range."); -// -// double scale = (maxDestination - minDestination) -// / (maxSource - minSource); -// // ///////////////////////////////////////////////////////////////// -// // -// // Take into account the fact that the maxSample and the minSample can -// // be -// // similar hence we have a constant transformation. -// // -// // ///////////////////////////////////////////////////////////////// -// if (Double.isNaN(scale)) -// scale = 0; -// final double offset = minDestination - scale * minSource; -// return createLinearTransform(scale, offset); -// } -// -// /** -// * Returns a {@code double} value for the specified number. If -// * {@code direction} is non-zero, then this method will returns the closest -// * representable number of type {@code type} before or after the double -// * value. -// * -// * @param type -// * The range element class. {@code number} must be an instance of -// * this class (this will not be checked). -// * @param number -// * The number to transform to a {@code double} value. -// * @param direction -// * -1 to return the previous representable number, +1 to return -// * the next representable number, or 0 to return the number with -// * no change. -// */ -// static double doubleValue(final Class type, -// final Comparable number, final int direction) { -// assert (direction >= -1) && (direction <= +1) : direction; -// return XMath.rool(type, ((Number) number).doubleValue(), direction); -// } - - /** - * Ensure the specified point is one-dimensional. - */ - static void checkDimension(final DirectPosition point) { - final int dim = point.getDimension(); - if (dim != 1) { - throw new MismatchedDimensionException(Errors.format( - ErrorKeys.MISMATCHED_DIMENSION_$2, Integer.valueOf(1), - Integer.valueOf(dim))); - } - } - /** - * Check that all the output values for the various - * {@link DefaultConstantPiecewiseTransformElement} are equal. - * - * @param preservingElements - * array of {@link DefaultConstantPiecewiseTransformElement}s. - * @return the array of {@link DefaultConstantPiecewiseTransformElement}s if the check is - * successful. - * @throws IllegalArgumentException - * in case the check is unsuccessful. - */ - static DefaultPiecewiseTransform1DElement[] checkPreservingElements( - LinearColorMapElement[] preservingElements) { - if (preservingElements != null) { - double outval = Double.NaN; - Color color=null; - for (int i = 0; i < preservingElements.length; i++) { - //the no data element must be a linear transform mapping to a single value - if(!(preservingElements[i] instanceof ConstantColorMapElement)) - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, preservingElements)); - final ConstantColorMapElement nc = (ConstantColorMapElement) preservingElements[i]; - if(nc.getColors().length!=1) - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); - if (i == 0) - { - outval = nc.getOutputMaximum(); - color=nc.getColors()[0]; - } - else - { - if (compare(outval, nc.getOutputMaximum()) != 0) - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); - if (!color.equals(nc.getColors()[0])) - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); - } - - } - } - return preservingElements; - } -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ContrastEnhancementNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ContrastEnhancementNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ContrastEnhancementNode.java (working copy) @@ -26,9 +26,7 @@ import java.awt.image.renderable.ParameterBlock; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Set; import javax.media.jai.Histogram; import javax.media.jai.ImageLayout; @@ -63,6 +61,7 @@ import org.opengis.coverage.grid.GridCoverage; import org.opengis.filter.expression.Expression; import org.opengis.referencing.operation.TransformException; +import org.opengis.style.ContrastMethod; import org.opengis.util.InternationalString; /** @@ -93,25 +92,11 @@ } /** - * Specified the supported Histogram Enhancement algorithms. - * - * @todo in the future this should be pluggable. - */ - private final static Set SUPPORTED_HE_ALGORITHMS; - - /** * This are the different types f histogram equalization that we support for * the moment. MOre should be added soon. * */ static { - //load the contrast enhancement operations - final HashSet heAlg = new HashSet(2, 1.0f); - heAlg.add("NORMALIZE"); - heAlg.add("HISTOGRAM"); - heAlg.add("LOGARITHMIC"); - heAlg.add("EXPONENTIAL"); - SUPPORTED_HE_ALGORITHMS = Collections.unmodifiableSet(heAlg); //load, if it is needed the GenericPiecewise tranformation try{ @@ -124,7 +109,7 @@ } /** Histogram Enhancement algorithm to use. */ - private String type = null; + private ContrastMethod type = ContrastMethod.NONE; /** * Value we'll use for the gamma correction operation. @@ -136,7 +121,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.StyleVisitorAdapter#visit(org.geotools.styling.ContrastEnhancement) */ - public synchronized void visit(final ContrastEnhancement ce) { + public void visit(final ContrastEnhancement ce) { // ///////////////////////////////////////////////////////////////////// // // Do nothing if we don't have a valid ContrastEnhancement element. This @@ -151,14 +136,10 @@ // TYPE of the operation to perform // // ///////////////////////////////////////////////////////////////////// - final Expression expType = ce.getType(); - if (expType != null) { - final String type = expType.evaluate(null, String.class); - if (type != null) { - this.type = type.toUpperCase(); - if (!SUPPORTED_HE_ALGORITHMS.contains(type.toUpperCase())) - throw new IllegalArgumentException(Errors.format(ErrorKeys.OPERATION_NOT_FOUND_$1, type.toUpperCase())); - } + final ContrastMethod contrastMethod = ce.getMethod(); + if (contrastMethod != null) { + type = contrastMethod; + } // ///////////////////////////////////////////////////////////////////// @@ -228,7 +209,7 @@ if ((!Double.isNaN(gammaValue) && !Double.isInfinite(gammaValue) && !(Math.abs(gammaValue -1)<1E-6))|| - (type != null && type.length() > 0)) { + (type != null && !type.equals(ContrastMethod.NONE))) { // ///////////////////////////////////////////////////////////////////// // @@ -258,7 +239,7 @@ // //// RenderedImage initialImage; - if(type!=null&&type.equalsIgnoreCase("HISTOGRAM")) + if(type.equals(ContrastMethod.HISTOGRAM)) { initialImage = new ImageWorker(sourceImage) @@ -277,7 +258,6 @@ } final int numbands = initialImage.getSampleModel().getNumBands(); - // // // // Save the alpha band if present, in order to put it back @@ -486,7 +466,7 @@ private RenderedImage performContrastEnhancement( RenderedImage inputImage, final Hints hints) { - if (type != null && type.length() > 0) { + if (type != null && !type.equals(ContrastMethod.NONE)) { assert inputImage.getSampleModel().getNumBands() == 1:inputImage; final int dataType=inputImage.getSampleModel().getDataType(); @@ -497,8 +477,9 @@ // // // ///////////////////////////////////////////////////////////////////// - if (type.equalsIgnoreCase("NORMALIZE")) { + if (type.equals(ContrastMethod.NORMALIZE)) { //step 1 do the extrema to get the statistics for this image + final RenderedOp image = ExtremaDescriptor.create(inputImage, null, Integer.valueOf(1), Integer.valueOf(1), null, Integer.valueOf(1), null); @@ -569,7 +550,7 @@ // // // ///////////////////////////////////////////////////////////////////// - if (type.equalsIgnoreCase("EXPONENTIAL")) { + if (type.equals(ContrastMethod.EXPONENTIAL)) { if(dataType==DataBuffer.TYPE_BYTE){ //// @@ -647,7 +628,7 @@ return JAI.create( GenericPiecewise.OPERATION_NAME, pbj); } - if (type.equalsIgnoreCase("LOGARITHMIC")) { + if (type.equals(ContrastMethod.LOGARITHMIC)) { // ///////////////////////////////////////////////////////////////////// // // Logarithm Normalization @@ -735,7 +716,7 @@ return JAI.create( GenericPiecewise.OPERATION_NAME, pbj); } - if (type.equalsIgnoreCase("HISTOGRAM")) { + if (type.equals(ContrastMethod.HISTOGRAM)) { // ///////////////////////////////////////////////////////////////////// // // Histogram Equalization @@ -888,3 +869,4 @@ } + Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerHelper.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerHelper.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/RasterSymbolizerHelper.java (working copy) @@ -17,7 +17,6 @@ package org.geotools.renderer.lite.gridcoverage2d; import java.awt.image.DataBuffer; -import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; @@ -35,6 +34,7 @@ import org.geotools.styling.RasterSymbolizer; import org.geotools.styling.StyleVisitor; import org.geotools.util.SimpleInternationalString; +import org.geotools.util.Utilities; import org.opengis.coverage.grid.GridCoverage; /** @@ -54,7 +54,7 @@ * not be drawable. * @return {@link GridCoverage2D} the result of this operation */ - public synchronized GridCoverage2D execute() { + public GridCoverage2D execute() { /////////////////////////////////////////////////////////////////////// // // We get the geophysics view of this coverage and we check if we give away @@ -138,9 +138,9 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.StyleVisitorAdapter#visit(org.geotools.styling.RasterSymbolizer) */ - public synchronized void visit(RasterSymbolizer rs) { + public void visit(RasterSymbolizer rs) { - ColorMapUtilities.ensureNonNull("RasterSymbolizer", rs); + Utilities.ensureNonNull("RasterSymbolizer", rs); // ///////////////////////////////////////////////////////////////////// // Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandSelectionNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandSelectionNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandSelectionNode.java (working copy) @@ -196,7 +196,7 @@ } - public synchronized void visit(SelectedChannelType sct) { + public void visit(SelectedChannelType sct) { // ///////////////////////////////////////////////////////////////////// // // If a SelectedChannelType was provided, let's try to parse it. Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/StyleVisitorAdapter.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/StyleVisitorAdapter.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/StyleVisitorAdapter.java (working copy) @@ -35,7 +35,6 @@ import org.geotools.styling.LineSymbolizer; import org.geotools.styling.Mark; import org.geotools.styling.NamedLayer; -import org.geotools.styling.OverlapBehavior; import org.geotools.styling.PointPlacement; import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PolygonSymbolizer; @@ -50,6 +49,7 @@ import org.geotools.styling.Symbolizer; import org.geotools.styling.TextSymbolizer; import org.geotools.styling.UserLayer; +import org.opengis.style.OverlapBehavior; /** * Simple empty implementation for the {@link StyleVisitor} interface. Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMapElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMapElement.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/LinearColorMapElement.java (working copy) @@ -1,251 +0,0 @@ -/* - * 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.Color; -import java.awt.image.IndexColorModel; -import java.util.Arrays; - -import org.geotools.coverage.GridSampleDimension; -import org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement; -import org.geotools.referencing.piecewise.DomainElement1D; -import org.geotools.referencing.piecewise.PiecewiseTransform1DElement; -import org.geotools.renderer.i18n.ErrorKeys; -import org.geotools.renderer.i18n.Errors; -import org.geotools.renderer.lite.gridcoverage2d.LinearColorMap.LinearColorMapType; -import org.geotools.util.NumberRange; -import org.geotools.util.Utilities; -import org.opengis.referencing.operation.MathTransform1D; - -/** - * This {@link LinearColorMapElement} is a special implementation of both {@link PiecewiseTransform1DElement} and {@link ColorMapTransformElement} which can be used to do various types of classifications on raster. Specifically the supported types of classifications are unique values, classified and color ramps.

The supported types of classifications are {@link LinearColorMapType#TYPE_RAMP} , {@link LinearColorMapType#TYPE_VALUES} and {@link LinearColorMapType#TYPE_INTERVALS} . - * @see LinearColorMap - * @see LinearColorMap.LinearColorMapType - * @author Simone Giannecchini, GeoSolutions - * - * @source $URL$ - */ -public class LinearColorMapElement extends DefaultLinearPiecewiseTransform1DElement - implements PiecewiseTransform1DElement, ColorMapTransformElement { - - /** - * - */ - private static final long serialVersionUID = 2216106857184603629L; - - - /** - * {@link Color} s associated to this {@link ColorMapTransformElement} . - * @uml.property name="colors" - */ - private Color[] colors; - - - private int hashCode=-1; - - public static LinearColorMapElement create(final CharSequence name, - final Color[] colors, final NumberRange valueRange, - final NumberRange sampleRange) throws IllegalArgumentException { - return new LinearColorMapElement(name, colors, valueRange, sampleRange); - } - public static LinearColorMapElement create(CharSequence name, final Color color, - final NumberRange inRange, final int outVal) - throws IllegalArgumentException { - return new ConstantColorMapElement(name, color, inRange, outVal); - } - - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - public static LinearColorMapElement create(final CharSequence name, - final Color color, final short value, final int sample) - throws IllegalArgumentException { - return new ConstantColorMapElement(name, color, value, sample); - } - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - public static LinearColorMapElement create(final CharSequence name, - final Color color, final int value, final int sample) - throws IllegalArgumentException { - return new ConstantColorMapElement(name, color, value, sample); - } - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - public static LinearColorMapElement create(final CharSequence name, - final Color color, final float value, final int sample) - throws IllegalArgumentException { - return new ConstantColorMapElement(name, color, value, sample); - } - - - /** - * @see LinearColorMapElement#ClassificationCategory(CharSequence, - * Color[], NumberRange, NumberRange) - */ - public static LinearColorMapElement create(final CharSequence name, - final Color color, final double value, final int sample) - throws IllegalArgumentException { - return new ConstantColorMapElement(name, color, value, sample); - } - - - /** - * Constructor for a {@link LinearColorMapElement}. It allows users - * to build a category which is able to map values into integer sample - * values for further rendering using and {@link IndexColorModel}. - * - * NOTE Due to the limitations of the - * {@link IndexColorModel} we can accept as valid ranges only those that - * fit between 0 -65535. - * - * @param name - * for this {@link DomainElement1D}. - * @param colors - * to use when rendering values belonging to this - * {@link DomainElement1D} - * @param valueRange - * the input range for this category. - * @param sampleRange - * the sample range for this category. It will be used as indexes - * for the final color map. - * @throws IllegalArgumentException - * in case the output range does not respect - * {@link IndexColorModel} limitations. - */ - LinearColorMapElement(final CharSequence name, - final Color[] colors, final NumberRange valueRange, - final NumberRange sampleRange) throws IllegalArgumentException { - super(name, valueRange, checkSampleRange(sampleRange)); -// //@todo check this test -// final int inEquals = ColorMapUtilities.compare(getInputMaximum(), getInputMinimum()); -// final int outEquals = ColorMapUtilities.compare(getOutputMaximum(), getOutputMinimum()); -// if (inEquals == 0 && outEquals == 0) -// this.type = LinearColorMap.LinearColorMapType.TYPE_VALUES; -// else if (outEquals == 0) -// this.type = LinearColorMap.LinearColorMapType.TYPE_INTERVALS; -// else { -// if (isIdentity()) -// -// this.type = LinearColorMap.LinearColorMapType.TYPE_VALUES; -// else -// this.type = LinearColorMap.LinearColorMapType.TYPE_RAMP; -// } - // ///////////////////////////////////////////////////////////////////// - // - // Initialise fields for visualization - // - // ///////////////////////////////////////////////////////////////////// - this.colors = new Color[colors.length]; - System.arraycopy(colors, 0, this.colors, 0, colors.length); - - } - - - /** - * This method is responsible for performing a few checks on the provided - * range in order to make sure we are talking about a valid range for - * building an {@link IndexColorModel}. - * - * @param numberRange - * the range to use for mapping values to colors. - * @return the input {@link NumberRange} if everything goes well. - * @see IndexColorModel - */ - private static NumberRange checkSampleRange(NumberRange numberRange) { - if (numberRange == null) - throw new IllegalArgumentException(); - final Class elementClass = numberRange.getElementClass(); - if (!elementClass.equals(Integer.class) - && !elementClass.equals(Byte.class) - && !elementClass.equals(Short.class)) - throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, numberRange)); - if (numberRange.getMinimum() < 0 || numberRange.getMaximum() > 65535) - throw new IndexOutOfBoundsException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, numberRange)); - return numberRange; - } - - /* - * (non-Javadoc) - * - * @see org.geotools.renderer.lite.gridcoverage2d.Category#equals(java.lang.Object) - */ - public boolean equals(final Object object) { - if(this==object) - return true; - if(!(object instanceof LinearColorMapElement)) - return false; - final LinearColorMapElement that = (LinearColorMapElement) object; - if(getEquivalenceClass()!=that.getEquivalenceClass()) - return false; - if(Arrays.equals(this.getColors(), that.getColors())) - return false; - return super.equals(that); - } - - /** - * Returns the set of colors for this category. Change to the returned array will not affect this category. - * @see GridSampleDimension#getColorModel - * @uml.property name="colors" - */ - public Color[] getColors() { - return (Color[]) colors.clone(); - } - - /** - * Gives access to the internal {@link MathTransform1D}. - * - * @return the internal {@link MathTransform1D}. - */ - MathTransform1D accessTransform() { - return getTransform(); - } - - /* - * (non-Javadoc) - * @see org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement#toString() - */ - public String toString() { - final StringBuilder buffer= new StringBuilder(super.toString()); - buffer.append("\n").append("colors="); - for(int i=0;(colors !=null)&&i getEquivalenceClass(){ - return LinearColorMapElement.class; - } - @Override - public int hashCode() { - if(hashCode>=0) - return hashCode; - hashCode=37; - hashCode=Utilities.hash( colors,hashCode); - hashCode=Utilities.hash( super.hashCode(),hashCode); - return hashCode; - } - -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapNode.java (working copy) @@ -18,14 +18,12 @@ import java.awt.Color; import java.awt.image.DataBuffer; -import java.awt.image.LookupTable; import java.awt.image.RenderedImage; import java.awt.image.renderable.ParameterBlock; import java.util.logging.Level; import java.util.logging.Logger; import javax.media.jai.JAI; -import javax.media.jai.LookupTableJAI; import javax.media.jai.OperationDescriptor; import javax.media.jai.RenderedOp; @@ -38,6 +36,11 @@ import org.geotools.renderer.i18n.Errors; import org.geotools.renderer.i18n.Vocabulary; import org.geotools.renderer.i18n.VocabularyKeys; +import org.geotools.renderer.lite.gridcoverage2d.colormap.ColorMapTransform; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMap; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMapElement; +import org.geotools.renderer.lite.gridcoverage2d.colormap.RasterClassifier; +import org.geotools.renderer.lite.gridcoverage2d.colormap.SLDColorMapBuilder; import org.geotools.styling.ColorMap; import org.geotools.styling.ColorMapEntry; import org.geotools.styling.StyleVisitor; @@ -110,7 +113,7 @@ * Visits the provided {@link ColorMapTransform} and build up a {@link Domain1D} * for later creation of a palette rendering for this coverage. */ - public synchronized void visit(ColorMap colorMap) { + public void visit(ColorMap colorMap) { // // // // This allows this node to work in store-and-forward way in case we had @@ -327,7 +330,7 @@ * @return the extendedColors * @uml.property name="extendedColors" */ - public synchronized boolean isExtendedColors() { + public boolean isExtendedColors() { return extendedColors; } Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransformElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransformElement.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ColorMapTransformElement.java (working copy) @@ -1,49 +0,0 @@ -/* - * 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.Color; - -import org.geotools.referencing.piecewise.DomainElement1D; -import org.geotools.referencing.piecewise.PiecewiseTransform1DElement; - - - -/** - * {@link ColorMapTransformElement}s are a special type of - * {@link PiecewiseTransform1DElement}s that can be used to generate specific renderings - * as the result of specific transformations applied to the input values. - * - *

- * A popular example is represented by a {@link DomainElement1D} used to classify - * values which means applying a color to all the pixels of an image whose value - * falls in the {@link DomainElement1D}'s range. - * - * @author Simone Giannecchini, GeoSolutions - * - * - * @source $URL$ - */ -public interface ColorMapTransformElement extends PiecewiseTransform1DElement { - /** - * Returns the set of colors for this category. Change to the returned array - * will not affect this category. - * - * @see GridSampleDimension#getColorModel - */ - public Color[] getColors(); -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ChannelSelectionNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ChannelSelectionNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/ChannelSelectionNode.java (working copy) @@ -80,7 +80,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.StyleVisitorAdapter#visit(org.geotools.styling.ChannelSelection) */ - public synchronized void visit(final ChannelSelection cs) { + public void visit(final ChannelSelection cs) { // ///////////////////////////////////////////////////////////////////// // // Ensure that the ChannelSelection is not null and that the source is Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SLDColorMapBuilder.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SLDColorMapBuilder.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/SLDColorMapBuilder.java (working copy) @@ -1,657 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-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.Color; -import java.util.ArrayList; -import java.util.List; -import java.util.MissingResourceException; - -import org.geotools.renderer.i18n.ErrorKeys; -import org.geotools.renderer.i18n.Errors; -import org.geotools.renderer.lite.gridcoverage2d.LinearColorMap.LinearColorMapType; -import org.geotools.styling.ColorMap; -import org.geotools.styling.ColorMapEntry; -import org.geotools.styling.RasterSymbolizer; -import org.geotools.util.NumberRange; -import org.opengis.filter.expression.Expression; - -/** - * Builder facility for creating a {@link LinearColorMap} using elements from {@link RasterSymbolizer} {@link ColorMapTransform} element.

This class is not intended to be thread safe. - * @author Simone Giannecchini, GeoSolutions - * - * @source $URL$ - */ -public class SLDColorMapBuilder { - - public final static Color defaultColorForValuesToPreserve= new Color(0,0,0,0); - - /**Default color to fill gaps.**/ - public final static Color defaultGapsColor= new Color(0,0,0,0); - - /**List of {@link LinearColorMapElement} we are putting together to create the final {@link LinearColorMap}**/ - private final List colormapElements = new ArrayList(); - - /** - * {@link LinearColorMapType} * - * @uml.property name="linearColorMapType" - */ - private int linearColorMapType = -1; - - /**{@link Color} used to fill gaps.**/ - private Color gapsColor; - - /**{@link Color} use for the values that we want to preserve through the color map.**/ - private Color preservedValuesColor; - - /**List of values that we want to preserve through the color map.**/ - private final List preservedValues = new ArrayList(); - - /**Number of colors we can distribute to each {@link ColorMapTransformElement}.**/ - private int colorsPerColorMapElement; - - /** - * Used during {@link LinearColorMap} creation to hold the last color. - */ - private Color lastColorValue; - - private String name; - - /** - * Default constructor for the {@link SLDColorMapBuilder} class. - */ - public SLDColorMapBuilder() { - this.name="sld-colormap"; - } - - /** - * Constructor for the {@link SLDColorMapBuilder} class. - * @param name name for the {@link LinearColorMap} we will create at the - * end of this process. - */ - public SLDColorMapBuilder( - final String name) { - ColorMapUtilities.ensureNonNull("name", name); - this.name= name; - } - - /** - * Sets the default {@link Color} to use when a value falls outside the range of values for provided color map elements.

Note that once the underlying colormap has been built this method will throw an {@link IllegalStateException} if invoked.

In case one would want to unset the default color, he should simply call this method with a null value. - * @param the default {@link Color} to use when a value falls outside the provided color map elements. - * @uml.property name="gapsColor" - */ - public void setGapsColor(final Color defaultColor) { - - // ///////////////////////////////////////////////////////////////////// - // - // Do we already have a liner color map? - // - // ///////////////////////////////////////////////////////////////////// - checkIfColorMapCreated(); - - //set the defult color - this.gapsColor = defaultColor; - } - - /** - * Checks whether or not the underlying {@link LinearColorMap} has been already - * created. - * - * @throws IllegalStateException In case the the underlying {@link LinearColorMap} has been already created. - */ - private void checkIfColorMapCreated() throws IllegalStateException { - // ///////////////////////////////////////////////////////////////////// - // - // Do we already have a liner color map? - // - // ///////////////////////////////////////////////////////////////////// - if(this.colorMap!=null) - throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); - } - - /** - * Sets the {@link LinearColorMapType} for this {@link SLDColorMapBuilder} . - * @see LinearColorMapType - * @return this {@link SLDColorMapBuilder} . - * @uml.property name="linearColorMapType" - */ - public SLDColorMapBuilder setLinearColorMapType(int colorMapType) { - // // - // - // Do we already have a liner color map? - // - // // - checkIfColorMapCreated(); - - //// - // - // Color map type cannot be changed once it has been set. - // - ///// - if (LinearColorMapType.validateColorMapTye(this.linearColorMapType )) - throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); - - //// - // - // provided Color map type validation. - // - ///// - if (!LinearColorMapType.validateColorMapTye(colorMapType)) - throw new IllegalArgumentException( - Errors.format( - ErrorKeys.ILLEGAL_ARGUMENT_$2, - "colorMapType", - Integer.toString(colorMapType))); - ///set the linear colormap type - this.linearColorMapType = colorMapType; - return this; - - } - - /** - * Retrieves the {@link LinearColorMapType} for this {@link SLDColorMapBuilder} .

-1 is returned in case the {@link LinearColorMapType} is still unspecified. - * @return the {@link LinearColorMapType} for this {@link SLDColorMapBuilder} or -1 case the {@link LinearColorMapType} is still unspecified. - * @uml.property name="linearColorMapType" - */ - public int getLinearColorMapType() { - return linearColorMapType; - } - - /** - * Add a new {@link ColorMapEntry} to the list of {@link ColorMapEntry} we want to use - * for building a {@link LinearColorMap}. - * - *

- * - * @param colorMapEntry - * @return - */ - public SLDColorMapBuilder addColorMapEntry(ColorMapEntry colorMapEntry) { - /////////////////////////////////////////////////////////////////////// - // - // INITIAL CHECKS - // - /////////////////////////////////////////////////////////////////////// - // Color map type must be already set. - ColorMapUtilities.ensureNonNull("colorMapEntry",colorMapEntry); - // Color map already created. - checkIfColorMapCreated(); - // Color map type must be already set. - // Number of domains must be already set. - ColorMapUtilities.ensureNonNull("colorMapEntry",colorMapEntry); - if(this.numberColorMapEntries==-1||linearColorMapType == -1||numberColorMapEntries) previous.getRange()) - .getMaximum(), true, q, false), - NumberRange.create((int) previous.getOutputMaximum() , - colorsPerColorMapElement - + (int) previous.getOutputMaximum()))); - break; - case ColorMap.TYPE_VALUES: - colormapElements.add(LinearColorMapElement.create(label, - newColorValue, q, newColorMapElementIndex)); - break; - case ColorMap.TYPE_INTERVALS: - colormapElements.add(LinearColorMapElement.create(label, - newColorValue, NumberRange.create(((NumberRange) previous - .getRange()).getMaximum(), true, q, false), - newColorMapElementIndex)); - break; - default: - throw new IllegalArgumentException(Errors.format( - ErrorKeys.ILLEGAL_ARGUMENT_$2, "ColorMapTransform.type", Double - .toString(opacityValue), Integer.valueOf( - linearColorMapType))); - - } - - } - lastColorValue = newColorValue; - return this; - } - - /** - * initialization of the basic element for this {@link SLDColorMapBuilder}. - */ - private void init() { - if(numberOfColorMapElements!=-1) - return; - // // - // - // A ColorMapTransform with a single entry makes sense only if we have - // ColorMapTransform type VALUES - // - // // - if (numberColorMapEntries== 1 && linearColorMapType != ColorMap.TYPE_VALUES) - throw new IllegalArgumentException( - Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,"colormap entries","1")); - - - // ///////////////////////////////////////////////////////////////////// - // - // PREPARATION - // - // ///////////////////////////////////////////////////////////////////// - numberOfColorMapElements = numberColorMapEntries; - if (linearColorMapType == ColorMap.TYPE_RAMP) - { - - // // - // - // Let's distribute the number of colors that we'll use between the - // various color map elements we'll build. We start by checking if we can use - // 256 colors, otherwise we switch to 65536. - // - // Keep into account that some categories are inherently single - // valued, hence we take them out of the count because we don't. - // - // // - double colorsToDistribute=!extendedColors && numberColorMapEntries < 256?256:65536; - //default color - if(gapsColor!=null) - colorsToDistribute--; - //preserved values - if(preservedValuesColor!=null) - colorsToDistribute--; - - - //compute the number of colors we can use for each color map element - colorsPerColorMapElement = (int) ((colorsToDistribute ) / - // we remove one since the first and last element use 1 color only, hence we want to account only the internal ranges - (numberOfColorMapElements-1)); - - //now keep into account the last element - numberOfColorMapElements++; - } else - colorsPerColorMapElement = 1; - - } - - /** - * Retrieves the values to preserve. - * - * @return an array of double which represents the values that need to - * be preserved by the {@link ColorMapTransform} we will create. - */ - public double[] getValuesToPreserve() { - if (this.preservedValues.size() == 0) - return new double[0]; - final double retVal[] = new double[this.preservedValues.size()]; - int i = 0; - for(Double value:preservedValues) - retVal[i++] = value.doubleValue(); - return retVal; - } - - /** - * Add a value that we should try to preserve while applying the color map. - * - *

- * This means that all the values we add using this method will be mapped to - * the same color which can be set using {@link #setColorForValuesToPreserve(Color)}. - * - *

- * - * @return this {@link SLDColorMapBuilder}. - */ - public SLDColorMapBuilder addValueToPreserve(final double value) { - checkIfColorMapCreated(); - - //add the value to preserve if not already in - assert preservedValues !=null; - preservedValues.add(value); - return this; - } - - /** - * Set the color to use for the values we want to preserve. - * @return this {@link SLDColorMapBuilder}. - */ - public SLDColorMapBuilder setColorForValuesToPreserve(final Color color) { - ColorMapUtilities.ensureNonNull("color",color); - checkIfColorMapCreated(); - //@todo TODO check number of color map entries - this.preservedValuesColor = color; - return this; - } - - /** - * @return - */ - public Color getColorForValuesToPreserve() { - return this.preservedValuesColor; - } - - /** - * @param entry - * @return - * @throws NumberFormatException - */ - private static Color getColor(ColorMapEntry entry) - throws NumberFormatException { - ColorMapUtilities.ensureNonNull("ColorMapEntry",entry); - final Expression color = entry.getColor(); - ColorMapUtilities.ensureNonNull("color",color); - final String colorString= (String) color.evaluate(null, String.class); - ColorMapUtilities.ensureNonNull("colorString",colorString); - return Color.decode(colorString); - } - - /** - * @param entry - * @return - * @throws IllegalArgumentException - * @throws MissingResourceException - */ - private static double getOpacity(ColorMapEntry entry) - throws IllegalArgumentException, MissingResourceException { - - ColorMapUtilities.ensureNonNull("ColorMapEntry",entry); - // // - // - // As stated in - // OGC Styled-Layer Descriptor Report (OGC 02-070) version - // 1.0.0.: - // "Not all systems can support opacity in colormaps. The default - // opacity is 1.0 (fully opaque)." - // - // // - ColorMapUtilities.ensureNonNull("entry",entry); - Expression opacity = entry.getOpacity(); - Double opacityValue = null; - if (opacity != null) - opacityValue = (Double) opacity.evaluate(null, Double.class); - else - return 1.0; - if ((opacityValue.doubleValue() - 1) > 0 - || opacityValue.doubleValue() < 0) { - throw new IllegalArgumentException(Errors.format( - ErrorKeys.ILLEGAL_ARGUMENT_$2, "Opacity", opacityValue)); - } - return opacityValue.doubleValue(); - } - - /** - * @param entry - * @return - */ - private static double getQuantity(ColorMapEntry entry) { - ColorMapUtilities.ensureNonNull("ColorMapEntry",entry); - Expression quantity = entry.getQuantity(); - ColorMapUtilities.ensureNonNull("quantity",quantity); - Double quantityString = (Double) quantity.evaluate(null, Double.class); - ColorMapUtilities.ensureNonNull("quantityString",quantityString); - double q = quantityString.doubleValue(); - return q; - } - - /** - * @uml.property name="extendedColors" - */ - private boolean extendedColors = false; - - /** - * Getter of the property extendedColors - * @return Returns the extendedColors. - * @uml.property name="extendedColors" - */ - public boolean getExtendedColors() { - return extendedColors; - } - - /** - * Setter of the property extendedColors

Unless this property is set prior to start working with this {@link SLDColorMapBuilder} we will make use of only 256 colors. If we use extended colors, then we'll be able to use up to 65536 colors.

Note that this imposes a limitation on the maximum number of {@link ColorMapEntry} we can use. - * @param extendedColors The extendedColors to set. - * @return - * @uml.property name="extendedColors" - */ - public SLDColorMapBuilder setExtendedColors(boolean extendedColors) { - if(this.numberColorMapEntries!=-1) - throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); - checkIfColorMapCreated(); - this.extendedColors = extendedColors; - return this; - } - - /** - * @uml.property name="numberColorMapEntries" - */ - private int numberColorMapEntries = -1; - - /** - * Getter of the property numberColorMapEntries - * @return Returns the numberColorMapEntries. - * @uml.property name="numberColorMapEntries" - */ - public int getNumberColorMapEntries() { - return numberColorMapEntries; - } - - /** - * Setter of the property numberColorMapEntries - * @param numberColorMapEntries The numberColorMapEntries to set. - * @return - * @uml.property name="numberColorMapEntries" - */ - public SLDColorMapBuilder setNumberColorMapEntries( - final int numberColorMapEntries) { - checkIfColorMapCreated(); - if(this.numberColorMapEntries!=-1) - throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); - if(numberColorMapEntries<=0||numberColorMapEntries>(extendedColors?65536:256)) - throw new IllegalArgumentException( - Errors.format( - ErrorKeys.ILLEGAL_ARGUMENT_$2, - "numberColorMapEntries", - Integer.toString(numberColorMapEntries) - )); - this.numberColorMapEntries = numberColorMapEntries; - return this; - } - - /** - * @uml.property name="numberOfColorMapElements" - */ - private int numberOfColorMapElements = -1; - - /**This is the target object for this builder.**/ - private LinearColorMap colorMap; - - /** - * Getter of the property numberOfColorMapElements - * @return Returns the numberOfColorMapElements. - * @uml.property name="numberOfColorMapElements" - */ - public int getNumberOfColorMapElements() { - return numberOfColorMapElements; - } - - /** - */ - public LinearColorMap buildLinearColorMap() { - if(this.numberColorMapEntries==-1) - throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); - - - // ///////////////////////////////////////////////////////////////////// - // - // Do we already have an object? - // - // ///////////////////////////////////////////////////////////////////// - if(this.colorMap!=null) - return this.colorMap; - - // ///////////////////////////////////////////////////////////////////// - // - // Create the last category - // - // ///////////////////////////////////////////////////////////////////// - LinearColorMapElement last = (LinearColorMapElement) this.colormapElements - .get(this.colormapElements.size() - 1); - if (linearColorMapType == ColorMap.TYPE_RAMP) { - - // // - // - // Get the previous category - // - // // - final LinearColorMapElement previous = last; - - // // - // - // Build the last one - // - // // - last=LinearColorMapElement.create( - "ColorMapEntry"+this.colormapElements.size(), lastColorValue, NumberRange.create( - previous.getRange().getMaximum(), - true, Double.POSITIVE_INFINITY, false), - (int) previous.getOutputMaximum()); - this.colormapElements.add(last); - - } - - - - // ///////////////////////////////////////////////////////////////////// - // - // Create the list of no data classification domain elements. Note that - // all of them - // - // ///////////////////////////////////////////////////////////////////// - final LinearColorMapElement preservedValuesElement[] = new LinearColorMapElement[preservedValues - .size()]; - final int value=(int) last.getOutputMaximum()+1; - for (int i = 0; i < preservedValuesElement.length; i++) { - preservedValuesElement[i] = LinearColorMapElement - .create( - org.geotools.resources.i18n.Vocabulary.format( - org.geotools.resources.i18n.VocabularyKeys.NODATA)+ Integer.toString(i + 1), - preservedValuesColor, - NumberRange.create( preservedValues.get(i), preservedValues.get(i)), - value - ); - } - - this.colorMap = new LinearColorMap(name, - (LinearColorMapElement[]) colormapElements.toArray(new LinearColorMapElement[colormapElements.size()]), - preservedValuesElement, - this.gapsColor); - return colorMap; - } - -} Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/GridCoverageRenderer.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/GridCoverageRenderer.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/GridCoverageRenderer.java (working copy) @@ -77,7 +77,6 @@ import com.sun.media.jai.opimage.RIFUtil; import com.sun.media.jai.opimage.TranslateIntOpImage; -import com.sun.media.jai.util.Rational; import com.vividsolutions.jts.geom.Envelope; /** @@ -195,70 +194,8 @@ private final AffineTransform finalWorldToGrid; private final Hints hints = new Hints(); - - // FORMULAE FOR FORWARD MAP are derived as follows - // Nearest - // Minimum: - // srcMin = floor ((dstMin + 0.5 - trans) / scale) - // srcMin <= (dstMin + 0.5 - trans) / scale < srcMin + 1 - // srcMin*scale <= dstMin + 0.5 - trans < (srcMin + 1)*scale - // srcMin*scale - 0.5 + trans - // <= dstMin < (srcMin + 1)*scale - 0.5 + trans - // Let A = srcMin*scale - 0.5 + trans, - // Let B = (srcMin + 1)*scale - 0.5 + trans - // - // dstMin = ceil(A) - // - // Maximum: - // Note that srcMax is defined to be srcMin + dimension - 1 - // srcMax = floor ((dstMax + 0.5 - trans) / scale) - // srcMax <= (dstMax + 0.5 - trans) / scale < srcMax + 1 - // srcMax*scale <= dstMax + 0.5 - trans < (srcMax + 1)*scale - // srcMax*scale - 0.5 + trans - // <= dstMax < (srcMax+1) * scale - 0.5 + trans - // Let float A = (srcMax + 1) * scale - 0.5 + trans - // - // dstMax = floor(A), if floor(A) < A, else - // dstMax = floor(A) - 1 - // OR dstMax = ceil(A - 1) - // - // Other interpolations - // - // First the source should be shrunk by the padding that is - // required for the particular interpolation. Then the - // shrunk source should be forward mapped as follows: - // - // Minimum: - // srcMin = floor (((dstMin + 0.5 - trans)/scale) - 0.5) - // srcMin <= ((dstMin + 0.5 - trans)/scale) - 0.5 < srcMin+1 - // (srcMin+0.5)*scale <= dstMin+0.5-trans < - // (srcMin+1.5)*scale - // (srcMin+0.5)*scale - 0.5 + trans - // <= dstMin < (srcMin+1.5)*scale - 0.5 + trans - // Let A = (srcMin+0.5)*scale - 0.5 + trans, - // Let B = (srcMin+1.5)*scale - 0.5 + trans - // - // dstMin = ceil(A) - // - // Maximum: - // srcMax is defined as srcMin + dimension - 1 - // srcMax = floor (((dstMax + 0.5 - trans) / scale) - 0.5) - // srcMax <= ((dstMax + 0.5 - trans)/scale) - 0.5 < srcMax+1 - // (srcMax+0.5)*scale <= dstMax + 0.5 - trans < - // (srcMax+1.5)*scale - // (srcMax+0.5)*scale - 0.5 + trans - // <= dstMax < (srcMax+1.5)*scale - 0.5 + trans - // Let float A = (srcMax+1.5)*scale - 0.5 + trans - // - // dstMax = floor(A), if floor(A) < A, else - // dstMax = floor(A) - 1 - // OR dstMax = ceil(A - 1) - // - - private static float rationalTolerance = 0.000001F; - - /** Parameters used to control the {@link Resample} operation. */ + /** Parameters used to control the {@link Resample} operation. */ private final static ParameterValueGroup resampleParams; /** Parameters used to control the {@link Crop} operation. */ @@ -786,7 +723,7 @@ final AffineTransform finalRaster2Model = couple.getTransform(); //paranoiac check to avoid that JAI freaks out when computing its internal layouT on images that are too small - Rectangle2D finalLayout= layoutHelper( + Rectangle2D finalLayout= ImageUtilities.layoutHelper( finalImage, (float)finalRaster2Model.getScaleX(), (float)finalRaster2Model.getScaleY(), @@ -1025,120 +962,4 @@ } - - - private static Rectangle2D layoutHelper(RenderedImage source, - float scaleX, - float scaleY, - float transX, - float transY, - Interpolation interp) { - - // Represent the scale factors as Rational numbers. - // Since a value of 1.2 is represented as 1.200001 which - // throws the forward/backward mapping in certain situations. - // Convert the scale and translation factors to Rational numbers - Rational scaleXRational = Rational.approximate(scaleX,rationalTolerance); - Rational scaleYRational = Rational.approximate(scaleY,rationalTolerance); - - long scaleXRationalNum = (long) scaleXRational.num; - long scaleXRationalDenom = (long) scaleXRational.denom; - long scaleYRationalNum = (long) scaleYRational.num; - long scaleYRationalDenom = (long) scaleYRational.denom; - - Rational transXRational = Rational.approximate(transX,rationalTolerance); - Rational transYRational = Rational.approximate(transY,rationalTolerance); - - long transXRationalNum = (long) transXRational.num; - long transXRationalDenom = (long) transXRational.denom; - long transYRationalNum = (long) transYRational.num; - long transYRationalDenom = (long) transYRational.denom; - - int x0 = source.getMinX(); - int y0 = source.getMinY(); - int w = source.getWidth(); - int h = source.getHeight(); - - // Variables to store the calculated destination upper left coordinate - long dx0Num, dx0Denom, dy0Num, dy0Denom; - - // Variables to store the calculated destination bottom right - // coordinate - long dx1Num, dx1Denom, dy1Num, dy1Denom; - - // Start calculations for destination - - dx0Num = x0; - dx0Denom = 1; - - dy0Num = y0; - dy0Denom = 1; - - // Formula requires srcMaxX + 1 = (x0 + w - 1) + 1 = x0 + w - dx1Num = x0 + w; - dx1Denom = 1; - - // Formula requires srcMaxY + 1 = (y0 + h - 1) + 1 = y0 + h - dy1Num = y0 + h; - dy1Denom = 1; - - dx0Num *= scaleXRationalNum; - dx0Denom *= scaleXRationalDenom; - - dy0Num *= scaleYRationalNum; - dy0Denom *= scaleYRationalDenom; - - dx1Num *= scaleXRationalNum; - dx1Denom *= scaleXRationalDenom; - - dy1Num *= scaleYRationalNum; - dy1Denom *= scaleYRationalDenom; - - // Equivalent to subtracting 0.5 - dx0Num = 2 * dx0Num - dx0Denom; - dx0Denom *= 2; - - dy0Num = 2 * dy0Num - dy0Denom; - dy0Denom *= 2; - - // Equivalent to subtracting 1.5 - dx1Num = 2 * dx1Num - 3 * dx1Denom; - dx1Denom *= 2; - - dy1Num = 2 * dy1Num - 3 * dy1Denom; - dy1Denom *= 2; - - // Adding translation factors - - // Equivalent to float dx0 += transX - dx0Num = dx0Num * transXRationalDenom + transXRationalNum * dx0Denom; - dx0Denom *= transXRationalDenom; - - // Equivalent to float dy0 += transY - dy0Num = dy0Num * transYRationalDenom + transYRationalNum * dy0Denom; - dy0Denom *= transYRationalDenom; - - // Equivalent to float dx1 += transX - dx1Num = dx1Num * transXRationalDenom + transXRationalNum * dx1Denom; - dx1Denom *= transXRationalDenom; - - // Equivalent to float dy1 += transY - dy1Num = dy1Num * transYRationalDenom + transYRationalNum * dy1Denom; - dy1Denom *= transYRationalDenom; - - // Get the integral coordinates - int l_x0, l_y0, l_x1, l_y1; - - l_x0 = Rational.ceil(dx0Num, dx0Denom); - l_y0 = Rational.ceil(dy0Num, dy0Denom); - - l_x1 = Rational.ceil(dx1Num, dx1Denom); - l_y1 = Rational.ceil(dy1Num, dy1Denom); - - // Set the top left coordinate of the destination - final Rectangle2D retValue= new Rectangle2D.Double(); - retValue.setFrame(l_x0, l_y0, l_x1 - l_x0 + 1, l_y1 - l_y0 + 1); - return retValue; - } - } Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BaseCoverageProcessingNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BaseCoverageProcessingNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BaseCoverageProcessingNode.java (working copy) @@ -280,7 +280,7 @@ * @param force * force the disposition of this node. */ - public synchronized void dispose(boolean force) { + public void dispose(boolean force) { // ///////////////////////////////////////////////////////////////////// // @@ -334,7 +334,7 @@ * This method is responsible for triggering the execution of this {@link CoverageProcessingNode} and also of all its sources.

In case something bad happens a {@link CoverageProcessingException} is thrown. * @uml.property name="output" */ - public synchronized GridCoverage2D getOutput() + public GridCoverage2D getOutput() throws CoverageProcessingException { checkExecuted(); if (error != null) @@ -348,7 +348,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#addSink(org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode) */ - public synchronized void addSink(CoverageProcessingNode sink) { + public void addSink(CoverageProcessingNode sink) { ensureNotNull(sink, "CoverageProcessingNode"); sinks.add(sink); detectCycle(); @@ -373,7 +373,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#addSource(org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode) */ - public synchronized boolean addSource(CoverageProcessingNode source) { + public boolean addSource(CoverageProcessingNode source) { ensureNotNull(source, "CoverageProcessingNode"); checkNumSources(1); if (this.sources.add(source)) { @@ -405,7 +405,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#getSink(int) */ - public synchronized CoverageProcessingNode getSink(int index) { + public CoverageProcessingNode getSink(int index) { return (CoverageProcessingNode) sinks.get(index); } @@ -419,7 +419,7 @@ * @return * @uml.property name="sinks" */ - public synchronized List getSinks() { + public List getSinks() { return Collections.unmodifiableList(sinks); } @@ -429,7 +429,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#getSource(int) */ - public synchronized CoverageProcessingNode getSource(int index) { + public CoverageProcessingNode getSource(int index) { return (CoverageProcessingNode) sources.get(index); } @@ -443,7 +443,7 @@ * @return * @uml.property name="sources" */ - public synchronized List getSources() { + public List getSources() { return Collections.unmodifiableList(sources); } @@ -453,7 +453,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#removeSink(org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode) */ - public synchronized boolean removeSink(CoverageProcessingNode sink) { + public boolean removeSink(CoverageProcessingNode sink) { ensureNotNull(sink, "CoverageProcessingNode"); // ///////////////////////////////////////////////////////////////////// // @@ -468,7 +468,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#removeSink(int) */ - public synchronized CoverageProcessingNode removeSink(int index) { + public CoverageProcessingNode removeSink(int index) { return (CoverageProcessingNode) this.sinks.remove(index); } @@ -478,7 +478,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#removeSource(org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode) */ - public synchronized boolean removeSource(CoverageProcessingNode source) { + public boolean removeSource(CoverageProcessingNode source) { ensureNotNull(source, "CoverageProcessingNode"); final boolean success = this.sources.remove(source); if (success) @@ -492,7 +492,7 @@ * @return {@link Hints} provided at construction time to control {@link GridCoverageFactory} creation. * @uml.property name="hints" */ - public synchronized Hints getHints() { + public Hints getHints() { return new Hints(hints); } @@ -519,7 +519,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#getNumberOfSinks() */ - public synchronized int getNumberOfSinks() { + public int getNumberOfSinks() { return this.sinks.size(); } @@ -528,7 +528,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#getNumberOfSources() */ - public synchronized int getNumberOfSources() { + public int getNumberOfSources() { return sources.size(); } @@ -596,7 +596,7 @@ * * @see org.geotools.renderer.lite.gridcoverage2d.CoverageProcessingNode#removeSource(int) */ - public synchronized CoverageProcessingNode removeSource(int index) + public CoverageProcessingNode removeSource(int index) throws IndexOutOfBoundsException { return (CoverageProcessingNode) sources.remove(index); } @@ -630,7 +630,7 @@ * @return true if the node has been already disposed, false otherwise. * @uml.property name="disposed" */ - public synchronized boolean isDisposed() { + public boolean isDisposed() { return disposed; } @@ -639,7 +639,7 @@ * @return true if the node has been already executed, false otherwise. * @uml.property name="executed" */ - public synchronized boolean isExecuted() { + public boolean isExecuted() { return this.executed ; } Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandMergeNode.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandMergeNode.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/BandMergeNode.java (working copy) @@ -69,7 +69,7 @@ * (non-Javadoc) * @see org.geotools.renderer.lite.gridcoverage2d.BaseCoverageProcessingNode#dispose(boolean) */ - public synchronized void dispose(boolean force) { + public void dispose(boolean force) { /////////////////////////////////////////////////////////////////////// // // Dispose local intermediate operations Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ConstantColorMapElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ConstantColorMapElement.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ConstantColorMapElement.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMapElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMapElement.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMapElement.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; import java.awt.image.IndexColorModel; @@ -26,7 +26,7 @@ import org.geotools.referencing.piecewise.PiecewiseTransform1DElement; import org.geotools.renderer.i18n.ErrorKeys; import org.geotools.renderer.i18n.Errors; -import org.geotools.renderer.lite.gridcoverage2d.LinearColorMap.LinearColorMapType; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMap.LinearColorMapType; import org.geotools.util.NumberRange; import org.geotools.util.Utilities; import org.opengis.referencing.operation.MathTransform1D; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransformElement.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransformElement.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransformElement.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/RasterClassifier.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/RasterClassifier.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/RasterClassifier.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Rectangle; import java.awt.RenderingHints; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/SLDColorMapBuilder.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/SLDColorMapBuilder.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/SLDColorMapBuilder.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; import java.util.ArrayList; @@ -23,7 +23,7 @@ import org.geotools.renderer.i18n.ErrorKeys; import org.geotools.renderer.i18n.Errors; -import org.geotools.renderer.lite.gridcoverage2d.LinearColorMap.LinearColorMapType; +import org.geotools.renderer.lite.gridcoverage2d.colormap.LinearColorMap.LinearColorMapType; import org.geotools.styling.ColorMap; import org.geotools.styling.ColorMapEntry; import org.geotools.styling.RasterSymbolizer; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMap.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMap.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/LinearColorMap.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; import java.awt.image.ColorModel; @@ -330,7 +330,7 @@ return colorModel; } - private synchronized void initColorModel() { + private void initColorModel() { if (colorModel == null) { // ///////////////////////////////////////////////////////////////////// // @@ -519,7 +519,7 @@ // * order to emulate the behavior of this {@link PiecewiseTransform1D}. // */ // private void checkOptimalJAIOps() { -// synchronized (scales) { +// (scales) { // if (offsets != null) // return; // Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransform.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransform.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapTransform.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; Index: render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapUtilities.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapUtilities.java (revision 0) +++ render/src/main/java/org/geotools/renderer/lite/gridcoverage2d/colormap/ColorMapUtilities.java (working copy) @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package org.geotools.renderer.lite.gridcoverage2d; +package org.geotools.renderer.lite.gridcoverage2d.colormap; import java.awt.Color; Index: render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java =================================================================== --- render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java (revision 37083) +++ render/src/main/java/org/geotools/renderer/lite/MetaBufferEstimator.java (working copy) @@ -43,7 +43,6 @@ import org.geotools.styling.LineSymbolizer; import org.geotools.styling.Mark; import org.geotools.styling.NamedLayer; -import org.geotools.styling.OverlapBehavior; import org.geotools.styling.PointPlacement; import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PolygonSymbolizer; @@ -59,11 +58,11 @@ import org.geotools.styling.Symbolizer; import org.geotools.styling.TextSymbolizer; import org.geotools.styling.UserLayer; -import org.opengis.feature.Feature; import org.opengis.filter.Filter; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; import org.opengis.style.GraphicalSymbol; +import org.opengis.style.OverlapBehavior; /** * Parses a style or part of it and returns the size of the largest stroke and the biggest point symbolizer whose width is specified with a literal expression.
Also provides an indication whether the stroke width is accurate, or if a non literal width has been found. Index: render/src/main/java/org/geotools/styling/StyleAttributeExtractor.java =================================================================== --- render/src/main/java/org/geotools/styling/StyleAttributeExtractor.java (revision 37083) +++ render/src/main/java/org/geotools/styling/StyleAttributeExtractor.java (working copy) @@ -23,12 +23,12 @@ import org.geotools.filter.FilterAttributeExtractor; import org.geotools.renderer.style.ExpressionExtractor; -import org.opengis.feature.type.AttributeDescriptor; import org.opengis.filter.Filter; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.ExpressionVisitor; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; +import org.opengis.style.OverlapBehavior; /** @@ -544,7 +544,7 @@ } public void visit(OverlapBehavior ob) { - ob.accept(this); +// ob.accept(this); } Index: main/src/test/java/org/geotools/styling/visitor/DuplicatorStyleVisitorTest.java =================================================================== --- main/src/test/java/org/geotools/styling/visitor/DuplicatorStyleVisitorTest.java (revision 37083) +++ main/src/test/java/org/geotools/styling/visitor/DuplicatorStyleVisitorTest.java (working copy) @@ -624,13 +624,11 @@ ContrastEnhancement ce = sf.createContrastEnhancement(); ce.setGammaValue(sb.literalExpression(0.5)); ce.setMethod(ContrastMethod.HISTOGRAM); - ce.setHistogram(); ce.accept(visitor); ContrastEnhancement ce2 = (ContrastEnhancement) visitor.getCopy(); assertEquals("Gamma value incorrest after duplication", ((Literal)ce.getGammaValue()).getValue(), ((Literal)ce2.getGammaValue()).getValue()); assertEquals("ContrastMethod must be equal after duplication ", ce.getMethod(), ce2.getMethod()); - assertEquals("Contrast Type must be equal after duplication ", ((Literal)ce.getType()).getValue(), ((Literal)ce2.getType()).getValue()); } Index: main/src/test/java/org/geotools/styling/SLDStyleTest.java =================================================================== --- main/src/test/java/org/geotools/styling/SLDStyleTest.java (revision 37083) +++ main/src/test/java/org/geotools/styling/SLDStyleTest.java (working copy) @@ -45,6 +45,8 @@ import org.opengis.filter.expression.PropertyName; import org.opengis.filter.spatial.BinarySpatialOperator; import org.opengis.filter.spatial.Disjoint; +import org.opengis.style.ContrastMethod; +import org.opengis.style.OverlapBehavior; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; @@ -591,21 +593,18 @@ //contrast enhancement ContrastEnhancement rcs = redChannel.getContrastEnhancement(); - String type = (String)rcs.getType().evaluate(null); - assertEquals("Histogram", type); + assertEquals(ContrastMethod.HISTOGRAM, rcs.getMethod()); ContrastEnhancement gcs = greenChannel.getContrastEnhancement(); Double ggamma = (Double)gcs.getGammaValue().evaluate(null); assertEquals(2.8, ggamma.doubleValue()); ContrastEnhancement bcs = blueChannel.getContrastEnhancement(); - type = (String)bcs.getType().evaluate(null); - assertEquals("Normalize", type); + assertEquals(ContrastMethod.NORMALIZE, rcs.getMethod()); //overlap behaviour - Expression overlapExpr = rs.getOverlap(); - type = (String)overlapExpr.evaluate(null); - assertEquals("LATEST_ON_TOP", type); + OverlapBehavior overlapExpr = rs.getOverlapBehavior(); + assertEquals(OverlapBehavior.LATEST_ON_TOP, overlapExpr); //ContrastEnhancement ContrastEnhancement ce = rs.getContrastEnhancement(); @@ -637,9 +636,8 @@ assertEquals(1.0, d.doubleValue()); //overlap behaviour - Expression overlapExpr = rs.getOverlap(); - String type = (String)overlapExpr.evaluate(null); - assertEquals("AVERAGE", type); + OverlapBehavior overlapExpr = rs.getOverlapBehavior(); + assertEquals(OverlapBehavior.AVERAGE,overlapExpr); //ColorMap ColorMap cMap = rs.getColorMap(); Index: main/src/test/java/org/geotools/styling/SLDTransformerTest.java =================================================================== --- main/src/test/java/org/geotools/styling/SLDTransformerTest.java (revision 37083) +++ main/src/test/java/org/geotools/styling/SLDTransformerTest.java (working copy) @@ -47,6 +47,7 @@ import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; +import org.opengis.style.ContrastMethod; import org.opengis.style.GraphicalSymbol; import org.opengis.style.Rule; import org.opengis.style.Symbolizer; @@ -135,7 +136,7 @@ SelectedChannelTypeImpl redChannel = new SelectedChannelTypeImpl(); redChannel.setChannelName("1"); ContrastEnhancementImpl rcei = new ContrastEnhancementImpl(); - rcei.setHistogram(); + rcei.setMethod(ContrastMethod.HISTOGRAM); redChannel.setContrastEnhancement(rcei); // green @@ -149,7 +150,7 @@ SelectedChannelTypeImpl blueChannel = new SelectedChannelTypeImpl(); blueChannel.setChannelName("2"); ContrastEnhancementImpl bcei = new ContrastEnhancementImpl(); - bcei.setNormalize(); + bcei.setMethod(ContrastMethod.NORMALIZE); blueChannel.setContrastEnhancement(bcei); csi.setRGBChannels(redChannel, greenChannel, blueChannel); Index: main/src/main/java/org/geotools/styling/SLDParser.java =================================================================== --- main/src/main/java/org/geotools/styling/SLDParser.java (revision 37083) +++ main/src/main/java/org/geotools/styling/SLDParser.java (working copy) @@ -39,6 +39,8 @@ import org.opengis.filter.expression.Function; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; +import org.opengis.style.ContrastMethod; +import org.opengis.style.OverlapBehavior; import org.w3c.dom.CharacterData; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -1155,7 +1157,7 @@ } else if (childName.equalsIgnoreCase(overlapBehaviorString)) { try { final String overlapString = child.getFirstChild().getLocalName(); - symbol.setOverlap(ff.literal(overlapString)); + symbol.setOverlapBehavior(OverlapBehavior.valueOf(overlapString)); } catch (Throwable e) { if (LOGGER.isLoggable(Level.WARNING)) LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); @@ -1396,13 +1398,13 @@ } if (childName.equalsIgnoreCase("Normalize")) { - symbol.setNormalize(); + symbol.setMethod(ContrastMethod.NORMALIZE); } else if (childName.equalsIgnoreCase("Histogram")) { - symbol.setHistogram(); + symbol.setMethod(ContrastMethod.HISTOGRAM); } else if (childName.equalsIgnoreCase("Logarithmic")) { - symbol.setLogarithmic(); + symbol.setMethod(ContrastMethod.LOGARITHMIC); } else if (childName.equalsIgnoreCase("Exponential")) { - symbol.setExponential(); + symbol.setMethod(ContrastMethod.EXPONENTIAL); } else if (childName.equalsIgnoreCase("GammaValue")) { try { final String gammaString = getFirstChildValue(child); Index: main/src/main/java/org/geotools/styling/SLDTransformer.java =================================================================== --- main/src/main/java/org/geotools/styling/SLDTransformer.java (revision 37083) +++ main/src/main/java/org/geotools/styling/SLDTransformer.java (working copy) @@ -23,8 +23,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; -import java.util.Map.Entry; import java.util.logging.Logger; import javax.measure.quantity.Length; @@ -37,7 +37,6 @@ import org.geotools.filter.FilterTransformer; import org.geotools.gml.producer.FeatureTransformer; import org.geotools.referencing.CRS; -import org.geotools.referencing.NamedIdentifier; import org.geotools.xml.transform.TransformerBase; import org.geotools.xml.transform.Translator; import org.opengis.feature.simple.SimpleFeatureType; @@ -49,6 +48,8 @@ import org.opengis.filter.expression.PropertyName; import org.opengis.referencing.ReferenceIdentifier; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.style.ContrastMethod; +import org.opengis.style.OverlapBehavior; import org.opengis.style.SemanticType; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; @@ -455,21 +456,21 @@ } } - if (raster.getOverlap() != null) { - Expression overlaps = raster.getOverlap(); - if( overlaps instanceof PropertyName){ - final String pn = ((PropertyName)overlaps).getPropertyName(); - if("RANDOM".equals(pn)) { - start("OverlapBehavior"); - start(pn); - end(pn); - end("OverlapBehavior"); - } - } else { - //this expression needs to be converted to a single string and then written - //1.0.0 specs don't allow it to be written as an expression - elementLiteral("OverlapBehavior",overlaps, "RANDOM"); - } + if (raster.getOverlapBehavior() != null) { + OverlapBehavior overlaps = raster.getOverlapBehavior(); +// if( overlaps instanceof PropertyName){ +// final String pn = ((PropertyName)overlaps).getPropertyName(); +// if("RANDOM".equals(pn)) { + start("OverlapBehavior"); + start(overlaps.name()); + end(overlaps.name()); + end("OverlapBehavior"); +// } +// } else { +// //this expression needs to be converted to a single string and then written +// //1.0.0 specs don't allow it to be written as an expression +// elementLiteral("OverlapBehavior",overlaps, "RANDOM"); +// } } ColorMap colorMap = raster.getColorMap(); @@ -1144,15 +1145,15 @@ start("ContrastEnhancement"); // histogram - Literal exp = (Literal) ce.getType(); - if (exp != null) { - final String val = (String) exp.getValue(); + ContrastMethod cem = ce.getMethod(); + if (cem != null) { + final String val = (String) cem.name(); start(val); end(val); } //gamma - exp=(Literal)ce.getGammaValue(); + Literal exp = (Literal)ce.getGammaValue(); if (exp != null) { //gamma is a double so the actual value needs to be printed here element("GammaValue", ((Literal)exp).getValue().toString()); @@ -1183,7 +1184,7 @@ public void visit(OverlapBehavior ob) { start("OverlapBehavior"); - final String pn = (String) ob.getValue(); + final String pn = (String) ob.name(); start(pn); end(pn); end("OverlapBehavior"); Index: main/src/main/java/org/geotools/styling/StyleFactoryImpl.java =================================================================== --- main/src/main/java/org/geotools/styling/StyleFactoryImpl.java (revision 37083) +++ main/src/main/java/org/geotools/styling/StyleFactoryImpl.java (working copy) @@ -664,7 +664,7 @@ public RasterSymbolizer createRasterSymbolizer( String geometryPropertyName, Expression opacity, - ChannelSelection channel, Expression overlap, ColorMap colorMap, + ChannelSelection channel, OverlapBehavior overlap, ColorMap colorMap, ContrastEnhancement cenhancement, ShadedRelief relief, Symbolizer outline) { RasterSymbolizer rastersym = new RasterSymbolizerImpl(filterFactory); @@ -682,7 +682,7 @@ } if (overlap != null) { - rastersym.setOverlap(overlap); + rastersym.setOverlapBehavior(overlap); } if (colorMap != null) { Index: main/src/main/java/org/geotools/styling/SLD.java =================================================================== --- main/src/main/java/org/geotools/styling/SLD.java (revision 37083) +++ main/src/main/java/org/geotools/styling/SLD.java (working copy) @@ -878,13 +878,12 @@ ContrastEnhancement ce = copy(raster.getContrastEnhancement()); String geometryProperty = raster.getGeometryPropertyName(); Symbolizer outline = copy(raster.getImageOutline()); - Expression overlap = copy(raster.getOverlap()); ShadedRelief shadedRelief = copy(raster.getShadedRelief()); Expression newOpacity = ff.literal(opacity); RasterSymbolizer copy = sf.createRasterSymbolizer(geometryProperty, newOpacity, channelSelection, - overlap, colorMap, ce, shadedRelief, outline); + raster.getOverlapBehavior(), colorMap, ce, shadedRelief, outline); if (STRICT && !copy.equals(raster)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + raster); @@ -930,13 +929,12 @@ ContrastEnhancement ce = copy(raster.getContrastEnhancement()); String geometryProperty = raster.getGeometryPropertyName(); Symbolizer outline = copy(raster.getImageOutline()); - Expression overlap = copy(raster.getOverlap()); ShadedRelief shadedRelief = copy(raster.getShadedRelief()); Expression opacity = copy(raster.getOpacity()); RasterSymbolizer copy = sf.createRasterSymbolizer(geometryProperty, opacity, - channelSelection, overlap, colorMap, ce, + channelSelection, raster.getOverlapBehavior(), colorMap, ce, shadedRelief, outline); if (STRICT && !copy.equals(raster)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + raster); Index: main/src/main/java/org/geotools/styling/ContrastEnhancementImpl.java =================================================================== --- main/src/main/java/org/geotools/styling/ContrastEnhancementImpl.java (revision 37083) +++ main/src/main/java/org/geotools/styling/ContrastEnhancementImpl.java (working copy) @@ -19,11 +19,11 @@ package org.geotools.styling; import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; import org.geotools.util.Utilities; import org.opengis.filter.FilterFactory; import org.opengis.filter.FilterFactory2; import org.opengis.filter.expression.Expression; -import org.opengis.filter.expression.Literal; import org.opengis.style.ContrastMethod; /** @@ -71,10 +71,8 @@ private Expression gamma; - private Expression type; + private ContrastMethod method= ContrastMethod.NONE; - private ContrastMethod method; - public ContrastEnhancementImpl() { this(CommonFactoryFinder.getFilterFactory(null)); } @@ -89,7 +87,7 @@ } public ContrastEnhancementImpl(org.opengis.style.ContrastEnhancement contrastEnhancement) { - filterFactory = CommonFactoryFinder.getFilterFactory2(null); + filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); this.method = contrastEnhancement.getMethod(); this.gamma = contrastEnhancement.getGammaValue(); } @@ -98,7 +96,6 @@ this.filterFactory = factory; this.gamma = gamma; this.method = method; - this.type = factory.literal(method.name()); } public void setFilterFactory(FilterFactory factory) { @@ -108,61 +105,12 @@ public Expression getGammaValue() { return gamma; } - - public Expression getType() { - return type; - } - public void setGammaValue(Expression gamma) { this.gamma = gamma; } - public void setHistogram() { - type = filterFactory.literal("Histogram"); - method = ContrastMethod.HISTOGRAM; - } - - public void setNormalize() { - type = filterFactory.literal("Normalize"); - method = ContrastMethod.NORMALIZE; - } - - public void setLogarithmic() { - type = filterFactory.literal("Logarithmic"); - method = ContrastMethod.NONE; - } - - public void setExponential() { - type = filterFactory.literal("Exponential"); - method = ContrastMethod.NONE; - } - - public void setType(Expression type) { - this.type = type; - if (type instanceof Literal) { - String value = type.evaluate(null, String.class); - if ("Histogram".equalsIgnoreCase(value)) { - method = ContrastMethod.HISTOGRAM; - } else if ("Normalize".equalsIgnoreCase(value)) { - method = ContrastMethod.NORMALIZE; - } else { - method = ContrastMethod.NONE; - } - } else { - method = ContrastMethod.NONE; - } - } - public void setMethod(ContrastMethod method) { - if (method == ContrastMethod.NORMALIZE) { - this.type = filterFactory.literal("Normalize"); - this.method = ContrastMethod.NORMALIZE; - } else if (method == ContrastMethod.HISTOGRAM) { - this.type = filterFactory.literal("Histogram"); - this.method = ContrastMethod.HISTOGRAM; - } else { - this.method = method; - } + this.method = method; } public ContrastMethod getMethod() { @@ -170,7 +118,7 @@ } public Object accept(org.opengis.style.StyleVisitor visitor, Object extraData) { - return null; + return visitor.visit(this, extraData); } public void accept(StyleVisitor visitor) { @@ -186,10 +134,6 @@ result = (PRIME * result) + gamma.hashCode(); } - if (type != null) { - result = (PRIME * result) + type.hashCode(); - } - if (method != null) { result = (PRIME * result) + method.hashCode(); } @@ -207,7 +151,6 @@ ContrastEnhancementImpl other = (ContrastEnhancementImpl) obj; return Utilities.equals(gamma, other.gamma) - && Utilities.equals(type, other.type) && Utilities.equals(method, other.method); } @@ -228,4 +171,12 @@ return copy; } } + + + @Override + public String toString() { + return "ContrastEnhancementImpl [filterFactory=" + filterFactory + ", gamma=" + gamma + + ", method=" + method + "]"; + } + } Index: main/src/main/java/org/geotools/styling/RasterSymbolizerImpl.java =================================================================== --- main/src/main/java/org/geotools/styling/RasterSymbolizerImpl.java (revision 37083) +++ main/src/main/java/org/geotools/styling/RasterSymbolizerImpl.java (working copy) @@ -45,10 +45,9 @@ private ColorMapImpl colorMap = new ColorMapImpl(); private ContrastEnhancementImpl contrastEnhancement = new ContrastEnhancementImpl(); private ShadedReliefImpl shadedRelief; - private String geometryName = "geom"; private Symbolizer symbolizer; private Expression opacity; - private Expression overlap; + private OverlapBehavior overlap; public RasterSymbolizerImpl(){ this( CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints())); @@ -62,7 +61,7 @@ super(name, desc, "grid", uom); this.filterFactory = factory; this.opacity = filterFactory.literal(1.0); - this.overlap = filterFactory.literal(OverlapBehavior.RANDOM); + this.overlap = OverlapBehavior.RANDOM; this.behavior = behavior; } @@ -236,26 +235,6 @@ return opacity; } - /** - * The OverlapBehavior element tells a system how to behave when multiple - * raster images in a layer overlap each other, for example with - * satellite-image scenes. LATEST_ON_TOP and EARLIEST_ON_TOP refer to the - * time the scene was captured. AVERAGE means to average multiple scenes - * together. This can produce blurry results if the source images are not - * perfectly aligned in their geo-referencing. RANDOM means to select an - * image (or piece thereof) randomly and place it on top. This can - * produce crisper results than AVERAGE potentially more efficiently than - * LATEST_ON_TOP or EARLIEST_ON_TOP. The default behaviour is - * system-dependent. - * - * @return The expression which evaluates to LATEST_ON_TOP, - * EARLIEST_ON_TOP, AVERAGE or RANDOM - */ - @Deprecated - public Expression getOverlap() { - return overlap; - } - public OverlapBehavior getOverlapBehavior() { return behavior; } @@ -407,29 +386,6 @@ } /** - * The OverlapBehavior element tells a system how to behave when multiple - * raster images in a layer overlap each other, for example with - * satellite-image scenes. LATEST_ON_TOP and EARLIEST_ON_TOP refer to the - * time the scene was captured. AVERAGE means to average multiple scenes - * together. This can produce blurry results if the source images are not - * perfectly aligned in their geo-referencing. RANDOM means to select an - * image (or piece thereof) randomly and place it on top. This can - * produce crisper results than AVERAGE potentially more efficiently than - * LATEST_ON_TOP or EARLIEST_ON_TOP. The default behaviour is - * system-dependent. - * - * @param overlap the expression which evaluates to LATEST_ON_TOP, - * EARLIEST_ON_TOP, AVERAGE or RANDOM - */ - @Deprecated - public void setOverlap(Expression overlap) { - if (this.overlap == overlap) { - return; - } - this.overlap = overlap; - } - - /** * The ShadedRelief element selects the application of relief shading (or * ?hill shading?) to an image for a three-dimensional visual effect. It * is defined as: Exact parameters of the shading are system-dependent Index: main/src/main/java/org/geotools/styling/AbstractStyleFactory.java =================================================================== --- main/src/main/java/org/geotools/styling/AbstractStyleFactory.java (revision 37083) +++ main/src/main/java/org/geotools/styling/AbstractStyleFactory.java (working copy) @@ -22,6 +22,7 @@ import java.util.Map; import org.opengis.filter.expression.Expression; +import org.opengis.style.OverlapBehavior; /** @@ -189,7 +190,7 @@ public abstract RasterSymbolizer createRasterSymbolizer( String geometryPropertyName, Expression opacity, - ChannelSelection channel, Expression overlap, ColorMap colorMap, + ChannelSelection channel, OverlapBehavior overlap, ColorMap colorMap, ContrastEnhancement ce, ShadedRelief relief, Symbolizer outline); public abstract RasterSymbolizer getDefaultRasterSymbolizer(); Index: main/src/main/java/org/geotools/styling/visitor/DuplicatingStyleVisitor.java =================================================================== --- main/src/main/java/org/geotools/styling/visitor/DuplicatingStyleVisitor.java (revision 37083) +++ main/src/main/java/org/geotools/styling/visitor/DuplicatingStyleVisitor.java (working copy) @@ -48,7 +48,6 @@ import org.geotools.styling.NamedLayer; import org.geotools.styling.OtherText; import org.geotools.styling.OtherTextImpl; -import org.geotools.styling.OverlapBehavior; import org.geotools.styling.PointPlacement; import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PolygonSymbolizer; @@ -59,7 +58,6 @@ import org.geotools.styling.Stroke; import org.geotools.styling.Style; import org.geotools.styling.StyleFactory; -import org.geotools.styling.StyleFactoryImpl; import org.geotools.styling.StyleVisitor; import org.geotools.styling.StyledLayer; import org.geotools.styling.StyledLayerDescriptor; @@ -72,6 +70,7 @@ import org.opengis.filter.FilterFactory2; import org.opengis.filter.expression.Expression; import org.opengis.style.Description; +import org.opengis.style.OverlapBehavior; /** * Creates a deep copy of a Style, this class is *NOT THREAD SAFE*. @@ -472,7 +471,7 @@ protected OverlapBehavior copy(OverlapBehavior ob) { if( ob == null ) return null; - ob.accept(this); +// ob.accept(this); return (OverlapBehavior) pages.pop(); } @@ -482,9 +481,6 @@ ContrastEnhancement copy = sf.createContrastEnhancement(); copy.setGammaValue( copy( contrast.getGammaValue())); copy.setMethod(contrast.getMethod()); - if(contrast.getType() != null) { - copy.setType(contrast.getType()); - } return copy; } @@ -736,7 +732,7 @@ copy.setUnitOfMeasure(raster.getUnitOfMeasure()); copy.setImageOutline( copy( raster.getImageOutline())); copy.setOpacity( copy( raster.getOpacity() )); - copy.setOverlap( copy( raster.getOverlap())); + copy.setOverlapBehavior( raster.getOverlapBehavior()); copy.setShadedRelief( copy( raster.getShadedRelief())); if( STRICT && !copy.equals( raster )){ @@ -970,7 +966,7 @@ public void visit(ContrastEnhancement contrastEnhancement) { final ContrastEnhancement copy = sf.createContrastEnhancement(); - copy.setType(contrastEnhancement.getType()); + copy.setMethod(contrastEnhancement.getMethod()); copy.setGammaValue(contrastEnhancement.getGammaValue()); if (STRICT && !copy.equals(contrastEnhancement)) { throw new IllegalStateException("Was unable to duplicate provided contrastEnhancement:" + contrastEnhancement); @@ -1005,15 +1001,14 @@ } public void visit(OverlapBehavior ob) { - final String behavior = (String) ob.getValue(); - if (behavior.equalsIgnoreCase(OverlapBehavior.AVERAGE_RESCTRICTION)) { - pages.push(OverlapBehavior.AVERAGE_RESCTRICTION); - } else if (behavior.equalsIgnoreCase(OverlapBehavior.EARLIEST_ON_TOP_RESCTRICTION)) { - pages.push(OverlapBehavior.EARLIEST_ON_TOP_RESCTRICTION); - } else if (behavior.equalsIgnoreCase(OverlapBehavior.LATEST_ON_TOP_RESCTRICTION)) { - pages.push(OverlapBehavior.LATEST_ON_TOP_RESCTRICTION); - } else if (behavior.equalsIgnoreCase(OverlapBehavior.RANDOM_RESCTRICTION)) { - pages.push(OverlapBehavior.RANDOM_RESCTRICTION); + if (ob.equals(OverlapBehavior.AVERAGE)) { + pages.push(OverlapBehavior.AVERAGE); + } else if (ob.equals(OverlapBehavior.EARLIEST_ON_TOP)) { + pages.push(OverlapBehavior.EARLIEST_ON_TOP); + } else if (ob.equals(OverlapBehavior.LATEST_ON_TOP)) { + pages.push(OverlapBehavior.LATEST_ON_TOP); + } else if (ob.equals(OverlapBehavior.RANDOM)) { + pages.push(OverlapBehavior.RANDOM); } else { throw new IllegalStateException("Was unable to duplicate provided OverlapBehavior:" + ob); } Index: coverage/src/main/java/org/geotools/image/ImageLayout2.java =================================================================== --- coverage/src/main/java/org/geotools/image/ImageLayout2.java (revision 37083) +++ coverage/src/main/java/org/geotools/image/ImageLayout2.java (working copy) @@ -17,6 +17,10 @@ */ package org.geotools.image; +import java.awt.image.ColorModel; +import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; + import javax.media.jai.ImageLayout; /** @@ -27,7 +31,36 @@ */ public class ImageLayout2 extends ImageLayout{ - /** + public ImageLayout2() { + super(); + // TODO Auto-generated constructor stub + } + + public ImageLayout2(int minX, int minY, int width, int height, int tileGridXOffset, + int tileGridYOffset, int tileWidth, int tileHeight, SampleModel sampleModel, + ColorModel colorModel) { + super(minX, minY, width, height, tileGridXOffset, tileGridYOffset, tileWidth, tileHeight, + sampleModel, colorModel); + // TODO Auto-generated constructor stub + } + + public ImageLayout2(int tileGridXOffset, int tileGridYOffset, int tileWidth, int tileHeight, + SampleModel sampleModel, ColorModel colorModel) { + super(tileGridXOffset, tileGridYOffset, tileWidth, tileHeight, sampleModel, colorModel); + // TODO Auto-generated constructor stub + } + + public ImageLayout2(int minX, int minY, int width, int height) { + super(minX, minY, width, height); + // TODO Auto-generated constructor stub + } + + public ImageLayout2(RenderedImage im) { + super(im); + // TODO Auto-generated constructor stub + } + + /** * */ private static final long serialVersionUID = -7921590012423277029L; Index: coverage/src/main/java/org/geotools/resources/image/ImageUtilities.java =================================================================== --- coverage/src/main/java/org/geotools/resources/image/ImageUtilities.java (revision 37083) +++ coverage/src/main/java/org/geotools/resources/image/ImageUtilities.java (working copy) @@ -19,6 +19,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; @@ -67,6 +68,7 @@ import com.sun.media.imageioimpl.common.PackageUtil; import com.sun.media.jai.operator.ImageReadDescriptor; +import com.sun.media.jai.util.Rational; /** @@ -91,7 +93,7 @@ /** * {@code true} if JAI media lib is available. */ - private static final boolean mediaLibAvailable; + private static final boolean MEDIALIB_AVAILABLE; static { // do we wrappers at hand? @@ -152,7 +154,7 @@ } - mediaLibAvailable=mediaLib; + MEDIALIB_AVAILABLE=mediaLib; } /** @@ -246,6 +248,8 @@ public static final String DIRECT_KAKADU_PLUGIN = "it.geosolutions.imageio.plugins.jp2k.JP2KKakaduImageReader"; + public static float RATIONAL_TOLERANCE = 0.000001F; + /** * Do not allow creation of instances of this class. */ @@ -745,7 +749,7 @@ * @return false in case the JAI native libs are not in the path, true otherwise. */ public static boolean isMediaLibAvailable() { - return mediaLibAvailable; + return MEDIALIB_AVAILABLE; } /** @@ -877,4 +881,118 @@ } return w.makeColorTransparent(transparentColor).getRenderedImage(); } + + public static Rectangle2D layoutHelper(RenderedImage source, + float scaleX, + float scaleY, + float transX, + float transY, + Interpolation interp) { + + // Represent the scale factors as Rational numbers. + // Since a value of 1.2 is represented as 1.200001 which + // throws the forward/backward mapping in certain situations. + // Convert the scale and translation factors to Rational numbers + Rational scaleXRational = Rational.approximate(scaleX,RATIONAL_TOLERANCE); + Rational scaleYRational = Rational.approximate(scaleY,RATIONAL_TOLERANCE); + + long scaleXRationalNum = (long) scaleXRational.num; + long scaleXRationalDenom = (long) scaleXRational.denom; + long scaleYRationalNum = (long) scaleYRational.num; + long scaleYRationalDenom = (long) scaleYRational.denom; + + Rational transXRational = Rational.approximate(transX,RATIONAL_TOLERANCE); + Rational transYRational = Rational.approximate(transY,RATIONAL_TOLERANCE); + + long transXRationalNum = (long) transXRational.num; + long transXRationalDenom = (long) transXRational.denom; + long transYRationalNum = (long) transYRational.num; + long transYRationalDenom = (long) transYRational.denom; + + int x0 = source.getMinX(); + int y0 = source.getMinY(); + int w = source.getWidth(); + int h = source.getHeight(); + + // Variables to store the calculated destination upper left coordinate + long dx0Num, dx0Denom, dy0Num, dy0Denom; + + // Variables to store the calculated destination bottom right + // coordinate + long dx1Num, dx1Denom, dy1Num, dy1Denom; + + // Start calculations for destination + + dx0Num = x0; + dx0Denom = 1; + + dy0Num = y0; + dy0Denom = 1; + + // Formula requires srcMaxX + 1 = (x0 + w - 1) + 1 = x0 + w + dx1Num = x0 + w; + dx1Denom = 1; + + // Formula requires srcMaxY + 1 = (y0 + h - 1) + 1 = y0 + h + dy1Num = y0 + h; + dy1Denom = 1; + + dx0Num *= scaleXRationalNum; + dx0Denom *= scaleXRationalDenom; + + dy0Num *= scaleYRationalNum; + dy0Denom *= scaleYRationalDenom; + + dx1Num *= scaleXRationalNum; + dx1Denom *= scaleXRationalDenom; + + dy1Num *= scaleYRationalNum; + dy1Denom *= scaleYRationalDenom; + + // Equivalent to subtracting 0.5 + dx0Num = 2 * dx0Num - dx0Denom; + dx0Denom *= 2; + + dy0Num = 2 * dy0Num - dy0Denom; + dy0Denom *= 2; + + // Equivalent to subtracting 1.5 + dx1Num = 2 * dx1Num - 3 * dx1Denom; + dx1Denom *= 2; + + dy1Num = 2 * dy1Num - 3 * dy1Denom; + dy1Denom *= 2; + + // Adding translation factors + + // Equivalent to float dx0 += transX + dx0Num = dx0Num * transXRationalDenom + transXRationalNum * dx0Denom; + dx0Denom *= transXRationalDenom; + + // Equivalent to float dy0 += transY + dy0Num = dy0Num * transYRationalDenom + transYRationalNum * dy0Denom; + dy0Denom *= transYRationalDenom; + + // Equivalent to float dx1 += transX + dx1Num = dx1Num * transXRationalDenom + transXRationalNum * dx1Denom; + dx1Denom *= transXRationalDenom; + + // Equivalent to float dy1 += transY + dy1Num = dy1Num * transYRationalDenom + transYRationalNum * dy1Denom; + dy1Denom *= transYRationalDenom; + + // Get the integral coordinates + int l_x0, l_y0, l_x1, l_y1; + + l_x0 = Rational.ceil(dx0Num, dx0Denom); + l_y0 = Rational.ceil(dy0Num, dy0Denom); + + l_x1 = Rational.ceil(dx1Num, dx1Denom); + l_y1 = Rational.ceil(dy1Num, dy1Denom); + + // Set the top left coordinate of the destination + final Rectangle2D retValue= new Rectangle2D.Double(); + retValue.setFrame(l_x0, l_y0, l_x1 - l_x0 + 1, l_y1 - l_y0 + 1); + return retValue; + } } Index: coverage/src/main/java/org/geotools/coverage/processing/operation/Resampler2D.java =================================================================== --- coverage/src/main/java/org/geotools/coverage/processing/operation/Resampler2D.java (revision 37083) +++ coverage/src/main/java/org/geotools/coverage/processing/operation/Resampler2D.java (working copy) @@ -32,7 +32,6 @@ import java.util.logging.Logger; import javax.media.jai.BorderExtender; -import javax.media.jai.BorderExtenderConstant; import javax.media.jai.ImageLayout; import javax.media.jai.Interpolation; import javax.media.jai.InterpolationNearest; Index: xml/src/main/java/org/geotools/xml/styling/sldComplexTypes.java =================================================================== --- xml/src/main/java/org/geotools/xml/styling/sldComplexTypes.java (revision 37083) +++ xml/src/main/java/org/geotools/xml/styling/sldComplexTypes.java (working copy) @@ -54,6 +54,7 @@ import org.geotools.xml.styling.sldComplexTypes2._PointPlacement; import org.geotools.xml.styling.sldComplexTypes2._PolygonSymbolizer; import org.geotools.xml.styling.sldComplexTypes2._Rule; +import org.opengis.style.ContrastMethod; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -137,13 +138,17 @@ private static final Attribute[] attrs = null; private static final Element[] elems = new Element[]{ new sldElement("Normalize", _Normalize.getInstance(), null, 1, 1), - new sldElement("Histogram", sldComplexTypes._Histogram.getInstance(), null, 1, 1), + new sldElement("Logarithmic", _Logarithmic.getInstance(), null, 1, 1), + new sldElement("Exponential", _Exponentual.getInstance(), null, 1, 1), + new sldElement("Histogram", _Histogram.getInstance(), null, 1, 1), new sldElement("GammaValue", org.geotools.xml.xsi.XSISimpleTypes.Double .getInstance()/* simpleType name is double */, null, 0, 1)}; private static final int NORMALIZE = 0; - private static final int HISTORGRAM = 1; - private static final int GAMMAVALUE = 2; + private static final int LOGARITHMIC = 1; + private static final int EXPONENTIAL = 2; + private static final int HISTOGRAM = 3; + private static final int GAMMAVALUE = 4; private static final ElementGrouping child = new SequenceGT(null, new ElementGrouping[]{ new ChoiceGT(null, 0, 1, new ElementGrouping[]{elems[0], elems[1]}), @@ -213,11 +218,17 @@ Element e = value[i].getElement(); if(elems[NORMALIZE].getName().equals(e.getName())) - symbol.setNormalize(); // (Graphic)value[i].getValue() + symbol.setMethod(ContrastMethod.NORMALIZE); - if(elems[HISTORGRAM].getName().equals(e.getName())) - symbol.setHistogram(); // (Graphic)value[i].getValue() - + if(elems[HISTOGRAM].getName().equals(e.getName())) + symbol.setMethod(ContrastMethod.HISTOGRAM); + + if(elems[EXPONENTIAL].getName().equals(e.getName())) + symbol.setMethod(ContrastMethod.EXPONENTIAL); + + if(elems[LOGARITHMIC].getName().equals(e.getName())) + symbol.setMethod(ContrastMethod.LOGARITHMIC); + if(elems[GAMMAVALUE].getName().equals(e.getName())){ symbol.setGammaValue(FilterFactoryFinder.createFilterFactory().createLiteralExpression(((Double)value[i].getValue()).doubleValue())); } @@ -2084,4 +2095,143 @@ // TODO fill me in } } + static class _Exponentual extends sldComplexType { + private static final ComplexType instance = new _Exponentual(); + public static ComplexType getInstance() { + return instance; + } + + private static final Attribute[] attrs = null; + private static final Element[] elems = null; + private static final ElementGrouping child = new SequenceGT(null); + + private _Exponentual() { + super(null, child, attrs, elems, null, false, false); + } + + /** + * + * getInstanceType ... + * + * @see org.geotools.xml.schema.Type#getInstanceType() + */ + public Class getInstanceType() { + return null; + // TODO fill me in + } + + + /** + * canEncode ... + * + * @see org.geotools.xml.schema.Type#canEncode(org.geotools.xml.schema.Element, java.lang.Object, java.util.Map) + * @param element + * @param value + * @param hints + */ + public boolean canEncode( Element element, Object value, Map hints ) { + return super.canEncode(element, value, hints); + // TODO fill me in + } + /** + * encode ... + * + * @see org.geotools.xml.schema.Type#encode(org.geotools.xml.schema.Element, java.lang.Object, org.geotools.xml.PrintHandler, java.util.Map) + * @param element + * @param value + * @param output + * @param hints + * @throws OperationNotSupportedException + */ + public void encode( Element element, Object value, PrintHandler output, Map hints ) + throws OperationNotSupportedException { + super.encode(element, value, output, hints); + // TODO fill me in + } + /** + * getValue ... + * + * @see org.geotools.xml.schema.Type#getValue(org.geotools.xml.schema.Element, org.geotools.xml.schema.ElementValue[], org.xml.sax.Attributes, java.util.Map) + * @param element + * @param value + * @param attrs1 + * @param hints + * @throws OperationNotSupportedException + */ + public Object getValue( Element element, ElementValue[] value, Attributes attrs1, Map hints ) + throws OperationNotSupportedException, SAXException { + return super.getValue(element, value, attrs1, hints); + // TODO fill me in + } + } + + static class _Logarithmic extends sldComplexType { + private static final ComplexType instance = new _Logarithmic(); + public static ComplexType getInstance() { + return instance; + } + + private static final Attribute[] attrs = null; + private static final Element[] elems = null; + private static final ElementGrouping child = new SequenceGT(null); + + private _Logarithmic() { + super(null, child, attrs, elems, null, false, false); + } + + /** + * + * getInstanceType ... + * + * @see org.geotools.xml.schema.Type#getInstanceType() + */ + public Class getInstanceType() { + return null; + // TODO fill me in + } + + + /** + * canEncode ... + * + * @see org.geotools.xml.schema.Type#canEncode(org.geotools.xml.schema.Element, java.lang.Object, java.util.Map) + * @param element + * @param value + * @param hints + */ + public boolean canEncode( Element element, Object value, Map hints ) { + return super.canEncode(element, value, hints); + // TODO fill me in + } + /** + * encode ... + * + * @see org.geotools.xml.schema.Type#encode(org.geotools.xml.schema.Element, java.lang.Object, org.geotools.xml.PrintHandler, java.util.Map) + * @param element + * @param value + * @param output + * @param hints + * @throws OperationNotSupportedException + */ + public void encode( Element element, Object value, PrintHandler output, Map hints ) + throws OperationNotSupportedException { + super.encode(element, value, output, hints); + // TODO fill me in + } + /** + * getValue ... + * + * @see org.geotools.xml.schema.Type#getValue(org.geotools.xml.schema.Element, org.geotools.xml.schema.ElementValue[], org.xml.sax.Attributes, java.util.Map) + * @param element + * @param value + * @param attrs1 + * @param hints + * @throws OperationNotSupportedException + */ + public Object getValue( Element element, ElementValue[] value, Attributes attrs1, Map hints ) + throws OperationNotSupportedException, SAXException { + return super.getValue(element, value, attrs1, hints); + // TODO fill me in + } + } } Index: xml/src/main/java/org/geotools/xml/styling/sldComplexTypes2.java =================================================================== --- xml/src/main/java/org/geotools/xml/styling/sldComplexTypes2.java (revision 37083) +++ xml/src/main/java/org/geotools/xml/styling/sldComplexTypes2.java (working copy) @@ -27,6 +27,7 @@ import org.geotools.styling.ChannelSelection; import org.geotools.styling.ColorMap; import org.geotools.styling.ContrastEnhancement; +import org.geotools.styling.ContrastEnhancementImpl; import org.geotools.styling.FeatureTypeConstraint; import org.geotools.styling.Fill; import org.geotools.styling.Font; @@ -84,6 +85,7 @@ import org.geotools.xml.styling.sldComplexTypes._LATEST_ON_TOP; import org.geotools.xml.styling.sldComplexTypes._LabelPlacement; import org.geotools.xml.xLink.XLinkSchema; +import org.opengis.style.OverlapBehavior; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -1415,8 +1417,11 @@ if(elems[CHANNELSELECTION].getName().equals(e.getName())) symbol.setChannelSelection((ChannelSelection)value[i].getValue()); - if(elems[OVERLAPBEHAVIOR].getName().equals(e.getName())) - symbol.setOverlap((Expression)value[i].getValue()); + if(elems[OVERLAPBEHAVIOR].getName().equals(e.getName())){ + final Expression expr = (Expression)value[i].getValue(); + + symbol.setOverlapBehavior(OverlapBehavior.valueOf("")); + } if(elems[COLORMAP].getName().equals(e.getName())) symbol.setColorMap((ColorMap)value[i].getValue()); @@ -2403,8 +2408,11 @@ if(elems[SOURCECHANNELNAME].getName().equals(e.getName())) symbol.setChannelName((String)value[i].getValue()); - if(elems[CONTRASTENHANCEMENT].getName().equals(e.getName())) - symbol.setContrastEnhancement((Expression)value[i].getValue()); + if(elems[CONTRASTENHANCEMENT].getName().equals(e.getName())){ + ContrastEnhancementImpl ce= new ContrastEnhancementImpl(); + ce.setGammaValue((Expression)value[i].getValue()); + symbol.setContrastEnhancement(ce); + } } return symbol; Index: opengis/src/main/java/org/opengis/style/ContrastMethod.java =================================================================== --- opengis/src/main/java/org/opengis/style/ContrastMethod.java (revision 37083) +++ opengis/src/main/java/org/opengis/style/ContrastMethod.java (working copy) @@ -21,9 +21,9 @@ * false-color image or for a color image. * * In the case of a color image, the relative grayscale brightness of a pixel color is used. - * “Normalize” means to stretch the contrast so that the dimmest color is stretched to black + * “Normalizeâ€� means to stretch the contrast so that the dimmest color is stretched to black * and the brightest color is stretched to white, with all colors in between stretched out - * linearly. “Histogram” means to stretch the contrast based on a histogram of how many + * linearly. “Histogramâ€� means to stretch the contrast based on a histogram of how many * colors are at each brightness level on input, with the goal of producing equal number of * pixels in the image at each brightness level on output. This has the effect of revealing * many subtle ground features. @@ -44,11 +44,11 @@ * List of all enumerations of this type. * Must be declared before any enum declaration. */ - private static final List VALUES = new ArrayList(3); + private static final List VALUES = new ArrayList(5); /** * Normalize enchancement. - * “Normalize” means to stretch the contrast so that the dimmest color is stretched to black + * “Normalizeâ€� means to stretch the contrast so that the dimmest color is stretched to black * and the brightest color is stretched to white, with all colors in between stretched out * linearly. */ @@ -57,12 +57,18 @@ /** * Histogram enchancement. - * “Histogram” means to stretch the contrast based on a histogram of how many + * “Histogramâ€� means to stretch the contrast based on a histogram of how many * colors are at each brightness level on input, with the goal of producing equal number of * pixels in the image at each brightness level on output. */ @XmlElement("Histogram") public static final ContrastMethod HISTOGRAM = new ContrastMethod("HISTOGRAM"); + + @XmlElement("Logarithmic") + public static final ContrastMethod LOGARITHMIC = new ContrastMethod("LOGARITHMIC"); + + @XmlElement("Exponential") + public static final ContrastMethod EXPONENTIAL = new ContrastMethod("EXPONENTIAL"); /** * No enchancement. Index: opengis/src/main/java/org/opengis/coverage/SampleDimension.java =================================================================== --- opengis/src/main/java/org/opengis/coverage/SampleDimension.java (revision 37083) +++ opengis/src/main/java/org/opengis/coverage/SampleDimension.java (working copy) @@ -77,7 +77,6 @@ * * @return The color interpretation of the sample dimension. * - * @deprecated No replacement. */ @UML(identifier="colorInterpretation", obligation=MANDATORY, specification=OGC_01004) ColorInterpretation getColorInterpretation(); Index: api/src/main/java/org/geotools/styling/StyleFactory.java =================================================================== --- api/src/main/java/org/geotools/styling/StyleFactory.java (revision 37083) +++ api/src/main/java/org/geotools/styling/StyleFactory.java (working copy) @@ -31,6 +31,7 @@ import org.opengis.filter.Id; import org.opengis.filter.expression.Expression; import org.opengis.metadata.citation.OnLineResource; +import org.opengis.style.OverlapBehavior; import org.opengis.util.InternationalString; @@ -232,7 +233,7 @@ public RasterSymbolizer createRasterSymbolizer(); public RasterSymbolizer createRasterSymbolizer(String geometryPropertyName, Expression opacity, - ChannelSelection channel, Expression overlap, ColorMap colorMap, ContrastEnhancement ce, + ChannelSelection channel, OverlapBehavior overlap, ColorMap colorMap, ContrastEnhancement ce, ShadedRelief relief, Symbolizer outline); public RasterSymbolizer getDefaultRasterSymbolizer(); Index: api/src/main/java/org/geotools/styling/ContrastEnhancement.java =================================================================== --- api/src/main/java/org/geotools/styling/ContrastEnhancement.java (revision 37083) +++ api/src/main/java/org/geotools/styling/ContrastEnhancement.java (working copy) @@ -61,63 +61,20 @@ * */ public interface ContrastEnhancement extends org.opengis.style.ContrastEnhancement { - /** - * Used to set the contrast enhancement method used. - * @param method - */ - public void setMethod( ContrastMethod method ); - /** - * @param type Should be a Literal of "Normalize" or "Histogram" or "None", if null supplied "None" is assumed - * @deprecated Please use setMethod - */ - public void setType(Expression type); - - /** - * Returns a literal expression (one of NORMALIZE, HISTOGRAM, NONE) - * indicating which ContrastMethod value is to be used. + * Used to set the contrast enhancement method used. * - * @deprecated Please use getMethod + * @param method */ - public Expression getType(); + public void setMethod(ContrastMethod method); + /** * @param gamma How much to brighten (greater than 1) or dim (less than 1) this channel; use 1.0 to indicate no change. */ - public void setGammaValue(Expression gamma); + public void setGammaValue(Expression gamma); /** - * How much to brighten (values greater than 1.0) or dim (values less than 1.0) an image. The default GammaValue is 1.0 - * (no change). - * - * @return Expression, if null a value of 1.0 is assumed indicating no change - */ - public Expression getGammaValue(); - - /** - * @deprecated Please use setMethod( ContrastMethodt.NORMALIZE ) - */ - @Deprecated - public void setNormalize(); - - /** - * @deprecated Please use setMethod( ContrastMethodt.HISTOGRAM ) - */ - @Deprecated - public void setHistogram(); - - /** - * @deprecated Please use setMethod; please note Logarithmic is not currently supported - */ - @Deprecated - public void setLogarithmic(); - - /** - * @deprecated Please use setMethod; please note Exponential is not currently supported - */ - public void setExponential(); - - /** * Traversal of the style data structure. * @param visitor */ Index: api/src/main/java/org/geotools/styling/RasterSymbolizer.java =================================================================== --- api/src/main/java/org/geotools/styling/RasterSymbolizer.java (revision 37083) +++ api/src/main/java/org/geotools/styling/RasterSymbolizer.java (working copy) @@ -158,40 +158,6 @@ ChannelSelection getChannelSelection(); /** - * The OverlapBehavior element tells a system how to behave when multiple - * raster images in a layer overlap each other, for example with - * satellite-image scenes. LATEST_ON_TOP and EARLIEST_ON_TOP refer to the - * time the scene was captured. AVERAGE means to average multiple scenes - * together. This can produce blurry results if the source images are not - * perfectly aligned in their geo-referencing. RANDOM means to select an - * image (or piece thereof) randomly and place it on top. This can - * produce crisper results than AVERAGE potentially more efficiently than - * LATEST_ON_TOP or EARLIEST_ON_TOP. The default behaviour is - * system-dependent. - * - * @param overlap the expression which evaluates to LATEST_ON_TOP, - * EARLIEST_ON_TOP, AVERAGE or RANDOM - */ - void setOverlap(Expression overlap); - - /** - * The OverlapBehavior element tells a system how to behave when multiple - * raster images in a layer overlap each other, for example with - * satellite-image scenes. LATEST_ON_TOP and EARLIEST_ON_TOP refer to the - * time the scene was captured. AVERAGE means to average multiple scenes - * together. This can produce blurry results if the source images are - * not perfectly aligned in their geo-referencing. RANDOM means to select - * an image (or piece thereof) randomly and place it on top. This can - * produce crisper results than AVERAGE potentially more efficiently than - * LATEST_ON_TOP or EARLIEST_ON_TOP. The default behaviour is - * system-dependent. - * - * @return The expression which evaluates to LATEST_ON_TOP, - * EARLIEST_ON_TOP, AVERAGE or RANDOM - */ - Expression getOverlap(); - - /** * Set the overlap behavior. * @param overlapBehavior */ Index: api/src/main/java/org/geotools/styling/StyleVisitor.java =================================================================== --- api/src/main/java/org/geotools/styling/StyleVisitor.java (revision 37083) +++ api/src/main/java/org/geotools/styling/StyleVisitor.java (working copy) @@ -16,7 +16,9 @@ */ package org.geotools.styling; +import org.opengis.style.OverlapBehavior; + /** * An interface for classes that want to perform operations on a Style * hierarchy. It forms part of a GoF Visitor Patern implementation. A call to Index: api/src/main/java/org/geotools/styling/SelectedChannelType.java =================================================================== --- api/src/main/java/org/geotools/styling/SelectedChannelType.java (revision 37083) +++ api/src/main/java/org/geotools/styling/SelectedChannelType.java (working copy) @@ -50,11 +50,6 @@ */ public String getChannelName(); - /** - * @deprecated Use {@link #setContrastEnhancement(ContrastEnhancement))} instead. - */ - public void setContrastEnhancement(Expression gammaValue); - public void setContrastEnhancement(org.opengis.style.ContrastEnhancement enhancement); public ContrastEnhancement getContrastEnhancement(); Index: api/src/main/java/org/geotools/styling/TextSymbolizer2.java =================================================================== --- api/src/main/java/org/geotools/styling/TextSymbolizer2.java (revision 37083) +++ api/src/main/java/org/geotools/styling/TextSymbolizer2.java (working copy) @@ -17,7 +17,6 @@ package org.geotools.styling; import org.opengis.filter.expression.Expression; -import org.opengis.style.Description; /** Index: api/src/main/java/org/geotools/styling/OverlapBehavior.java =================================================================== --- api/src/main/java/org/geotools/styling/OverlapBehavior.java (revision 37083) +++ api/src/main/java/org/geotools/styling/OverlapBehavior.java (working copy) @@ -1,73 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-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.styling; - -import org.geotools.filter.ConstantExpression; - - -/** - * OverlapBehavior tells a system how to behave when multiple raster images in - * a layer overlap each other, for example with satellite-image scenes. - *

- *

- *         
- *  <xsd:element name="OverlapBehavior">
- *      <xsd:annotation>
- *          <xsd:documentation>         "OverlapBehavior" tells a
- *              system how to behave when multiple         raster images in
- *              a layer overlap each other, for example with
- *              satellite-image scenes.       </xsd:documentation>
- *      </xsd:annotation>
- *      <xsd:complexType>
- *          <xsd:choice>
- *              <xsd:element ref="sld:LATEST_ON_TOP"/>
- *              <xsd:element ref="sld:EARLIEST_ON_TOP"/>
- *              <xsd:element ref="sld:AVERAGE"/>
- *              <xsd:element ref="sld:RANDOM"/>
- *          </xsd:choice>
- *      </xsd:complexType>
- *  </xsd:element>
- *
- *          
- *         
- *

- * - * @author Justin Deoliveira, The Open Planning Project - * - * @source $URL$ - * @deprecated Please use org.opengis.style.OverlapBehavior - */ -public class OverlapBehavior extends ConstantExpression { - public final static String AVERAGE_RESCTRICTION= "AVERAGE"; - public final static String RANDOM_RESCTRICTION= "RANDOM"; - public final static String LATEST_ON_TOP_RESCTRICTION= "LATEST_ON_TOP"; - public final static String EARLIEST_ON_TOP_RESCTRICTION= "EARLIEST_ON_TOP"; - public final static String UNSPECIFIED_RESCTRICTION = "UNSPECIFIED"; - - public static final OverlapBehavior LATEST_ON_TOP = new OverlapBehavior(OverlapBehavior.LATEST_ON_TOP_RESCTRICTION); - public static final OverlapBehavior EARLIEST_ON_TOP = new OverlapBehavior(OverlapBehavior.EARLIEST_ON_TOP_RESCTRICTION); - public static final OverlapBehavior AVERAGE = new OverlapBehavior(OverlapBehavior.AVERAGE_RESCTRICTION); - public static final OverlapBehavior RANDOM = new OverlapBehavior(OverlapBehavior.RANDOM_RESCTRICTION); - - private OverlapBehavior(String value) { - super(value); - } - - public void accept(org.geotools.styling.StyleVisitor visitor){ - visitor.visit(this); - } -}