Revision: 6681
          http://sourceforge.net/p/jump-pilot/code/6681
Author:   ma15569
Date:     2021-12-08 05:39:14 +0000 (Wed, 08 Dec 2021)
Log Message:
-----------
Added methods to map values and classes of values

Modified Paths:
--------------
    core/trunk/src/org/openjump/core/rasterimage/RasterImageLayer.java

Modified: core/trunk/src/org/openjump/core/rasterimage/RasterImageLayer.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/RasterImageLayer.java  
2021-12-03 05:10:19 UTC (rev 6680)
+++ core/trunk/src/org/openjump/core/rasterimage/RasterImageLayer.java  
2021-12-08 05:39:14 UTC (rev 6681)
@@ -9,22 +9,35 @@
  */
 package org.openjump.core.rasterimage;
 
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Point2D;
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
 import java.awt.image.IndexColorModel;
 import java.awt.image.Raster;
 import java.awt.image.renderable.ParameterBlock;
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Objects;
+import java.util.TreeMap;
 import java.util.UUID;
 
 import javax.media.jai.JAI;
 
-import com.vividsolutions.jump.workbench.model.Disposable;
 import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.Imaging;
 import org.openjump.core.ccordsys.utils.SRSInfo;
@@ -41,6 +54,7 @@
 import com.vividsolutions.jump.workbench.Logger;
 import com.vividsolutions.jump.workbench.WorkbenchContext;
 import com.vividsolutions.jump.workbench.model.AbstractLayerable;
+import com.vividsolutions.jump.workbench.model.Disposable;
 import com.vividsolutions.jump.workbench.model.LayerManager;
 import com.vividsolutions.jump.workbench.model.Layerable;
 import com.vividsolutions.jump.workbench.plugin.PlugInContext;
@@ -49,1323 +63,1421 @@
 import com.vividsolutions.jump.workbench.ui.Viewport;
 
 /**
- * Layer representing a georeferenced raster image (e.g. an areal photography) 
in OpenJump.
+ * Layer representing a georeferenced raster image (e.g. an areal photography)
+ * in OpenJump.
  *
- * @author Ole Rahn
- * <br>
- * <br>FH Osnabr&uuml;ck - University of Applied Sciences Osnabr&uuml;ck,
- * <br>Project: PIROL (2006),
- * <br>Subproject: Daten- und Wissensmanagement
- * 
- * @version $Rev: 2509 $
- * modified: [sstein]: 16.Feb.2009 changed logger-entries to comments, used 
frame.warnUser
+ * @author Ole Rahn <br>
+ *         <br>
+ *         FH Osnabr&uuml;ck - University of Applied Sciences Osnabr&uuml;ck,
+ *         <br>
+ *         Project: PIROL (2006), <br>
+ *         Subproject: Daten- und Wissensmanagement
+ *
+ * @version $Rev: 2509 $ modified: [sstein]: 16.Feb.2009 changed logger-entries
+ *          to comments, used frame.warnUser
  */
-public final class RasterImageLayer extends AbstractLayerable
-        implements ObjectContainingMetaInformation, Disposable {
-    
-    protected static Blackboard blackboard = null;
-    
-    protected final static String BLACKBOARD_KEY_PLUGINCONTEXT = 
PlugInContext.class.getName();
-    protected final static String BLACKBOARD_KEY_WORKBENCHCONTEXT = 
PlugInContext.class.getName();
-    
-    protected int lastImgProcessingMode = 0;
-    
-    protected final static int MODE_NONE = 0;
-    protected final static int MODE_SCALINGFIRST = 1;
-    protected final static int MODE_CLIPPINGFIRST = 2;
-    protected final static int MODE_FASTDISPLAY = 3;
-    
-    protected Rectangle imagePart, visibleRect = null;
-    
-    protected double oldScaleXImg2Canvas;
-    
-    protected int xOffset, yOffset;
+public final class RasterImageLayer extends AbstractLayerable implements 
ObjectContainingMetaInformation, Disposable {
 
-    protected double transparencyLevel = .0f;
-    
-    protected static long availRAM = Runtime.getRuntime().maxMemory();
-    protected static double freeRamFactor = 0.5;
-    protected static double minRamToKeepFree = availRAM * freeRamFactor;
-    //[sstein 9.Aug.2010]
-    // The value below is set dynamically based on available memory
-    //       now its 200x200px as min (originally it was 500x500)
-    //protected static int maxPixelsForFastDisplayMode = 40000;
-    protected static int maxPixelsForFastDisplayMode = 250000;
+       protected static Blackboard blackboard = null;
 
-    protected String imageFileName = null;
-    protected int origImageWidth, origImageHeight;
-    protected boolean imageSet = false;
-    protected BufferedImage image = null;
-    protected int numBands = 0;
-    
-    //-- [sstein 2nd Aug 2010] new, since we scale the image now for display
-    //protected Raster actualRasterData = null;
-    protected boolean rasterDataChanged = false; //may be needed for rescaling 
the image values
-    //-- end
+       protected final static String BLACKBOARD_KEY_PLUGINCONTEXT = 
PlugInContext.class.getName();
+       protected final static String BLACKBOARD_KEY_WORKBENCHCONTEXT = 
PlugInContext.class.getName();
 
-    protected BufferedImage scaledBufferedImage = null;
+       protected int lastImgProcessingMode = 0;
 
-    protected Envelope actualImageEnvelope = null, visibleEnv = null, 
oldVisibleEnv;
-    protected Envelope originalImageEnvelope = null;
-    
-    /**
-     * Flag to decide, if events are fired automatically, if the appearance 
(imageEnvelope, etc.) changes.<br>
-     * default: true
-     */
-    protected boolean firingAppearanceEvents = true;
-    
-    /**
-     * Flag to control if the image should be deleted from RAM as soon as 
possible to save RAM
-     * or if it should be kept e.g. because it was generated
-     * dynamically and can not be loaded from a file again, once it was 
deleted.
-     */
-    protected boolean needToKeepImage = false;
+       protected final static int MODE_NONE = 0;
+       protected final static int MODE_SCALINGFIRST = 1;
+       protected final static int MODE_CLIPPINGFIRST = 2;
+       protected final static int MODE_FASTDISPLAY = 3;
 
-    protected Color transparentColor = null;
-    protected boolean transparencyColorNeedsToBeApplied = false;
+       protected Rectangle imagePart, visibleRect = null;
 
-    //-- [sstein 26 June 2013] new as with ASCII grid imports nodata values 
can be defined
-    protected double noDataValue = Double.NaN;
-    protected double originalCellSize;
-    protected double actualCellSize;
-    //-- end
+       protected double oldScaleXImg2Canvas;
 
-    private Metadata metadata;
-    private int bitsPerPixel = -1;
-    
-    private Stats stats;
-    
-    private RasterSymbology symbology = null;
-    private boolean symbologyChanged = false;
-    private final UUID uuid = java.util.UUID.randomUUID();
-    
-    /**
-     * for java2xml
-     */
-    public RasterImageLayer() {
-        super();
-        getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, true);
-    }
-    
-    /**
-     * for java2xml
-     *@return the Envelope as string
-     */
-    public String getXmlEnvelope(){
-        return this.originalImageEnvelope.toString();
-    }
+       protected int xOffset, yOffset;
 
-    /**
-     * for java2xml
-     *@param envStr the Envelope as string
-     */
-    public void setXmlEnvelope(String envStr){
-        String coords = envStr.substring(envStr.indexOf("[")+1, 
envStr.indexOf("]"));
-        
-        String[] coordArray = coords.split(",");
-        
-        String[] xCoords = coordArray[0].split(":");
-        String[] yCoords = coordArray[1].split(":");
-        
-        double minX = java.lang.Double.parseDouble(xCoords[0]);
-        double maxX = java.lang.Double.parseDouble(xCoords[1]);
-        
-        double minY = java.lang.Double.parseDouble(yCoords[0]);
-        double maxY = java.lang.Double.parseDouble(yCoords[1]);
-        
-        this.setWholeImageEnvelope( new Envelope( minX, maxX, minY, maxY ) );
-    }    
+       protected double transparencyLevel = .0f;
 
-    /**
-     * @param name name of the layer
-     * @param layerManager the LayerManager
-     * @param imageFileName the name of the image file
-     * @param imageToDisplay the image (if already loaded) or null
-     * @param wholeImageEnvelope the image envelope in model (real world) 
coordinates
-     */
-    public RasterImageLayer(String name, LayerManager layerManager, String 
imageFileName,
-                            BufferedImage imageToDisplay, Envelope 
wholeImageEnvelope) {
-        super(name, layerManager);
-        
-        getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, true);
-        
-        this.imageFileName = imageFileName;
-        this.originalImageEnvelope = wholeImageEnvelope;
-        
-        if (imageToDisplay != null)
-            this.setImage(imageToDisplay);
+       protected static long availRAM = Runtime.getRuntime().maxMemory();
+       protected static double freeRamFactor = 0.5;
+       protected static double minRamToKeepFree = availRAM * freeRamFactor;
+       // [sstein 9.Aug.2010]
+       // The value below is set dynamically based on available memory
+       // now its 200x200px as min (originally it was 500x500)
+       // protected static int maxPixelsForFastDisplayMode = 40000;
+       protected static int maxPixelsForFastDisplayMode = 250000;
 
-        //[sstein 9.Aug.2010]       
-        long avram = getAvailRAM();
-        if(avram > 256000000){
-               maxPixelsForFastDisplayMode = 250000; //500x500 px
-        }
-        if(avram > 750000000){
-               maxPixelsForFastDisplayMode = 4000000; //2000x2000 px
-        }
-        //[sstein end]
-    }
-    
-    
-    /**
-     * Constructor to be used in case the image was not loaded from a file, so 
there is
-     * no file name, but an image
-     * 
-     *@param name name of the layer
-     *@param layerManager the LayerManager
-     *@param imageToDisplay the image (if already loaded) or null
-     *@param newRaster the raster (if already loaded) or null
-     *@param wholeImageEnvelope the image envelope in model (real world) 
coordinates
-     */
-    public RasterImageLayer(String name, LayerManager layerManager, 
BufferedImage imageToDisplay, Raster newRaster, Envelope wholeImageEnvelope) {
-        super(name, layerManager);
+       protected String imageFileName = null;
+       protected int origImageWidth, origImageHeight;
+       protected boolean imageSet = false;
+       protected BufferedImage image = null;
+       protected int numBands = 0;
 
-        if (imageToDisplay == null || newRaster == null) {
-            Logger.warn("imageToDisplay and newRaster must not be null");
-            return;
-        }
-        
-        getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, true);
-        
-        this.setNeedToKeepImage(true);
-        this.originalImageEnvelope = wholeImageEnvelope;
-        
-        this.setImage(imageToDisplay);
+       // -- [sstein 2nd Aug 2010] new, since we scale the image now for 
display
+       // protected Raster actualRasterData = null;
+       protected boolean rasterDataChanged = false; // may be needed for 
rescaling the image values
+       // -- end
 
-        //[sstein 9.Aug.2010]
-        long avram = getAvailRAM();
-        if(avram > 256000000){
-               maxPixelsForFastDisplayMode = 250000; //500x500 px
-        }
-        if(avram > 750000000){
-               maxPixelsForFastDisplayMode = 563500; //750x750 px
-        }
-        //[sstein end]
-    }
+       protected BufferedImage scaledBufferedImage = null;
 
-    @Override
-    public Blackboard getBlackboard() {
-        if (RasterImageLayer.blackboard == null)
-            RasterImageLayer.blackboard = new Blackboard();
-        
-        return RasterImageLayer.blackboard;
-    }
+       protected Envelope actualImageEnvelope = null, visibleEnv = null, 
oldVisibleEnv;
+       protected Envelope originalImageEnvelope = null;
 
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        RasterImageLayer raster = null;
-        try {
-            raster = new RasterImageLayer(getName(), getLayerManager(), 
getImageFileName(),
-                    getImageForDisplay(), new 
Envelope(getWholeImageEnvelope()));
-            raster.needToKeepImage = needToKeepImage;
-        } catch (Exception ex) {
-            Logger.error(ex);
-        }
-        // clone must produce a layerable with the same name (as for Layer) 
not a unique name
-        if (raster != null) {
-            raster.getLayerManager().setFiringEvents(false);
-            raster.setName(getName());
-            raster.getLayerManager().setFiringEvents(true);
-        }
-        return raster;
-    }
-    
-    /**
-     * apply a scale operation to the image and return the new image.
-     */
-    protected BufferedImage scaleImage(BufferedImage im, float xScale, float 
yScale) {
-        ParameterBlock pb = new ParameterBlock();
-        pb.addSource(im);
-        pb.add(xScale);
-        pb.add(yScale);
-        // @TODO Try to replace JAI by Graphics2D after migration to 2.0
-        //BufferedImage resizedImage =
-        //        new BufferedImage((int)(im.getWidth()*xScale), 
(int)(im.getHeight()*yScale), im.getType());
-        //Graphics2D graphics2D = resizedImage.createGraphics();
-        
//graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-        
//graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
-        //graphics2D.drawImage(im, 0, 0, (int)(im.getWidth()*xScale), 
(int)(im.getHeight()*yScale), null);
-        //graphics2D.dispose();
-        //return resizedImage;
-        return JAI.create("Scale", pb, null).getAsBufferedImage();
-    }
+       /**
+        * Flag to decide, if events are fired automatically, if the appearance
+        * (imageEnvelope, etc.) changes.<br>
+        * default: true
+        */
+       protected boolean firingAppearanceEvents = true;
 
+       /**
+        * Flag to control if the image should be deleted from RAM as soon as 
possible
+        * to save RAM or if it should be kept e.g. because it was generated 
dynamically
+        * and can not be loaded from a file again, once it was deleted.
+        */
+       protected boolean needToKeepImage = false;
 
-    /**
-     * Create a single color image in the case where a single image pixel is 
visible
-     * @param color color of the pixel
-     * @return a single color BufferedImage
-     */
-    protected BufferedImage createOneColorImage(Color color){
-        BufferedImage bim = new BufferedImage(visibleRect.width, 
visibleRect.height, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D grfcs = bim.createGraphics();
-        grfcs.setColor(color);
-        grfcs.fillRect( 0, 0, bim.getWidth(), bim.getHeight() );
-        grfcs.dispose();
-        return bim;
-    }
-    
-    /**
-     * Creates the image to draw
-     * @param layerViewPanel the LayerViewPanel where the image will be drawn
-     * @return the BufferedImage to be drawn
-     */
-    public BufferedImage createImage(LayerViewPanel layerViewPanel) {
-        
-        Viewport viewport = layerViewPanel.getViewport();
-        
-        if (!this.isVisible() || this.transparencyLevel >= 1.0) {
-            this.setImageProcessingMode(RasterImageLayer.MODE_NONE);
-            this.clearImageAndRaster(true);
-            return null;
-        }
+       protected Color transparentColor = null;
+       protected boolean transparencyColorNeedsToBeApplied = false;
 
-        BufferedImage imageToDraw = null;
+       // -- [sstein 26 June 2013] new as with ASCII grid imports nodata 
values can be
+       // defined
+       protected double noDataValue = Double.NaN;
+       protected double originalCellSize;
+       protected double actualCellSize;
+       // -- end
 
-        try {
+       private Metadata metadata;
+       private int bitsPerPixel = -1;
 
-            java.awt.Point imageDims = 
RasterImageIO.getImageDimensions(imageFileName);
+       private Stats stats;
 
-            assert imageDims != null;
-            origImageWidth = imageDims.x;
-            origImageHeight = imageDims.y;
-            visibleRect = viewport.getPanel().getVisibleRect();
+       private RasterSymbology symbology = null;
+       private boolean symbologyChanged = false;
+       private final UUID uuid = java.util.UUID.randomUUID();
 
-            int visibleX1 = visibleRect.x;
-            int visibleY1 = visibleRect.y;
-            int visibleX2 = visibleX1 + visibleRect.width;
-            int visibleY2 = visibleY1 + visibleRect.height;
+       /**
+        * for java2xml
+        */
+       public RasterImageLayer() {
+               super();
+               getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, 
true);
+       }
 
-            // Viewport envelope in model coordinates
-            Coordinate upperLeftVisible = viewport.toModelCoordinate(new 
Point(visibleX1, visibleY1));
-            Coordinate lowerRightVisible = viewport.toModelCoordinate(new 
Point(visibleX2, visibleY2));
-            Envelope newVisibleEnv = new Envelope(upperLeftVisible, 
lowerRightVisible);
+       /**
+        * for java2xml
+        * 
+        * @return the Envelope as string
+        */
+       public String getXmlEnvelope() {
+               return this.originalImageEnvelope.toString();
+       }
 
-            setImageSet(false);
-            
-            if (visibleEnv == null || visibleEnv.getMinX() != 
newVisibleEnv.getMinX() || visibleEnv.getMaxX() != newVisibleEnv.getMaxX() || 
-                    visibleEnv.getMinY() != newVisibleEnv.getMinY() || 
visibleEnv.getMaxY() != newVisibleEnv.getMaxY() || symbologyChanged){
-                visibleEnv = newVisibleEnv;
-                    
-                symbologyChanged = false;
-                this.setNeedToKeepImage(false);
-                if (bitsPerPixel == -1) {
-                    if (imageFileName.toLowerCase().endsWith(".flt")) 
bitsPerPixel = 16;
-                    else if (imageFileName.toLowerCase().endsWith(".asc")) 
bitsPerPixel = 16;
-                    else if (imageFileName.toLowerCase().endsWith(".txt")) 
bitsPerPixel = 16;
-                    else {
-                        try {
-                            bitsPerPixel = Imaging.getImageInfo(new 
File(imageFileName)).getBitsPerPixel();
-                        } catch(ImageReadException e) {
-                            Logger.warn("Can't get ImageInfo of " + 
imageFileName, e);
-                        }
-                    }
-                }
-                clearImageAndRaster(true);
-                // Check that there is enough free memory for the image + 1% 
of available memory + 10Mb
-                if (getAvailRAM()-getCommittedMemory() <
-                        origImageWidth*origImageHeight*bitsPerPixel/8 + 
getAvailRAM()*0.01 + 10*1024*1024) {
-                    layerViewPanel.getContext().warnUser("Low Memory : image " 
+
-                            imageFileName + " will not be displayed");
-                    System.out.println("" + 
(getAvailRAM()-getCommittedMemory())/1024 + "kb < " +
-                            
(origImageWidth*origImageHeight*bitsPerPixel/8)/1024 + "kb " +
-                            getAvailRAM()*0.01/1024 + "kb + 10240");
-                    return null;
-                } else {
-                    System.out.println("Reload image");
-                }
-                // Load the part of the image intersecting the viewport and 
setting this.image
-                reLoadImage();
-                if(image == null) {
-                    // If image does not intersect viewport, it is null
-                    return null;
-                }                    
+       /**
+        * for java2xml
+        * 
+        * @param envStr the Envelope as string
+        */
+       public void setXmlEnvelope(String envStr) {
+               final String coords = envStr.substring(envStr.indexOf("[") + 1, 
envStr.indexOf("]"));
 
-                // Coordinates of actual image in viewport coordinates
-                Point2D upperLeftCornerOfImage = viewport.toViewPoint(new 
Coordinate(getActualImageEnvelope().getMinX(), 
getActualImageEnvelope().getMaxY()));
-                Point2D lowerRightCornerOfImage = viewport.toViewPoint(new 
Coordinate(getActualImageEnvelope().getMaxX(), 
getActualImageEnvelope().getMinY()));
+               final String[] coordArray = coords.split(",");
 
-                double scaledWidth = lowerRightCornerOfImage.getX() - 
upperLeftCornerOfImage.getX();
-                double scaledHeight = upperLeftCornerOfImage.getY() - 
lowerRightCornerOfImage.getY();
+               final String[] xCoords = coordArray[0].split(":");
+               final String[] yCoords = coordArray[1].split(":");
 
-                // Apply symbology to this.image
-                imageToDraw = stretchImageValuesForDisplay();
-                setImage(imageToDraw);
+               final double minX = java.lang.Double.parseDouble(xCoords[0]);
+               final double maxX = java.lang.Double.parseDouble(xCoords[1]);
 
-                //if(getCommittedMemory() + minRamToKeepFree < availRAM){
-                    //setNeedToKeepImage(true); //so small images are not 
reloaded every time
-                //}
+               final double minY = java.lang.Double.parseDouble(yCoords[0]);
+               final double maxY = java.lang.Double.parseDouble(yCoords[1]);
 
-                //[sstein end]
-                //Compute envelope of the visible part
-                imagePart = 
getVisibleImageCoordinatesOfImage(image.getWidth(), image.getHeight(),
-                        visibleEnv, getActualImageEnvelope());
+               this.setWholeImageEnvelope(new Envelope(minX, maxX, minY, 
maxY));
+       }
 
-                double scaleXImg2Canvas = scaledWidth / image.getWidth();
-                double scaleYImg2Canvas = scaledHeight / image.getHeight();
+       /**
+        * @param name               name of the layer
+        * @param layerManager       the LayerManager
+        * @param imageFileName      the name of the image file
+        * @param imageToDisplay     the image (if already loaded) or null
+        * @param wholeImageEnvelope the image envelope in model (real world)
+        *                           coordinates
+        */
+       public RasterImageLayer(String name, LayerManager layerManager, String 
imageFileName, BufferedImage imageToDisplay,
+                       Envelope wholeImageEnvelope) {
+               super(name, layerManager);
 
-                if (scaledBufferedImage == null || scaleXImg2Canvas != 
oldScaleXImg2Canvas ||
-                        !RasterImageLayer.tilesAreNotNullAndCongruent( 
visibleEnv, oldVisibleEnv)){
+               getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, 
true);
 
-                    scaledBufferedImage = getVisiblePartOfTheImage( 
getImageForDisplay(), imagePart );
+               this.imageFileName = imageFileName;
+               this.originalImageEnvelope = wholeImageEnvelope;
 
-                    if (scaledBufferedImage != null) {
-                        // avoid an 1 pixel by 1 pixel image to get scaled to 
thousands by thousands pixels causing an out of memory error
-                        if (imagePart.width == 1 || imagePart.height == 1){
-                            xOffset = 0;
-                            yOffset = 0;
-                            scaledBufferedImage = createOneColorImage(
-                                    new 
Color(scaledBufferedImage.getRGB(0,0)));
-                        } else {
-                            scaledBufferedImage = 
getScaledImageMatchingVisible(scaledBufferedImage, scaleXImg2Canvas, 
scaleYImg2Canvas );
-                        }
+               if (imageToDisplay != null) {
+                       this.setImage(imageToDisplay);
+               }
 
-                    } else {
-                        return null;
-                    }
+               // [sstein 9.Aug.2010]
+               final long avram = getAvailRAM();
+               if (avram > 256000000) {
+                       maxPixelsForFastDisplayMode = 250000; // 500x500 px
+               }
+               if (avram > 750000000) {
+                       maxPixelsForFastDisplayMode = 4000000; // 2000x2000 px
+               }
+               // [sstein end]
+       }
 
-                    if (transparentColor!=null) 
transparencyColorNeedsToBeApplied = true;
+       /**
+        * Constructor to be used in case the image was not loaded from a file, 
so there
+        * is no file name, but an image
+        * 
+        * @param name               name of the layer
+        * @param layerManager       the LayerManager
+        * @param imageToDisplay     the image (if already loaded) or null
+        * @param newRaster          the raster (if already loaded) or null
+        * @param wholeImageEnvelope the image envelope in model (real world)
+        *                           coordinates
+        */
+       public RasterImageLayer(String name, LayerManager layerManager, 
BufferedImage imageToDisplay, Raster newRaster,
+                       Envelope wholeImageEnvelope) {
+               super(name, layerManager);
 
-                    xOffset = (int)(xOffset *scaleXImg2Canvas);
-                    yOffset = (int)(yOffset *(-scaleYImg2Canvas));
+               if (imageToDisplay == null || newRaster == null) {
+                       Logger.warn("imageToDisplay and newRaster must not be 
null");
+                       return;
+               }
 
-                    oldScaleXImg2Canvas = scaleXImg2Canvas;
+               getBlackboard().put(LayerNameRenderer.USE_CLOCK_ANIMATION_KEY, 
true);
 
-                    oldVisibleEnv = visibleEnv;
-                }
-    
-                               
-            }
+               this.setNeedToKeepImage(true);
+               this.originalImageEnvelope = wholeImageEnvelope;
 
-            if (scaledBufferedImage != null && 
transparencyColorNeedsToBeApplied ){
-                imageToDraw = setupTransparency(scaledBufferedImage);
-            } else if (scaledBufferedImage != null) {
-                imageToDraw = scaledBufferedImage;
-            }
-            
+               this.setImage(imageToDisplay);
 
-        } catch (Exception e){
-            Logger.warn(e);
-        }
-        if (imageToDraw != null) {
-            return imageToDraw;
-        } else {
-            return scaledBufferedImage;
-        }
-    }
+               // [sstein 9.Aug.2010]
+               final long avram = getAvailRAM();
+               if (avram > 256000000) {
+                       maxPixelsForFastDisplayMode = 250000; // 500x500 px
+               }
+               if (avram > 750000000) {
+                       maxPixelsForFastDisplayMode = 563500; // 750x750 px
+               }
+               // [sstein end]
+       }
 
-    protected long getCommittedMemory() {
-        return Runtime.getRuntime().totalMemory() - 
Runtime.getRuntime().freeMemory();
-    }
-    
-    /**
-     * Deletes image from RAM (if it is not to be kept and if the RAM 
consumption is high)
-     * and calls the garbage collector, if <code>garbageCollect</code> is true.
-     * @param garbageCollect if true the garbage collector will be called 
(this parameter
-     *                       may be overridden, if there is not enough RAM 
available...)
-     */
-    public boolean clearImageAndRaster(boolean garbageCollect){
-        boolean reallyNeedToFreeRAM = (availRAM-getCommittedMemory() < 
minRamToKeepFree);
-        if (!needToKeepImage && reallyNeedToFreeRAM ){
-            flushImages(garbageCollect);
-        }
-        else if (garbageCollect){
-            Runtime.getRuntime().gc();
-        }
-        return reallyNeedToFreeRAM;
-    }
-    
-    /**
-     * flushes all images from the RAM.
-     * @param garbageCollect if true the garbage collector will be called 
(this parameter may be overridden, if there is not enough RAM available...)
-     */
-    public void flushImages(boolean garbageCollect){
-        if (image!=null)
-            image.flush();
-        image = null;
-        if (scaledBufferedImage!=null)
-            scaledBufferedImage.flush();
-        scaledBufferedImage = null;
-        if (garbageCollect){
-            Runtime.getRuntime().gc();
-        }
-    }
-    
-    public void reLoadImage() throws Exception {
-        
-        //if (image == null && !needToKeepImage){
-        
-        RasterImageIO rasterImageIO = new RasterImageIO();
+       @Override
+       public Blackboard getBlackboard() {
+               if (RasterImageLayer.blackboard == null) {
+                       RasterImageLayer.blackboard = new Blackboard();
+               }
 
-        Viewport viewport = 
getWorkbenchContext().getLayerViewPanel().getViewport();
-        
if(!viewport.getEnvelopeInModelCoordinates().intersects(originalImageEnvelope) 
&&
-                
getWorkbenchContext().getLayerManager().getLayerables(Layerable.class).isEmpty())
 {
-            viewport.zoom(originalImageEnvelope);
-        }
+               return RasterImageLayer.blackboard;
+       }
 
-        Resolution requestedRes = 
RasterImageIO.calcRequestedResolution(viewport);
-        long start = Timer.milliSecondsSince(0);
-        Logger.debug("Try reading "+getName());
-        // Get the part of the image intersecting the viewport
-        ImageAndMetadata imageAndMetadata = 
rasterImageIO.loadImage(getWorkbenchContext(), imageFileName, stats, 
viewport.getEnvelopeInModelCoordinates(), requestedRes);
-        Logger.debug("Reading '"+getName()+"' took 
"+Timer.secondsSinceString(start)+"s.");
-        metadata = imageAndMetadata.getMetadata();
-        image = imageAndMetadata.getImage();
-        numBands = metadata.getStats().getBandCount();
-        noDataValue = imageAndMetadata.getMetadata().getNoDataValue();
-        stats = imageAndMetadata.getMetadata().getStats();
-        originalImageEnvelope = 
imageAndMetadata.getMetadata().getOriginalImageEnvelope();
-        actualImageEnvelope = 
imageAndMetadata.getMetadata().getActualEnvelope();
-        originalCellSize = 
imageAndMetadata.getMetadata().getOriginalCellSize();        
-        actualCellSize = imageAndMetadata.getMetadata().getActualCellSize();
+       @Override
+       public Object clone() throws CloneNotSupportedException {
+               RasterImageLayer raster = null;
+               try {
+                       raster = new RasterImageLayer(getName(), 
getLayerManager(), getImageFileName(), getImageForDisplay(),
+                                       new Envelope(getWholeImageEnvelope()));
+                       raster.needToKeepImage = needToKeepImage;
+               } catch (final Exception ex) {
+                       Logger.error(ex);
+               }
+               // clone must produce a layerable with the same name (as for 
Layer) not a unique
+               // name
+               if (raster != null) {
+                       raster.getLayerManager().setFiringEvents(false);
+                       raster.setName(getName());
+                       raster.getLayerManager().setFiringEvents(true);
+               }
+               return raster;
+       }
 
-        if(image != null) {
-            setImage(image);
-        }
-    }
-    
-    /**
-     * use this to assign the raster data again
-     * the method is called from  getRasterData();
-     */
-    public void reLoadImageButKeepImageForDisplay() throws Exception {
-       BufferedImage pi = getImageForDisplay();
-       //[sstein 24.Sept.2010] commented out:
-       //PlanarImage dontNeedThisImage = RasterImageLayer.loadImage( context, 
imageFileName); //causes error for .clone()
-       this.setImage(pi);
-    }
-    
-    protected BufferedImage stretchImageValuesForDisplay() throws 
NoninvertibleTransformException{
+       /**
+        * apply a scale operation to the image and return the new image.
+        */
+       protected BufferedImage scaleImage(BufferedImage im, float xScale, 
float yScale) {
+               final ParameterBlock pb = new ParameterBlock();
+               pb.addSource(im);
+               pb.add(xScale);
+               pb.add(yScale);
+               // @TODO Try to replace JAI by Graphics2D after migration to 2.0
+               // BufferedImage resizedImage =
+               // new BufferedImage((int)(im.getWidth()*xScale), 
(int)(im.getHeight()*yScale),
+               // im.getType());
+               // Graphics2D graphics2D = resizedImage.createGraphics();
+               // 
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+               // 
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
+               // graphics2D.drawImage(im, 0, 0, (int)(im.getWidth()*xScale),
+               // (int)(im.getHeight()*yScale), null);
+               // graphics2D.dispose();
+               // return resizedImage;
+               return JAI.create("Scale", pb, null).getAsBufferedImage();
+       }
 
-        Raster actualRasterData = image.copyData(null);
-        int width = actualRasterData.getWidth();
-        int height = actualRasterData.getHeight();
+       /**
+        * Create a single color image in the case where a single image pixel 
is visible
+        * 
+        * @param color color of the pixel
+        * @return a single color BufferedImage
+        */
+       protected BufferedImage createOneColorImage(Color color) {
+               final BufferedImage bim = new BufferedImage(visibleRect.width, 
visibleRect.height, BufferedImage.TYPE_INT_ARGB);
+               final Graphics2D grfcs = bim.createGraphics();
+               grfcs.setColor(color);
+               grfcs.fillRect(0, 0, bim.getWidth(), bim.getHeight());
+               grfcs.dispose();
+               return bim;
+       }
 
-        // Need to change image type to support transparency and apply 
symbology
-        if(image.getColorModel() instanceof IndexColorModel) {
-            return image;  
-        }
+       /**
+        * Creates the image to draw
+        * 
+        * @param layerViewPanel the LayerViewPanel where the image will be 
drawn
+        * @return the BufferedImage to be drawn
+        */
+       public BufferedImage createImage(LayerViewPanel layerViewPanel) {
 
-        BufferedImage newImage = new BufferedImage(width, height, 
BufferedImage.TYPE_4BYTE_ABGR);
-        for (int row = 0; row < height; row++) {
-            for (int col = 0; col < width; col++) {
+               final Viewport viewport = layerViewPanel.getViewport();
 
-                if(symbology == null) {
-                    if(stats.getBandCount() < 3) {
-                        
-                        final RasterSymbology rasterSymbology;
-                        //If there is onòy one value in the raster, the color 
will set to Black
-                        //to avoid confusion between raster color and color of 
the view
-                        if (metadata.getStats().getMin(0) == metadata
-                                .getStats().getMax(0)) {
-                            rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_SINGLE);
-                            
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.BLACK);
-                            
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.BLACK);   
-                            
-                        } else {
-                               //Standard representation of B/W raster
-                            rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_RAMP);
-                            
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.BLACK);
-                            
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.WHITE);
-                        }
-                        if (!Double.isNaN(metadata.getNoDataValue())) {
-                            
rasterSymbology.addColorMapEntry(metadata.getNoDataValue(), transparentColor);
-                        }
-                        
-                        
-                      /*  if (metadata.getStats().getMin(0) == metadata
-                                .getStats().getMax(0)) {
-                            rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_SINGLE);
-                        } else {
-                            rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_RAMP);
-                        }
-                        if (!Double.isNaN(metadata.getNoDataValue())) {
-                            
rasterSymbology.addColorMapEntry(metadata.getNoDataValue(), transparentColor);
-                        }
-                        
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.WHITE);
-                        
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.BLACK);*/
-                        
-                        
-                        setSymbology(rasterSymbology);
-                        
-                    } else {
-                        double valueR = actualRasterData.getSampleDouble(col, 
row, 0);
-                        double valueG = actualRasterData.getSampleDouble(col, 
row, 1);
-                        double valueB = actualRasterData.getSampleDouble(col, 
row, 2);
-                        double valueAlpha = 255;
-                        if(stats.getBandCount() > 3) {
-                            valueAlpha = actualRasterData.getSampleDouble(col, 
row, 3);
-                        }
-                        if(Double.isNaN(valueR) || Double.isInfinite(valueR) 
|| valueR == noDataValue
-                                || Double.isNaN(valueG) || 
Double.isInfinite(valueG) || valueG == noDataValue
-                                || Double.isNaN(valueB) || 
Double.isInfinite(valueB) || valueB == noDataValue
-                                || valueAlpha <= 0) {
-                            newImage.setRGB(col, row, Color.TRANSLUCENT);
-                            continue;
-                        }
-                        
-                        int r = (int) ((valueR - stats.getMin(0)) * 
255./(stats.getMax(0) - stats.getMin(0)));
-                        if(r > 255) r = 255;
-                        if(r < 0) r = 0;
-                        int g = (int) ((valueG - stats.getMin(1)) * 
255./(stats.getMax(1) - stats.getMin(0)));
-                        if(g > 255) g = 255;
-                        if(g < 0) g = 0;
-                        int b = (int) ((valueB - stats.getMin(2)) * 
255./(stats.getMax(2) - stats.getMin(0)));
-                        if(b > 255) b = 255;
-                        if(b < 0) b = 0;
+               if (!this.isVisible() || this.transparencyLevel >= 1.0) {
+                       this.setImageProcessingMode(RasterImageLayer.MODE_NONE);
+                       this.clearImageAndRaster(true);
+                       return null;
+               }
 
-                        int alpha = (int) valueAlpha;
-                        
-                        newImage.setRGB(col, row, new Color(r, g, b, 
alpha).getRGB());
-                    }
-                } else {
-                    // Symbology exists
-                    double value = actualRasterData.getSampleDouble(col, row, 
0);
-                    
+               BufferedImage imageToDraw = null;
 
-                    // If symbology min value is higher than raster min value
-                    // the value becomes equal to the symbology min value
-                    Double[] symbologyClassLimits =  
symbology.getColorMapEntries_tm().keySet().toArray(new Double[0]);
-                    double symbMinValue = symbologyClassLimits[0];
-                    double symbFirstValue = symbologyClassLimits[0];
-                    if(this.isNoData(symbFirstValue)) {
-                        symbMinValue = symbologyClassLimits[1];
-                    }
-                    
-                    if(!this.isNoData(value) && value < symbMinValue) {
-                        value = symbMinValue;
-                    }
-                    
-                    Color color = symbology.getColor(value);
-                    
-                    if((Double.isNaN(value) || Double.isInfinite(value) || 
this.isNoData(value))
-                            && color == null) {
-                        newImage.setRGB(col, row, Color.TRANSLUCENT);
-                        continue;
-                    }
-                    
-                    // Transparency is a combination of total layer 
transparency
-                    // and single cell transparency
-                    int transparency = 
-                            (int)(((1 - symbology.getTransparency()) * 
-                            (color.getAlpha() / 255d)) * 255);
-                    newImage.setRGB(col, row, new Color(
-                            color.getRed(),
-                            color.getGreen(),
-                            color.getBlue(),
-                            transparency).getRGB());
-                }  
-            }
-        }
-        return newImage;
-    }
-    
-    /**
-     * @return Envelope with the real world coordinates of the image
-     */
-    public Envelope getWholeImageEnvelope() {
-        return originalImageEnvelope;
-    }
-    
-    public Envelope getActualImageEnvelope() {
-        return actualImageEnvelope;
-    }
-    
-    /**
-     * Sets the Envelope containing the real world coordinates (e.g. WGS84) of 
the image
-     * this needs to be set (if it wasn't given to the constructor)!
-     * @param envelope the Envelope
-     */
-    private void setWholeImageEnvelope(Envelope envelope) {
-        originalImageEnvelope = envelope;
-        
-        forceTotalRepaint();
-        
-        if (this.isFiringAppearanceEvents())
-            this.fireAppearanceChanged();
-    }
-    
-    private void setActualImageEnvelope(Envelope envelope) {
-        actualImageEnvelope = envelope;
-        
-        forceTotalRepaint();
-        
-        if (isFiringAppearanceEvents())
-            fireAppearanceChanged();
-    }
-    
-    /**
-     * for java2xml
-     *@return the Envelope as string
-     */
-    public String getXmlWholeImageEnvelope(){
-        return this.originalImageEnvelope.toString();
-    }
-    
-    public String getXmlActualImageEnvelope() {
-        return this.actualImageEnvelope.toString();
-    }
-    
-    /**
-     * for java2xml
-     *@param envStr the Envelope as string
-     */
-    public void setXmlWholeImageEnvelope(String envStr){
-        String coords = envStr.substring(envStr.indexOf("[")+1, 
envStr.indexOf("]"));
-        
-        String[] coordArray = coords.split(",");
-        
-        String[] xCoords = coordArray[0].split(":");
-        String[] yCoords = coordArray[1].split(":");
-        
-        double minX = java.lang.Double.parseDouble(xCoords[0]);
-        double maxX = java.lang.Double.parseDouble(xCoords[1]);
-        
-        double minY = java.lang.Double.parseDouble(yCoords[0]);
-        double maxY = java.lang.Double.parseDouble(yCoords[1]);
-        
-        this.setWholeImageEnvelope( new Envelope( minX, maxX, minY, maxY ) );
-    }
-    
-    public void setXmlActualImageEnvelope(String envStr){
-        String coords = envStr.substring(envStr.indexOf("[")+1, 
envStr.indexOf("]"));
-        
-        String[] coordArray = coords.split(",");
-        
-        String[] xCoords = coordArray[0].split(":");
-        String[] yCoords = coordArray[1].split(":");
-        
-        double minX = java.lang.Double.parseDouble(xCoords[0]);
-        double maxX = java.lang.Double.parseDouble(xCoords[1]);
-        
-        double minY = java.lang.Double.parseDouble(yCoords[0]);
-        double maxY = java.lang.Double.parseDouble(yCoords[1]);
-        
-        this.setActualImageEnvelope( new Envelope( minX, maxX, minY, maxY ) );
-    }
-    
-    /**
-     * Method to change the coordinates of the image and later apply the
-     * changes to the RasterImageLayer by using
-     * {@link RasterImageLayer#setGeometryAsWholeImageEnvelope(Geometry)}.
-     * @return return the imageEnvelope (= bounding box) as a geometry,
-     */
-    public Geometry getWholeImageEnvelopeAsGeometry(){
-        return new GeometryFactory().toGeometry(originalImageEnvelope);
-    }
-    
-    public Geometry getActualImageEnvelopeAsGeometry(){
-        return new GeometryFactory().toGeometry(actualImageEnvelope);
-    }
-    
-    /**
-     * Method to set the coordinates of the image, e.g. after changing them 
after using
-     * {@link RasterImageLayer#getWholeImageEnvelopeAsGeometry()}.
-     */
-    public void setGeometryAsWholeImageEnvelope(Geometry geometry){
-        setWholeImageEnvelope(geometry.getEnvelopeInternal());
-    }
-    
-    public void setGeometryAsActualImageEnvelope(Geometry geometry){
-        setActualImageEnvelope(geometry.getEnvelopeInternal());
-    }
-    
-    /**
-     * Add transparency to the image (more exactly: to each pixel which a 
color == this.transparentColor)
-     *@param bim the image
-     */
-    private BufferedImage setupTransparency(BufferedImage bim){
-        //BufferedImage bim = pImage.getAsBufferedImage();
-        
-        ColorModel cm = bim.getColorModel();
-        int fullTransparencyAlpha = 255;
-        
-        if (this.getTransparentColor()==null){
-            return null;
-        }
-        
-        int transparentColor = this.getTransparentColor().getRGB();
-        
-        int[] argb = new int[4];
-        
-        if (!cm.hasAlpha()){
-            bim = RasterImageLayer.makeBufferedImage(bim);
-            //cm = bim.getColorModel();
-           
-        }
-        
-        for( int w=0; w<bim.getWidth(); w++){
-            for (int h=0; h<bim.getHeight(); h++){
+               try {
 
-                if (bim.getRGB(w,h)==transparentColor){
-                    Color color = new Color(bim.getRGB(w, h));
-                    
-                    argb[0] = fullTransparencyAlpha;
-                    argb[1] = color.getRed();
-                    argb[2] = color.getGreen();
-                    argb[3] = color.getBlue();
-                    
-                    bim.setRGB(w,h,1,1,argb,0,1);
-                }
-            }
-        }
-        
-        return bim;
-    }
-    
-    private void setImageProcessingMode( int nr ){
-        if (lastImgProcessingMode != nr){
+                       final java.awt.Point imageDims = 
RasterImageIO.getImageDimensions(imageFileName);
 
-            imagePart = null;
-            
-            oldScaleXImg2Canvas = -1;
-            
-            if (Runtime.getRuntime().freeMemory() < 
RasterImageLayer.getMinRamToKeepFree()){
-                Runtime.getRuntime().gc();
-            }
-            
-            lastImgProcessingMode = nr;
-        }
-    }
-    
+                       assert imageDims != null;
+                       origImageWidth = imageDims.x;
+                       origImageHeight = imageDims.y;
+                       visibleRect = viewport.getPanel().getVisibleRect();
 
-    private static boolean tilesAreNotNullAndCongruent( Envelope 
oldVisibleEnv, Envelope newVisibleEnv ){
+                       final int visibleX1 = visibleRect.x;
+                       final int visibleY1 = visibleRect.y;
+                       final int visibleX2 = visibleX1 + visibleRect.width;
+                       final int visibleY2 = visibleY1 + visibleRect.height;
 
-        if (oldVisibleEnv == null || newVisibleEnv == null) return true;
-        return (oldVisibleEnv.getMinX() == newVisibleEnv.getMinX() &&
-                oldVisibleEnv.getMaxX() == newVisibleEnv.getMaxX() &&
-                oldVisibleEnv.getMinY() == newVisibleEnv.getMinY() &&
-                oldVisibleEnv.getMaxY() == newVisibleEnv.getMaxY());
-        
-    }
-    
-    /**
-     * creates a BufferedImage out of an Image
-     * @param im the Image
-     * @return the BufferedImage
-     */
-    public static BufferedImage makeBufferedImage(Image im) {
-        BufferedImage copy = new BufferedImage(im.getWidth(null), 
im.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
-        Graphics2D g2d = copy.createGraphics();
-        g2d.drawImage(im,0,0,null);
-        g2d.dispose();
-        return copy;
-    }
-    
-    protected BufferedImage getScaledImageMatchingVisible( BufferedImage 
toBeScaled, double XscaleImg2Canvas, double YscaleImg2Canvas ){
+                       // Viewport envelope in model coordinates
+                       final Coordinate upperLeftVisible = 
viewport.toModelCoordinate(new Point(visibleX1, visibleY1));
+                       final Coordinate lowerRightVisible = 
viewport.toModelCoordinate(new Point(visibleX2, visibleY2));
+                       final Envelope newVisibleEnv = new 
Envelope(upperLeftVisible, lowerRightVisible);
 
-        if (toBeScaled==null) return null;
-        
-        int scaledWidth = (int)(toBeScaled.getWidth() * XscaleImg2Canvas);
-        int scaledHeight = (int)(toBeScaled.getHeight() * 
Math.abs(YscaleImg2Canvas) );
-        
-        if (scaledWidth<=0 || scaledHeight<=0) return null;
-        
-        return scaleImage(toBeScaled, (float)XscaleImg2Canvas, 
(float)Math.abs(YscaleImg2Canvas) );
+                       setImageSet(false);
 
-    }
-    
-    public BufferedImage getTileAsImage( Envelope wantedEnvelope ) throws 
Exception{
+                       if (visibleEnv == null || visibleEnv.getMinX() != 
newVisibleEnv.getMinX()
+                                       || visibleEnv.getMaxX() != 
newVisibleEnv.getMaxX()
+                                       || visibleEnv.getMinY() != 
newVisibleEnv.getMinY()
+                                       || visibleEnv.getMaxY() != 
newVisibleEnv.getMaxY() || symbologyChanged) {
+                               visibleEnv = newVisibleEnv;
 
-        double imgWidth = image.getWidth();
-        double imgHeight = image.getHeight();
-        Envelope imageEnv = getActualImageEnvelope();
-        Envelope visiblePartOfImage = wantedEnvelope.intersection(imageEnv);
-        if (visiblePartOfImage.isNull()) return null;
-        
-        double offset2VisibleX = imageEnv.getMinX() - wantedEnvelope.getMinX();
-        double offset2VisibleY = wantedEnvelope.getMaxY() - imageEnv.getMaxY();
-        
-        double scaleX = imgWidth / imageEnv.getWidth();
-        double scaleY = imgHeight / imageEnv.getHeight();
-        
-        // use local variables!
-        int xOffset, yOffset, width, height;
-        
-        if (offset2VisibleX >= 0){
-            xOffset = 0;
-        } else {
-            xOffset = (int)(-offset2VisibleX * scaleX);
-        }
-        
-        if (offset2VisibleY >= 0){
-            yOffset = 0;
-        } else {
-            yOffset = (int)(-offset2VisibleY * scaleY);
-        }
-        
-        width = (int)(visiblePartOfImage.getWidth() * scaleX);
-        height =  (int)(visiblePartOfImage.getHeight() * scaleY);
+                               symbologyChanged = false;
+                               this.setNeedToKeepImage(false);
+                               if (bitsPerPixel == -1) {
+                                       if 
(imageFileName.toLowerCase().endsWith(".flt")) {
+                                               bitsPerPixel = 16;
+                                       } else if 
(imageFileName.toLowerCase().endsWith(".asc")) {
+                                               bitsPerPixel = 16;
+                                       } else if 
(imageFileName.toLowerCase().endsWith(".txt")) {
+                                               bitsPerPixel = 16;
+                                       } else {
+                                               try {
+                                                       bitsPerPixel = 
Imaging.getImageInfo(new File(imageFileName)).getBitsPerPixel();
+                                               } catch (final 
ImageReadException e) {
+                                                       Logger.warn("Can't get 
ImageInfo of " + imageFileName, e);
+                                               }
+                                       }
+                               }
+                               clearImageAndRaster(true);
+                               // Check that there is enough free memory for 
the image + 1% of available memory
+                               // + 10Mb
+                               if (getAvailRAM() - getCommittedMemory() < 
origImageWidth * origImageHeight * bitsPerPixel / 8
+                                               + getAvailRAM() * 0.01 + 10 * 
1024 * 1024) {
+                                       layerViewPanel.getContext()
+                                                       .warnUser("Low Memory : 
image " + imageFileName + " will not be displayed");
+                                       System.out.println("" + (getAvailRAM() 
- getCommittedMemory()) / 1024 + "kb < "
+                                                       + (origImageWidth * 
origImageHeight * bitsPerPixel / 8) / 1024 + "kb "
+                                                       + getAvailRAM() * 0.01 
/ 1024 + "kb + 10240");
+                                       return null;
+                               } else {
+                                       System.out.println("Reload image");
+                               }
+                               // Load the part of the image intersecting the 
viewport and setting this.image
+                               reLoadImage();
+                               if (image == null) {
+                                       // If image does not intersect 
viewport, it is null
+                                       return null;
+                               }
 
-        if (width < imgWidth) width += 1;
-        if (height < imgHeight) height += 1;
-        
-        if (width <= 0 || height <= 0) return null;
-        
-        int wantedWidth = (int)(wantedEnvelope.getWidth() * scaleX);
-        int wantedHeight = (int)(wantedEnvelope.getHeight() * scaleY);
-        
-        if (image==null){
-            reLoadImage();
-        }
-        
-        BufferedImage imgTile = this.image.getSubimage(xOffset, yOffset, 
width, height);
-        
-        BufferedImage result = new BufferedImage( wantedWidth, wantedHeight, 
BufferedImage.TYPE_INT_ARGB);
-        
-        Graphics2D graf = result.createGraphics();
-        
-        Color backgroundColor = 
(this.transparentColor!=null)?this.transparentColor:Color.white;
-        
-        graf.fillRect(0,0,wantedWidth, wantedHeight);
-        
-        int xTileOffset,yTileOffset;
-        
-        if (xOffset > 0){
-            xTileOffset = 0;
-        } else {
-            xTileOffset = (int)(offset2VisibleX * scaleX);
-        }
-        
-        if (yOffset > 0){
-            yTileOffset = 0;
-        } else {
-            yTileOffset = (int)(offset2VisibleY * scaleY);
-        }
-        
-        graf.drawImage(imgTile, xTileOffset, yTileOffset, imgTile.getWidth(), 
imgTile.getHeight(), backgroundColor, null);
-        graf.dispose();
+                               // Coordinates of actual image in viewport 
coordinates
+                               final Point2D upperLeftCornerOfImage = 
viewport.toViewPoint(
+                                               new 
Coordinate(getActualImageEnvelope().getMinX(), 
getActualImageEnvelope().getMaxY()));
+                               final Point2D lowerRightCornerOfImage = 
viewport.toViewPoint(
+                                               new 
Coordinate(getActualImageEnvelope().getMaxX(), 
getActualImageEnvelope().getMinY()));
 
-        this.clearImageAndRaster(false);
-        return result;
-    }
-    
-    protected WorkbenchContext getWorkbenchContext(){
-        return 
(WorkbenchContext)this.getBlackboard().get(BLACKBOARD_KEY_WORKBENCHCONTEXT);
-    }
-    
-    public static void setWorkbenchContext(WorkbenchContext wContext){
-        if (blackboard==null)
-            blackboard = new Blackboard();
-        
-        blackboard.put(BLACKBOARD_KEY_WORKBENCHCONTEXT, wContext);
-    }
-    
-    public Rectangle getDrawingRectangle( double imgWidth, double imgHeight, 
Envelope imageEnv, Viewport viewport ) throws NoninvertibleTransformException{
-        
-        Rectangle visible = viewport.getPanel().getVisibleRect();
-        
-        Point2D upperLeftCorner;
-        Point2D lowerRightCorner;
-        
-        try {
-            upperLeftCorner = viewport.toViewPoint(new 
Coordinate(imageEnv.getMinX(), imageEnv.getMaxY()));
-            lowerRightCorner = viewport.toViewPoint(new 
Coordinate(imageEnv.getMaxX(), imageEnv.getMinY()));
-        } catch(java.awt.geom.NoninvertibleTransformException ne) {
-            ne.printStackTrace();
-            return null;
-        }
-        
-        int visibleX1 = visible.x;
-        int visibleY1 = visible.y;
-        int visibleX2 = visibleX1 + visible.width;
-        int visibleY2 = visibleY1 + visible.height;
-        
-        Coordinate upperLeftVisible = viewport.toModelCoordinate(new 
Point(visibleX1, visibleY1));
-        Coordinate lowerRightVisible = viewport.toModelCoordinate(new 
Point(visibleX2, visibleY2));
-        
-        Envelope newVisibleEnv = new Envelope(upperLeftVisible.x, 
lowerRightVisible.x, upperLeftVisible.y, lowerRightVisible.y);
-        
-        Rectangle rect = getVisibleImageCoordinatesOfImage(imgWidth, 
imgHeight, newVisibleEnv, imageEnv);
-        
-        if (rect==null) return null;
-        
-        double scaledWidth = lowerRightCorner.getX() - upperLeftCorner.getX();
-        double scaledHeight = upperLeftCorner.getY() - lowerRightCorner.getY();
-        
-        
-        double scaleXImg2Canvas = scaledWidth / imgWidth;
-        double scaleYImg2Canvas = scaledHeight / imgHeight;
-        
-        rect.width *= scaleXImg2Canvas;
-        rect.height *= scaleYImg2Canvas;
-        
-        return rect;
-    }
+                               final double scaledWidth = 
lowerRightCornerOfImage.getX() - upperLeftCornerOfImage.getX();
+                               final double scaledHeight = 
upperLeftCornerOfImage.getY() - lowerRightCornerOfImage.getY();
 
-    /**
-     * Returns the visible part of the image in image coordinate
-     * @param imgWidth original image width
-     * @param imgHeight original image height
-     * @param viewportEnv viewport in model coordinates
-     * @param imageEnv image envelope in model coordinates
-     * @return visible part of the image in image coordinates
-     */
-    protected Rectangle getVisibleImageCoordinatesOfImage(double imgWidth, 
double imgHeight,
-                                                          Envelope 
viewportEnv, Envelope imageEnv ){
+                               // Apply symbology to this.image
+                               imageToDraw = stretchImageValuesForDisplay();
+                               setImage(imageToDraw);
 
-        Envelope visiblePartOfImage = viewportEnv.intersection(imageEnv);
-        if (visiblePartOfImage.isNull()) return null;
+                               // if(getCommittedMemory() + minRamToKeepFree < 
availRAM){
+                               // setNeedToKeepImage(true); //so small images 
are not reloaded every time
+                               // }
 
-        // Offset from upperleft corner of viewport to upperleft corner of 
image in model coordinates
-        double offset2VisibleX = imageEnv.getMinX() - viewportEnv.getMinX();
-        double offset2VisibleY = viewportEnv.getMaxY() - imageEnv.getMaxY();
+                               // [sstein end]
+                               // Compute envelope of the visible part
+                               imagePart = 
getVisibleImageCoordinatesOfImage(image.getWidth(), image.getHeight(), 
visibleEnv,
+                                               getActualImageEnvelope());
 
-        // Scale to convert from model coordinates to image coordinates
-        double scaleX = imgWidth / imageEnv.getWidth();
-        double scaleY = imgHeight / imageEnv.getHeight();
-        
-        if (offset2VisibleX >= 0){
-            xOffset = 0;
-        } else {
-            xOffset = (int)(-offset2VisibleX * scaleX);
-        }
-        
-        if (offset2VisibleY >= 0){
-            yOffset = 0;
-        } else {
-            yOffset = (int)(-offset2VisibleY * scaleY);
-        }
-        
-        int width = (int)(visiblePartOfImage.getWidth() * scaleX);
-        int height =  (int)(visiblePartOfImage.getHeight() * scaleY);
+                               final double scaleXImg2Canvas = scaledWidth / 
image.getWidth();
+                               final double scaleYImg2Canvas = scaledHeight / 
image.getHeight();
 
-        if (width < imgWidth) width += 1;
-        if (height < imgHeight) height += 1;
+                               if (scaledBufferedImage == null || 
scaleXImg2Canvas != oldScaleXImg2Canvas
+                                               || 
!RasterImageLayer.tilesAreNotNullAndCongruent(visibleEnv, oldVisibleEnv)) {
 
-        return new Rectangle(xOffset, yOffset, width, height);
-    }
-    
-   
-    protected Rectangle getVisibleImageCoordinatesOfImage( BufferedImage img, 
Envelope visible, Envelope imageEnv ){
-        return this.getVisibleImageCoordinatesOfImage( img.getWidth(), 
img.getHeight(), visible, imageEnv );
-    }
-    
-    protected BufferedImage getVisiblePartOfTheImage( BufferedImage img, 
Rectangle desiredImageArea ){
-        if (desiredImageArea==null){
-            return null;
-        }
-        if ( desiredImageArea.width > 0 && desiredImageArea.height > 0 ){
-            if (desiredImageArea.width + desiredImageArea.x <= img.getWidth() 
&&
-                    desiredImageArea.height + desiredImageArea.y <= 
img.getHeight() ) {
-                
-                ParameterBlock pb = new ParameterBlock();
-                pb.addSource(img);
-                pb.add((float) desiredImageArea.x);
-                pb.add((float) desiredImageArea.y);
-                pb.add((float) desiredImageArea.width);
-                pb.add((float) desiredImageArea.height);
-                
-                return JAI.create("crop", pb).getAsBufferedImage();
-            }
-        }
-        return null;
-    }
+                                       scaledBufferedImage = 
getVisiblePartOfTheImage(getImageForDisplay(), imagePart);
 
-    public BufferedImage getImage() {
-        return image;
-    }
-    
-    
-    /**
-     * Sets the image that will be shown in the map (also sets some interally 
used flags)
-     *@param image image that will be shown in the map
-     */
-    public void setImage(BufferedImage image) {
-        this.image = image;
-        imageSet = true;
-    }
+                                       if (scaledBufferedImage != null) {
+                                               // avoid an 1 pixel by 1 pixel 
image to get scaled to thousands by thousands
+                                               // pixels causing an out of 
memory error
+                                               if (imagePart.width == 1 || 
imagePart.height == 1) {
+                                                       xOffset = 0;
+                                                       yOffset = 0;
+                                                       scaledBufferedImage = 
createOneColorImage(new Color(scaledBufferedImage.getRGB(0, 0)));
+                                               } else {
+                                                       scaledBufferedImage = 
getScaledImageMatchingVisible(scaledBufferedImage, scaleXImg2Canvas,
+                                                                       
scaleYImg2Canvas);
+                                               }
 
-    public void setImageSet(boolean imageSet) {
-        this.imageSet = imageSet;
-    }
+                                       } else {
+                                               return null;
+                                       }
 
-    public boolean isImageNull(){
-        return this.image == null;
-    }
-    
-    /**
-     * returns the image, this can be modified - i.e. is just a 
representation. 
-     * @return the image
-     */
-    public BufferedImage getImageForDisplay() throws Exception {
-        if (image == null)
-            reLoadImage();
-        return image;
-    }
-    
-    /**
-     * @return true, if the image object was set at least once, else false
-     */
-    public boolean isImageSet() {
-        return imageSet;
-    }
-    
-    /**
-     * Returns the transparency level of the image. The transparencyLevel 
controlls the transparency level of the whole image (all pixels). It
-     * is independent of the transparency color, that replaces a certain color 
in the image. 
-     * The transparencyLevel is expressed as a float within a range from 0.0 
(no transparency) to 1.0 (full transparency).
-     * @return the transparency level of the image
-     */
-    public double getTransparencyLevel() {
-        return transparencyLevel;
-    }
-    
-  
-    /**
-     * Sets the transparency level of the image. This controlls the 
transparency level of the whole image (all pixels). It
-     * is independent of the transparency color, that replaces a certain color 
in the image. 
-     * The transparencyLevel is expressed as a float within a range from 0.0 
(no transparency) to 1.0 (full transparency).
-     *@param transparencyLevel the transparency level of the image
-     */
-    public void setTransparencyLevel(double transparencyLevel) {
-        if (transparencyLevel != this.transparencyLevel){
-            this.transparencyLevel = transparencyLevel;
-            
-            if (this.isFiringAppearanceEvents()) 
-                this.fireAppearanceChanged();
-        }
-    }
-    /**
-     * Sets the transparency level of the image. This controlls the 
transparency level of the whole image (all pixels). It
-     * is independent of the transparency color, that replaces a certain color 
in the image. 
-     * The transparencyLevel is expressed as a percentage within a range from 
0 (no transparency) to 100 (full transparency).
-     *@param transparencyInPercent the transparency level of the image
-     */
-    public void setTransparencyLevelInPercent(int transparencyInPercent) {
-        double tLevel = transparencyInPercent/100.0;
-        if (tLevel != this.transparencyLevel){
-            this.transparencyLevel = tLevel;
-            if (this.isFiringAppearanceEvents()) 
-                this.fireAppearanceChanged();
-        }
-    }
-    
-    /**
-     * Gets the color which will be drawn with a zero opacity in the Jump map
-     *@return color that will be replaced with transparent pixels
-     */
-    public Color getTransparentColor() {
-        return transparentColor;
-    }
-    
-    /**
-     * for java2xml
-     */
-    public String getTransparentColorAsString() {
-       if (this.getTransparentColor()==null)
-               return "null";
-       
-        String hexColor = 
Integer.toHexString(this.getTransparentColor().getRGB());
-        if (hexColor.length()>6){
-               hexColor = hexColor.substring(2);
-        }
-        return hexColor;
-    }
-    
-    /**
-     * for java2xml
-     */
-    public void setTransparentColorAsString(String hexColorString) {
-       if (hexColorString==null || hexColorString.equals("null")){
-               return;
-       }
-       
-       int rgb = Integer.parseInt(hexColorString.toUpperCase(), 16);
-       
-       Color tColor = new Color(rgb);
+                                       if (transparentColor != null) {
+                                               
transparencyColorNeedsToBeApplied = true;
+                                       }
 
-       this.setTransparentColor(tColor);
-    }
-    
-    /**
-     * Sets the color which will be drawn with a zero opacity in the Jump map
-     *@param transparentColor the color for transparency
-     */
-    public void setTransparentColor(Color transparentColor) {
+                                       xOffset = (int) (xOffset * 
scaleXImg2Canvas);
+                                       yOffset = (int) (yOffset * 
(-scaleYImg2Canvas));
 
-        if (!Objects.equals(this.transparentColor, transparentColor)){
-         
-            this.transparentColor = transparentColor;
-            
-            this.forceTotalRepaint();
-            
-            if (this.isFiringAppearanceEvents()) 
-                this.fireAppearanceChanged();
-        }
-    }
-    
-    /**
-     * After this method was invoked, the image will be
-     * completely re-rendered (not using caches) the next time.
-     */
-    protected void forceTotalRepaint(){
-        this.visibleEnv = null;
-        this.setImageProcessingMode(RasterImageLayer.MODE_NONE);
-    }
+                                       oldScaleXImg2Canvas = scaleXImg2Canvas;
 
-    /**
-     *@return the current offset (to the viewport's <code>(0,0)</code>) in x 
direction 
-     */
-    public int getXOffset() {
-        return xOffset;
-    }
+                                       oldVisibleEnv = visibleEnv;
+                               }
 
-    /**
-     *@return the current offset (to the viewport's <code>(0,0)</code>) in y 
direction 
-     */
-    public int getYOffset() {
-        return yOffset;
-    }
-    
-    public static double getFreeRamFactor() {
-        return freeRamFactor;
-    }
+                       }
 
-    public static void setFreeRamFactor(double freeRamFactor) {
-        RasterImageLayer.freeRamFactor = freeRamFactor;
-        RasterImageLayer.minRamToKeepFree = RasterImageLayer.availRAM * 
RasterImageLayer.freeRamFactor;
-        RasterImageLayer.maxPixelsForFastDisplayMode = 
(int)((RasterImageLayer.availRAM - 
RasterImageLayer.minRamToKeepFree)/(1024*1024) * 3000);
-    }
+                       if (scaledBufferedImage != null && 
transparencyColorNeedsToBeApplied) {
+                               imageToDraw = 
setupTransparency(scaledBufferedImage);
+                       } else if (scaledBufferedImage != null) {
+                               imageToDraw = scaledBufferedImage;
+                       }
 
+               } catch (final Exception e) {
+                       Logger.warn(e);
+               }
+               if (imageToDraw != null) {
+                       return imageToDraw;
+               } else {
+                       return scaledBufferedImage;
+               }
+       }
 
-    public static long getAvailRAM() {
-        return availRAM;
-    }
+       protected long getCommittedMemory() {
+               return Runtime.getRuntime().totalMemory() - 
Runtime.getRuntime().freeMemory();
+       }
 
-    public static int getMaxPixelsForFastDisplayMode() {
-        return maxPixelsForFastDisplayMode;
-    }
+       /**
+        * Deletes image from RAM (if it is not to be kept and if the RAM 
consumption is
+        * high) and calls the garbage collector, if 
<code>garbageCollect</code> is
+        * true.
+        * 
+        * @param garbageCollect if true the garbage collector will be called 
(this
+        *                       parameter may be overridden, if there is not 
enough RAM
+        *                       available...)
+        */
+       public boolean clearImageAndRaster(boolean garbageCollect) {
+               final boolean reallyNeedToFreeRAM = (availRAM - 
getCommittedMemory() < minRamToKeepFree);
+               if (!needToKeepImage && reallyNeedToFreeRAM) {
+                       flushImages(garbageCollect);
+               } else if (garbageCollect) {
+                       Runtime.getRuntime().gc();
+               }
+               return reallyNeedToFreeRAM;
+       }
 
-    public static double getMinRamToKeepFree() {
-        return minRamToKeepFree;
-    }
+       /**
+        * flushes all images from the RAM.
+        * 
+        * @param garbageCollect if true the garbage collector will be called 
(this
+        *                       parameter may be overridden, if there is not 
enough RAM
+        *                       available...)
+        */
+       public void flushImages(boolean garbageCollect) {
+               if (image != null) {
+                       image.flush();
+               }
+               image = null;
+               if (scaledBufferedImage != null) {
+                       scaledBufferedImage.flush();
+               }
+               scaledBufferedImage = null;
+               if (garbageCollect) {
+                       Runtime.getRuntime().gc();
+               }
+       }
 
-    /**
-     * Sets the image's files name (if image is not to be kept) - this needs 
to be set!
-     * @param imageFileName the file name of the image
-     */
-    public void setImageFileName(String imageFileName) {
-        this.imageFileName = imageFileName;
-        this.setNeedToKeepImage(false);
-    }
-    
-    
-    /**
-     * 
-     * @return the file name of the image represented by this instance of the 
<code>RasterImageLayer</code>
-     */
-    public String getImageFileName() {
-        return imageFileName;
-    }
+       public void reLoadImage() throws Exception {
 
-    /**
-     * check, if image will be kept in RAM or if it will be reloaded from a 
file
-     * if needed
-     * @return true if image will be kept in RAM, else false
-     */
-    public boolean isNeedToKeepImage() {
-        return needToKeepImage;
-    }
-    /**
-     * toogle, if image will be kept in RAM or if it will be reloaded from a 
file
-     * if needed
-     * @param needToKeepImage true if image is supposed be kept in RAM, else 
false
-     */
-    public void setNeedToKeepImage(boolean needToKeepImage) {
-        this.needToKeepImage = needToKeepImage;
-    }
+               // if (image == null && !needToKeepImage){
 
-    @Override
+               final RasterImageIO rasterImageIO = new RasterImageIO();
+
+               final Viewport viewport = 
getWorkbenchContext().getLayerViewPanel().getViewport();
+               if 
(!viewport.getEnvelopeInModelCoordinates().intersects(originalImageEnvelope)
+                               && 
getWorkbenchContext().getLayerManager().getLayerables(Layerable.class).isEmpty())
 {
+                       viewport.zoom(originalImageEnvelope);
+               }
+
+               final Resolution requestedRes = 
RasterImageIO.calcRequestedResolution(viewport);
+               final long start = Timer.milliSecondsSince(0);
+               Logger.debug("Try reading " + getName());
+               // Get the part of the image intersecting the viewport
+               final ImageAndMetadata imageAndMetadata = 
rasterImageIO.loadImage(getWorkbenchContext(), imageFileName, stats,
+                               viewport.getEnvelopeInModelCoordinates(), 
requestedRes);
+               Logger.debug("Reading '" + getName() + "' took " + 
Timer.secondsSinceString(start) + "s.");
+               metadata = imageAndMetadata.getMetadata();
+               image = imageAndMetadata.getImage();
+               numBands = metadata.getStats().getBandCount();
+               noDataValue = imageAndMetadata.getMetadata().getNoDataValue();
+               stats = imageAndMetadata.getMetadata().getStats();
+               originalImageEnvelope = 
imageAndMetadata.getMetadata().getOriginalImageEnvelope();
+               actualImageEnvelope = 
imageAndMetadata.getMetadata().getActualEnvelope();
+               originalCellSize = 
imageAndMetadata.getMetadata().getOriginalCellSize();
+               actualCellSize = 
imageAndMetadata.getMetadata().getActualCellSize();
+
+               if (image != null) {
+                       setImage(image);
+               }
+       }
+
+       /**
+        * use this to assign the raster data again the method is called from
+        * getRasterData();
+        */
+       public void reLoadImageButKeepImageForDisplay() throws Exception {
+               final BufferedImage pi = getImageForDisplay();
+               // [sstein 24.Sept.2010] commented out:
+               // PlanarImage dontNeedThisImage = RasterImageLayer.loadImage( 
context,
+               // imageFileName); //causes error for .clone()
+               this.setImage(pi);
+       }
+
+       protected BufferedImage stretchImageValuesForDisplay() throws 
NoninvertibleTransformException {
+
+               final Raster actualRasterData = image.copyData(null);
+               final int width = actualRasterData.getWidth();
+               final int height = actualRasterData.getHeight();
+
+               // Need to change image type to support transparency and apply 
symbology
+               if (image.getColorModel() instanceof IndexColorModel) {
+                       return image;
+               }
+
+               final BufferedImage newImage = new BufferedImage(width, height, 
BufferedImage.TYPE_4BYTE_ABGR);
+               for (int row = 0; row < height; row++) {
+                       for (int col = 0; col < width; col++) {
+
+                               if (symbology == null) {
+                                       if (stats.getBandCount() < 3) {
+
+                                               final RasterSymbology 
rasterSymbology;
+                                               // If there is onòy one value 
in the raster, the color will set to Black
+                                               // to avoid confusion between 
raster color and color of the view
+                                               if 
(metadata.getStats().getMin(0) == metadata.getStats().getMax(0)) {
+                                                       rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_SINGLE);
+                                                       
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.BLACK);
+                                                       
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.BLACK);
+
+                                               } else {
+                                                       // Standard 
representation of B/W raster
+                                                       rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_RAMP);
+                                                       
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.BLACK);
+                                                       
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.WHITE);
+                                               }
+                                               if 
(!Double.isNaN(metadata.getNoDataValue())) {
+                                                       
rasterSymbology.addColorMapEntry(metadata.getNoDataValue(), transparentColor);
+                                               }
+
+                                               /*
+                                                * if 
(metadata.getStats().getMin(0) == metadata .getStats().getMax(0)) {
+                                                * rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_SINGLE); } else {
+                                                * rasterSymbology = new 
RasterSymbology(RasterSymbology.TYPE_RAMP); } if
+                                                * 
(!Double.isNaN(metadata.getNoDataValue())) {
+                                                * 
rasterSymbology.addColorMapEntry(metadata.getNoDataValue(),
+                                                * transparentColor); }
+                                                * 
rasterSymbology.addColorMapEntry(metadata.getStats().getMin(0), Color.WHITE);
+                                                * 
rasterSymbology.addColorMapEntry(metadata.getStats().getMax(0), Color.BLACK);
+                                                */
+
+                                               setSymbology(rasterSymbology);
+
+                                       } else {
+                                               final double valueR = 
actualRasterData.getSampleDouble(col, row, 0);
+                                               final double valueG = 
actualRasterData.getSampleDouble(col, row, 1);
+                                               final double valueB = 
actualRasterData.getSampleDouble(col, row, 2);
+                                               double valueAlpha = 255;
+                                               if (stats.getBandCount() > 3) {
+                                                       valueAlpha = 
actualRasterData.getSampleDouble(col, row, 3);
+                                               }
+                                               if (Double.isNaN(valueR) || 
Double.isInfinite(valueR) || valueR == noDataValue
+                                                               || 
Double.isNaN(valueG) || Double.isInfinite(valueG) || valueG == noDataValue
+                                                               || 
Double.isNaN(valueB) || Double.isInfinite(valueB) || valueB == noDataValue
+                                                               || valueAlpha 
<= 0) {
+                                                       newImage.setRGB(col, 
row, Color.TRANSLUCENT);
+                                                       continue;
+                                               }
+
+                                               int r = (int) ((valueR - 
stats.getMin(0)) * 255. / (stats.getMax(0) - stats.getMin(0)));
+                                               if (r > 255) {
+                                                       r = 255;
+                                               }
+                                               if (r < 0) {
+                                                       r = 0;
+                                               }
+                                               int g = (int) ((valueG - 
stats.getMin(1)) * 255. / (stats.getMax(1) - stats.getMin(0)));
+                                               if (g > 255) {
+                                                       g = 255;
+                                               }
+                                               if (g < 0) {
+                                                       g = 0;
+                                               }
+                                               int b = (int) ((valueB - 
stats.getMin(2)) * 255. / (stats.getMax(2) - stats.getMin(0)));
+                                               if (b > 255) {
+                                                       b = 255;
+                                               }
+                                               if (b < 0) {
+                                                       b = 0;
+                                               }
+
+                                               final int alpha = (int) 
valueAlpha;
+
+                                               newImage.setRGB(col, row, new 
Color(r, g, b, alpha).getRGB());
+                                       }
+                               } else {
+                                       // Symbology exists
+                                       double value = 
actualRasterData.getSampleDouble(col, row, 0);
+
+                                       // If symbology min value is higher 
than raster min value
+                                       // the value becomes equal to the 
symbology min value
+                                       final Double[] symbologyClassLimits = 
symbology.getColorMapEntries_tm().keySet()
+                                                       .toArray(new Double[0]);
+                                       double symbMinValue = 
symbologyClassLimits[0];
+                                       final double symbFirstValue = 
symbologyClassLimits[0];
+                                       if (this.isNoData(symbFirstValue)) {
+                                               symbMinValue = 
symbologyClassLimits[1];
+                                       }
+
+                                       if (!this.isNoData(value) && value < 
symbMinValue) {
+                                               value = symbMinValue;
+                                       }
+
+                                       final Color color = 
symbology.getColor(value);
+
+                                       if ((Double.isNaN(value) || 
Double.isInfinite(value) || this.isNoData(value)) && color == null) {
+                                               newImage.setRGB(col, row, 
Color.TRANSLUCENT);
+                                               continue;
+                                       }
+
+                                       // Transparency is a combination of 
total layer transparency
+                                       // and single cell transparency
+                                       final int transparency = (int) (((1 - 
symbology.getTransparency()) * (color.getAlpha() / 255d))
+                                                       * 255);
+                                       newImage.setRGB(col, row,
+                                                       new 
Color(color.getRed(), color.getGreen(), color.getBlue(), 
transparency).getRGB());
+                               }
+                       }
+               }
+               return newImage;
+       }
+
+       /**
+        * @return Envelope with the real world coordinates of the image
+        */
+       public Envelope getWholeImageEnvelope() {
+               return originalImageEnvelope;
+       }
+
+       public Envelope getActualImageEnvelope() {
+               return actualImageEnvelope;
+       }
+
+       /**
+        * Sets the Envelope containing the real world coordinates (e.g. WGS84) 
of the
+        * image this needs to be set (if it wasn't given to the constructor)!
+        * 
+        * @param envelope the Envelope
+        */
+       private void setWholeImageEnvelope(Envelope envelope) {
+               originalImageEnvelope = envelope;
+
+               forceTotalRepaint();
+
+               if (this.isFiringAppearanceEvents()) {
+                       this.fireAppearanceChanged();
+               }
+       }
+
+       private void setActualImageEnvelope(Envelope envelope) {
+               actualImageEnvelope = envelope;
+
+               forceTotalRepaint();
+
+               if (isFiringAppearanceEvents()) {
+                       fireAppearanceChanged();
+               }
+       }
+
+       /**
+        * for java2xml
+        * 
+        * @return the Envelope as string
+        */
+       public String getXmlWholeImageEnvelope() {
+               return this.originalImageEnvelope.toString();
+       }
+
+       public String getXmlActualImageEnvelope() {
+               return this.actualImageEnvelope.toString();
+       }
+
+       /**
+        * for java2xml
+        * 
+        * @param envStr the Envelope as string
+        */
+       public void setXmlWholeImageEnvelope(String envStr) {
+               final String coords = envStr.substring(envStr.indexOf("[") + 1, 
envStr.indexOf("]"));
+
+               final String[] coordArray = coords.split(",");
+
+               final String[] xCoords = coordArray[0].split(":");
+               final String[] yCoords = coordArray[1].split(":");
+
+               final double minX = java.lang.Double.parseDouble(xCoords[0]);
+               final double maxX = java.lang.Double.parseDouble(xCoords[1]);
+
+               final double minY = java.lang.Double.parseDouble(yCoords[0]);
+               final double maxY = java.lang.Double.parseDouble(yCoords[1]);
+
+               this.setWholeImageEnvelope(new Envelope(minX, maxX, minY, 
maxY));
+       }
+
+       public void setXmlActualImageEnvelope(String envStr) {
+               final String coords = envStr.substring(envStr.indexOf("[") + 1, 
envStr.indexOf("]"));
+
+               final String[] coordArray = coords.split(",");
+
+               final String[] xCoords = coordArray[0].split(":");
+               final String[] yCoords = coordArray[1].split(":");
+
+               final double minX = java.lang.Double.parseDouble(xCoords[0]);
+               final double maxX = java.lang.Double.parseDouble(xCoords[1]);
+
+               final double minY = java.lang.Double.parseDouble(yCoords[0]);
+               final double maxY = java.lang.Double.parseDouble(yCoords[1]);
+
+               this.setActualImageEnvelope(new Envelope(minX, maxX, minY, 
maxY));
+       }
+
+       /**
+        * Method to change the coordinates of the image and later apply the 
changes to
+        * the RasterImageLayer by using
+        * {@link RasterImageLayer#setGeometryAsWholeImageEnvelope(Geometry)}.
+        * 
+        * @return return the imageEnvelope (= bounding box) as a geometry,
+        */
+       public Geometry getWholeImageEnvelopeAsGeometry() {
+               return new GeometryFactory().toGeometry(originalImageEnvelope);
+       }
+
+       public Geometry getActualImageEnvelopeAsGeometry() {
+               return new GeometryFactory().toGeometry(actualImageEnvelope);
+       }
+
+       /**
+        * Method to set the coordinates of the image, e.g. after changing them 
after
+        * using {@link RasterImageLayer#getWholeImageEnvelopeAsGeometry()}.
+        */
+       public void setGeometryAsWholeImageEnvelope(Geometry geometry) {
+               setWholeImageEnvelope(geometry.getEnvelopeInternal());
+       }
+
+       public void setGeometryAsActualImageEnvelope(Geometry geometry) {
+               setActualImageEnvelope(geometry.getEnvelopeInternal());
+       }
+
+       /**
+        * Add transparency to the image (more exactly: to each pixel which a 
color ==
+        * this.transparentColor)
+        * 
+        * @param bim the image
+        */
+       private BufferedImage setupTransparency(BufferedImage bim) {
+               // BufferedImage bim = pImage.getAsBufferedImage();
+
+               final ColorModel cm = bim.getColorModel();
+               final int fullTransparencyAlpha = 255;
+
+               if (this.getTransparentColor() == null) {
+                       return null;
+               }
+
+               final int transparentColor = 
this.getTransparentColor().getRGB();
+
+               final int[] argb = new int[4];
+
+               if (!cm.hasAlpha()) {
+                       bim = RasterImageLayer.makeBufferedImage(bim);
+                       // cm = bim.getColorModel();
+
+               }
+
+               for (int w = 0; w < bim.getWidth(); w++) {
+                       for (int h = 0; h < bim.getHeight(); h++) {
+
+                               if (bim.getRGB(w, h) == transparentColor) {
+                                       final Color color = new 
Color(bim.getRGB(w, h));
+
+                                       argb[0] = fullTransparencyAlpha;
+                                       argb[1] = color.getRed();
+                                       argb[2] = color.getGreen();
+                                       argb[3] = color.getBlue();
+
+                                       bim.setRGB(w, h, 1, 1, argb, 0, 1);
+                               }
+                       }
+               }
+
+               return bim;
+       }
+
+       private void setImageProcessingMode(int nr) {
+               if (lastImgProcessingMode != nr) {
+
+                       imagePart = null;
+
+                       oldScaleXImg2Canvas = -1;
+
+                       if (Runtime.getRuntime().freeMemory() < 
RasterImageLayer.getMinRamToKeepFree()) {
+                               Runtime.getRuntime().gc();
+                       }
+
+                       lastImgProcessingMode = nr;
+               }
+       }
+
+       private static boolean tilesAreNotNullAndCongruent(Envelope 
oldVisibleEnv, Envelope newVisibleEnv) {
+
+               if (oldVisibleEnv == null || newVisibleEnv == null) {
+                       return true;
+               }
+               return (oldVisibleEnv.getMinX() == newVisibleEnv.getMinX() && 
oldVisibleEnv.getMaxX() == newVisibleEnv.getMaxX()
+                               && oldVisibleEnv.getMinY() == 
newVisibleEnv.getMinY()
+                               && oldVisibleEnv.getMaxY() == 
newVisibleEnv.getMaxY());
+
+       }
+
+       /**
+        * creates a BufferedImage out of an Image
+        * 
+        * @param im the Image
+        * @return the BufferedImage
+        */
+       public static BufferedImage makeBufferedImage(Image im) {
+               final BufferedImage copy = new BufferedImage(im.getWidth(null), 
im.getHeight(null),
+                               BufferedImage.TYPE_INT_ARGB);
+               final Graphics2D g2d = copy.createGraphics();
+               g2d.drawImage(im, 0, 0, null);
+               g2d.dispose();
+               return copy;
+       }
+
+       protected BufferedImage getScaledImageMatchingVisible(BufferedImage 
toBeScaled, double XscaleImg2Canvas,
+                       double YscaleImg2Canvas) {
+
+               if (toBeScaled == null) {
+                       return null;
+               }
+
+               final int scaledWidth = (int) (toBeScaled.getWidth() * 
XscaleImg2Canvas);
+               final int scaledHeight = (int) (toBeScaled.getHeight() * 
Math.abs(YscaleImg2Canvas));
+
+               if (scaledWidth <= 0 || scaledHeight <= 0) {
+                       return null;
+               }
+
+               return scaleImage(toBeScaled, (float) XscaleImg2Canvas, (float) 
Math.abs(YscaleImg2Canvas));
+
+       }
+
+       public BufferedImage getTileAsImage(Envelope wantedEnvelope) throws 
Exception {
+
+               final double imgWidth = image.getWidth();
+               final double imgHeight = image.getHeight();
+               final Envelope imageEnv = getActualImageEnvelope();
+               final Envelope visiblePartOfImage = 
wantedEnvelope.intersection(imageEnv);
+               if (visiblePartOfImage.isNull()) {
+                       return null;
+               }
+
+               final double offset2VisibleX = imageEnv.getMinX() - 
wantedEnvelope.getMinX();
+               final double offset2VisibleY = wantedEnvelope.getMaxY() - 
imageEnv.getMaxY();
+
+               final double scaleX = imgWidth / imageEnv.getWidth();
+               final double scaleY = imgHeight / imageEnv.getHeight();
+
+               // use local variables!
+               int xOffset, yOffset, width, height;
+
+               if (offset2VisibleX >= 0) {
+                       xOffset = 0;
+               } else {
+                       xOffset = (int) (-offset2VisibleX * scaleX);
+               }
+
+               if (offset2VisibleY >= 0) {
+                       yOffset = 0;
+               } else {
+                       yOffset = (int) (-offset2VisibleY * scaleY);
+               }
+
+               width = (int) (visiblePartOfImage.getWidth() * scaleX);
+               height = (int) (visiblePartOfImage.getHeight() * scaleY);
+
+               if (width < imgWidth) {
+                       width += 1;
+               }
+               if (height < imgHeight) {
+                       height += 1;
+               }
+
+               if (width <= 0 || height <= 0) {
+                       return null;
+               }
+
+               final int wantedWidth = (int) (wantedEnvelope.getWidth() * 
scaleX);
+               final int wantedHeight = (int) (wantedEnvelope.getHeight() * 
scaleY);
+
+               if (image == null) {
+                       reLoadImage();
+               }
+
+               final BufferedImage imgTile = this.image.getSubimage(xOffset, 
yOffset, width, height);
+
+               final BufferedImage result = new BufferedImage(wantedWidth, 
wantedHeight, BufferedImage.TYPE_INT_ARGB);
+
+               final Graphics2D graf = result.createGraphics();
+
+               final Color backgroundColor = (this.transparentColor != null) ? 
this.transparentColor : Color.white;
+
+               graf.fillRect(0, 0, wantedWidth, wantedHeight);
+
+               int xTileOffset, yTileOffset;
+
+               if (xOffset > 0) {
+                       xTileOffset = 0;
+               } else {
+                       xTileOffset = (int) (offset2VisibleX * scaleX);
+               }
+
+               if (yOffset > 0) {
+                       yTileOffset = 0;
+               } else {
+                       yTileOffset = (int) (offset2VisibleY * scaleY);
+               }
+
+               graf.drawImage(imgTile, xTileOffset, yTileOffset, 
imgTile.getWidth(), imgTile.getHeight(), backgroundColor,
+                               null);
+               graf.dispose();
+
+               this.clearImageAndRaster(false);
+               return result;
+       }
+
+       protected WorkbenchContext getWorkbenchContext() {
+               return (WorkbenchContext) 
this.getBlackboard().get(BLACKBOARD_KEY_WORKBENCHCONTEXT);
+       }
+
+       public static void setWorkbenchContext(WorkbenchContext wContext) {
+               if (blackboard == null) {
+                       blackboard = new Blackboard();
+               }
+
+               blackboard.put(BLACKBOARD_KEY_WORKBENCHCONTEXT, wContext);
+       }
+
+       public Rectangle getDrawingRectangle(double imgWidth, double imgHeight, 
Envelope imageEnv, Viewport viewport)
+                       throws NoninvertibleTransformException {
+
+               final Rectangle visible = viewport.getPanel().getVisibleRect();
+
+               Point2D upperLeftCorner;
+               Point2D lowerRightCorner;
+
+               try {
+                       upperLeftCorner = viewport.toViewPoint(new 
Coordinate(imageEnv.getMinX(), imageEnv.getMaxY()));
+                       lowerRightCorner = viewport.toViewPoint(new 
Coordinate(imageEnv.getMaxX(), imageEnv.getMinY()));
+               } catch (final java.awt.geom.NoninvertibleTransformException 
ne) {
+                       ne.printStackTrace();
+                       return null;
+               }
+
+               final int visibleX1 = visible.x;
+               final int visibleY1 = visible.y;
+               final int visibleX2 = visibleX1 + visible.width;
+               final int visibleY2 = visibleY1 + visible.height;
+
+               final Coordinate upperLeftVisible = 
viewport.toModelCoordinate(new Point(visibleX1, visibleY1));
+               final Coordinate lowerRightVisible = 
viewport.toModelCoordinate(new Point(visibleX2, visibleY2));
+
+               final Envelope newVisibleEnv = new Envelope(upperLeftVisible.x, 
lowerRightVisible.x, upperLeftVisible.y,
+                               lowerRightVisible.y);
+
+               final Rectangle rect = 
getVisibleImageCoordinatesOfImage(imgWidth, imgHeight, newVisibleEnv, imageEnv);
+
+               if (rect == null) {
+                       return null;
+               }
+
+               final double scaledWidth = lowerRightCorner.getX() - 
upperLeftCorner.getX();
+               final double scaledHeight = upperLeftCorner.getY() - 
lowerRightCorner.getY();
+
+               final double scaleXImg2Canvas = scaledWidth / imgWidth;
+               final double scaleYImg2Canvas = scaledHeight / imgHeight;
+
+               rect.width *= scaleXImg2Canvas;
+               rect.height *= scaleYImg2Canvas;
+
+               return rect;
+       }
+
+       /**
+        * Returns the visible part of the image in image coordinate
+        * 
+        * @param imgWidth    original image width
+        * @param imgHeight   original image height
+        * @param viewportEnv viewport in model coordinates
+        * @param imageEnv    image envelope in model coordinates
+        * @return visible part of the image in image coordinates
+        */
+       protected Rectangle getVisibleImageCoordinatesOfImage(double imgWidth, 
double imgHeight, Envelope viewportEnv,
+                       Envelope imageEnv) {
+
+               final Envelope visiblePartOfImage = 
viewportEnv.intersection(imageEnv);
+               if (visiblePartOfImage.isNull()) {
+                       return null;
+               }
+
+               // Offset from upperleft corner of viewport to upperleft corner 
of image in
+               // model coordinates
+               final double offset2VisibleX = imageEnv.getMinX() - 
viewportEnv.getMinX();
+               final double offset2VisibleY = viewportEnv.getMaxY() - 
imageEnv.getMaxY();
+
+               // Scale to convert from model coordinates to image coordinates
+               final double scaleX = imgWidth / imageEnv.getWidth();
+               final double scaleY = imgHeight / imageEnv.getHeight();
+
+               if (offset2VisibleX >= 0) {
+                       xOffset = 0;
+               } else {
+                       xOffset = (int) (-offset2VisibleX * scaleX);
+               }
+
+               if (offset2VisibleY >= 0) {
+                       yOffset = 0;
+               } else {
+                       yOffset = (int) (-offset2VisibleY * scaleY);
+               }
+
+               int width = (int) (visiblePartOfImage.getWidth() * scaleX);
+               int height = (int) (visiblePartOfImage.getHeight() * scaleY);
+
+               if (width < imgWidth) {
+                       width += 1;
+               }
+               if (height < imgHeight) {
+                       height += 1;
+               }
+
+               return new Rectangle(xOffset, yOffset, width, height);
+       }
+
+       protected Rectangle getVisibleImageCoordinatesOfImage(BufferedImage 
img, Envelope visible, Envelope imageEnv) {
+               return this.getVisibleImageCoordinatesOfImage(img.getWidth(), 
img.getHeight(), visible, imageEnv);
+       }
+
+       protected BufferedImage getVisiblePartOfTheImage(BufferedImage img, 
Rectangle desiredImageArea) {
+               if (desiredImageArea == null) {
+                       return null;
+               }
+               if (desiredImageArea.width > 0 && desiredImageArea.height > 0) {
+                       if (desiredImageArea.width + desiredImageArea.x <= 
img.getWidth()
+                                       && desiredImageArea.height + 
desiredImageArea.y <= img.getHeight()) {
+
+                               final ParameterBlock pb = new ParameterBlock();
+                               pb.addSource(img);
+                               pb.add((float) desiredImageArea.x);
+                               pb.add((float) desiredImageArea.y);
+                               pb.add((float) desiredImageArea.width);
+                               pb.add((float) desiredImageArea.height);
+
+                               return JAI.create("crop", 
pb).getAsBufferedImage();
+                       }
+               }
+               return null;
+       }
+
+       public BufferedImage getImage() {
+               return image;
+       }
+
+       /**
+        * Sets the image that will be shown in the map (also sets some 
interally used
+        * flags)
+        * 
+        * @param image image that will be shown in the map
+        */
+       public void setImage(BufferedImage image) {
+               this.image = image;
+               imageSet = true;
+       }
+
+       public void setImageSet(boolean imageSet) {
+               this.imageSet = imageSet;
+       }
+
+       public boolean isImageNull() {
+               return this.image == null;
+       }
+
+       /**
+        * returns the image, this can be modified - i.e. is just a 
representation.
+        * 
+        * @return the image
+        */
+       public BufferedImage getImageForDisplay() throws Exception {
+               if (image == null) {
+                       reLoadImage();
+               }
+               return image;
+       }
+
+       /**
+        * @return true, if the image object was set at least once, else false
+        */
+       public boolean isImageSet() {
+               return imageSet;
+       }
+
+       /**
+        * Returns the transparency level of the image. The transparencyLevel 
controlls
+        * the transparency level of the whole image (all pixels). It is 
independent of
+        * the transparency color, that replaces a certain color in the image. 
The
+        * transparencyLevel is expressed as a float within a range from 0.0 (no
+        * transparency) to 1.0 (full transparency).
+        * 
+        * @return the transparency level of the image
+        */
+       public double getTransparencyLevel() {
+               return transparencyLevel;
+       }
+
+       /**
+        * Sets the transparency level of the image. This controlls the 
transparency
+        * level of the whole image (all pixels). It is independent of the 
transparency
+        * color, that replaces a certain color in the image. The 
transparencyLevel is
+        * expressed as a float within a range from 0.0 (no transparency) to 
1.0 (full
+        * transparency).
+        * 
+        * @param transparencyLevel the transparency level of the image
+        */
+       public void setTransparencyLevel(double transparencyLevel) {
+               if (transparencyLevel != this.transparencyLevel) {
+                       this.transparencyLevel = transparencyLevel;
+
+                       if (this.isFiringAppearanceEvents()) {
+                               this.fireAppearanceChanged();
+                       }
+               }
+       }
+
+       /**
+        * Sets the transparency level of the image. This controlls the 
transparency
+        * level of the whole image (all pixels). It is independent of the 
transparency
+        * color, that replaces a certain color in the image. The 
transparencyLevel is
+        * expressed as a percentage within a range from 0 (no transparency) to 
100
+        * (full transparency).
+        * 
+        * @param transparencyInPercent the transparency level of the image
+        */
+       public void setTransparencyLevelInPercent(int transparencyInPercent) {
+               final double tLevel = transparencyInPercent / 100.0;
+               if (tLevel != this.transparencyLevel) {
+                       this.transparencyLevel = tLevel;
+                       if (this.isFiringAppearanceEvents()) {
+                               this.fireAppearanceChanged();
+                       }
+               }
+       }
+
+       /**
+        * Gets the color which will be drawn with a zero opacity in the Jump 
map
+        * 
+        * @return color that will be replaced with transparent pixels
+        */
+       public Color getTransparentColor() {
+               return transparentColor;
+       }
+
+       /**
+        * for java2xml
+        */
+       public String getTransparentColorAsString() {
+               if (this.getTransparentColor() == null) {
+                       return "null";
+               }
+
+               String hexColor = 
Integer.toHexString(this.getTransparentColor().getRGB());
+               if (hexColor.length() > 6) {
+                       hexColor = hexColor.substring(2);
+               }
+               return hexColor;
+       }
+
+       /**
+        * for java2xml
+        */
+       public void setTransparentColorAsString(String hexColorString) {
+               if (hexColorString == null || hexColorString.equals("null")) {
+                       return;
+               }
+
+               final int rgb = Integer.parseInt(hexColorString.toUpperCase(), 
16);
+
+               final Color tColor = new Color(rgb);
+
+               this.setTransparentColor(tColor);
+       }
+
+       /**
+        * Sets the color which will be drawn with a zero opacity in the Jump 
map
+        * 
+        * @param transparentColor the color for transparency
+        */
+       public void setTransparentColor(Color transparentColor) {
+
+               if (!Objects.equals(this.transparentColor, transparentColor)) {
+
+                       this.transparentColor = transparentColor;
+
+                       this.forceTotalRepaint();
+
+                       if (this.isFiringAppearanceEvents()) {
+                               this.fireAppearanceChanged();
+                       }
+               }
+       }
+
+       /**
+        * After this method was invoked, the image will be completely 
re-rendered (not
+        * using caches) the next time.
+        */
+       protected void forceTotalRepaint() {
+               this.visibleEnv = null;
+               this.setImageProcessingMode(RasterImageLayer.MODE_NONE);
+       }
+
+       /**
+        * @return the current offset (to the viewport's <code>(0,0)</code>) in 
x
+        *         direction
+        */
+       public int getXOffset() {
+               return xOffset;
+       }
+
+       /**
+        * @return the current offset (to the viewport's <code>(0,0)</code>) in 
y
+        *         direction
+        */
+       public int getYOffset() {
+               return yOffset;
+       }
+
+       public static double getFreeRamFactor() {
+               return freeRamFactor;
+       }
+
+       public static void setFreeRamFactor(double freeRamFactor) {
+               RasterImageLayer.freeRamFactor = freeRamFactor;
+               RasterImageLayer.minRamToKeepFree = RasterImageLayer.availRAM * 
RasterImageLayer.freeRamFactor;
+               RasterImageLayer.maxPixelsForFastDisplayMode = (int) 
((RasterImageLayer.availRAM
+                               - RasterImageLayer.minRamToKeepFree) / (1024 * 
1024) * 3000);
+       }
+
+       public static long getAvailRAM() {
+               return availRAM;
+       }
+
+       public static int getMaxPixelsForFastDisplayMode() {
+               return maxPixelsForFastDisplayMode;
+       }
+
+       public static double getMinRamToKeepFree() {
+               return minRamToKeepFree;
+       }
+
+       /**
+        * Sets the image's files name (if image is not to be kept) - this 
needs to be
+        * set!
+        * 
+        * @param imageFileName the file name of the image
+        */
+       public void setImageFileName(String imageFileName) {
+               this.imageFileName = imageFileName;
+               this.setNeedToKeepImage(false);
+       }
+
+       /**
+        * 
+        * @return the file name of the image represented by this instance of 
the
+        *         <code>RasterImageLayer</code>
+        */
+       public String getImageFileName() {
+               return imageFileName;
+       }
+
+       /**
+        * check, if image will be kept in RAM or if it will be reloaded from a 
file if
+        * needed
+        * 
+        * @return true if image will be kept in RAM, else false
+        */
+       public boolean isNeedToKeepImage() {
+               return needToKeepImage;
+       }
+
+       /**
+        * toogle, if image will be kept in RAM or if it will be reloaded from 
a file if
+        * needed
+        * 
+        * @param needToKeepImage true if image is supposed be kept in RAM, 
else false
+        */
+       public void setNeedToKeepImage(boolean needToKeepImage) {
+               this.needToKeepImage = needToKeepImage;
+       }
+
+       @Override
        protected void finalize() throws Throwable {
-        super.finalize();
-        this.flushImages(true);
-    }
+               super.finalize();
+               this.flushImages(true);
+       }
 
-    /**
-     *@return the height of the source image
-     */
-    public int getOrigImageHeight() {
-        return origImageHeight;
-    }
+       /**
+        * @return the height of the source image
+        */
+       public int getOrigImageHeight() {
+               return origImageHeight;
+       }
 
-    /**
-     *@return the width of the source image
-     */
-    public int getOrigImageWidth() {
-        return origImageWidth;
-    }
+       /**
+        * @return the width of the source image
+        */
+       public int getOrigImageWidth() {
+               return origImageWidth;
+       }
 
-    
-    /**
-     * for java2xml
-     * @param origImageHeight height of original image
-     */
-    public void setOrigImageHeight(int origImageHeight) {
-        this.origImageHeight = origImageHeight;
-    }
+       /**
+        * for java2xml
+        * 
+        * @param origImageHeight height of original image
+        */
+       public void setOrigImageHeight(int origImageHeight) {
+               this.origImageHeight = origImageHeight;
+       }
 
-    /**
-     * for java2xml
-     * @param origImageWidth width of original image
-     */
-    public void setOrigImageWidth(int origImageWidth) {
-        this.origImageWidth = origImageWidth;
-    }
+       /**
+        * for java2xml
+        * 
+        * @param origImageWidth width of original image
+        */
+       public void setOrigImageWidth(int origImageWidth) {
+               this.origImageWidth = origImageWidth;
+       }
 
-    /**
-     * shows or hides the image in the Jump map
-     * @param visible set true if image must be visible
-     */
-    @Override
+       /**
+        * shows or hides the image in the Jump map
+        * 
+        * @param visible set true if image must be visible
+        */
+       @Override
        public void setVisible(boolean visible) {
-        super.setVisible(visible);
-        
-        if (!visible)
-            this.clearImageAndRaster(true);
-        
-        if (this.isFiringAppearanceEvents())
-            this.fireAppearanceChanged();
-    }
-    
+               super.setVisible(visible);
 
-    /**
-     * @see #firingAppearanceEvents
-     * @return true if appearance events are fired automatically, false if not
-     */
-    public boolean isFiringAppearanceEvents() {
-        return firingAppearanceEvents;
-    }
+               if (!visible) {
+                       this.clearImageAndRaster(true);
+               }
 
-    /**
-     * @see #firingAppearanceEvents
-     * @param firingAppearanceEvents true if appearance events are to be fired 
automatically, false if not
-     */
-    public void setFiringAppearanceEvents(boolean firingAppearanceEvents) {
-        this.firingAppearanceEvents = firingAppearanceEvents;
-    }    
-    
-    // Metainformation stuff
-    
-    protected MetaDataMap metaInformation = null;
-    
-    @Override
-    public MetaDataMap getMetaInformation() {
-        return metaInformation;
-    }
+               if (this.isFiringAppearanceEvents()) {
+                       this.fireAppearanceChanged();
+               }
+       }
 
-    @Override
-    public void setMetaInformation(MetaDataMap metaInformation) {
-        this.metaInformation = metaInformation;
-    }
+       /**
+        * @see #firingAppearanceEvents
+        * @return true if appearance events are fired automatically, false if 
not
+        */
+       public boolean isFiringAppearanceEvents() {
+               return firingAppearanceEvents;
+       }
 
-    public Raster getRasterData(Rectangle subset) throws IOException {
+       /**
+        * @see #firingAppearanceEvents
+        * @param firingAppearanceEvents true if appearance events are to be 
fired
+        *                               automatically, false if not
+        */
+       public void setFiringAppearanceEvents(boolean firingAppearanceEvents) {
+               this.firingAppearanceEvents = firingAppearanceEvents;
+       }
 
-        return RasterImageIO.loadRasterData(imageFileName, subset);
-    }
-    
-    //Upgraded to OpenJUMP 2 modification
-    public Rectangle getRectangleFromEnvelope(Envelope envelope) {
+       // Metainformation stuff
+
+       protected MetaDataMap metaInformation = null;
+
+       @Override
+       public MetaDataMap getMetaInformation() {
+               return metaInformation;
+       }
+
+       @Override
+       public void setMetaInformation(MetaDataMap metaInformation) {
+               this.metaInformation = metaInformation;
+       }
+
+       public Raster getRasterData(Rectangle subset) throws IOException {
+
+               return RasterImageIO.loadRasterData(imageFileName, subset);
+       }
+
+       // Upgraded to OpenJUMP 2 modification
+       public Rectangle getRectangleFromEnvelope(Envelope envelope) {
                final double imgWidth = origImageWidth;
                final double imgHeight = origImageHeight;
                final Envelope imageEnv = originalImageEnvelope;
@@ -1389,7 +1501,7 @@
                final int wantedHeight = (int) Math.round((envelope.getHeight() 
* scaleY));
                return new Rectangle(xOffset, yOffset, wantedWidth, 
wantedHeight);
        }
-    
+
 //    /**
 //     * to set the Raster data, use also setImage()
 //     * @param newRaster
@@ -1399,176 +1511,359 @@
 //            setRasterDataChanged(true);
 //    }
 
-       
-    /**
-     * @return the rasterDataChanged
-     */
-    public boolean isRasterDataChanged() {
-        return rasterDataChanged;
-    }
+       /**
+        * @return the rasterDataChanged
+        */
+       public boolean isRasterDataChanged() {
+               return rasterDataChanged;
+       }
 
-    /**
-     * @param rasterDataChanged the rasterDataChanged to set
-     */
-    public void setRasterDataChanged(boolean rasterDataChanged) {
-        this.rasterDataChanged = rasterDataChanged;
-    }
-       
-    /**
-     * Default value is NaN. The value can be different when data have been 
read, 
-     * for example, from (ESRI) ASCII grid images
-     * @return value that is written when a cell does not contain data
-     */
-    public double getNoDataValue() {
-        return noDataValue;
-    }    
-    
-    /**
-     * TODO: sstein test - 25.Sept.2013
-     * @return number of bands
-     */
-    public int getNumBands(){
-       return numBands;
-    }
-    
-    public void dispose() {
-        // TODO: probably a good idea to remove resources when the layer is 
closed up
-        // TiffUtilsV2 contains a cache to avoid reading image files again and 
again
-        // but which can hold file lock for ever if entries are not removed.
-        TiffUtilsV2.removeFromGeoRastercache(new File(imageFileName));
-    }
-           
-    public Double getCellValue(Coordinate coordinate, int band) throws 
IOException {
-        
-        return getCellValue(coordinate.x, coordinate.y, band);
-    }
-    
-    public Double getCellValue(int col, int row, int band) throws IOException {
+       /**
+        * @param rasterDataChanged the rasterDataChanged to set
+        */
+       public void setRasterDataChanged(boolean rasterDataChanged) {
+               this.rasterDataChanged = rasterDataChanged;
+       }
 
-        int pos = row * origImageWidth + col;
-        if(pos <0 || pos > origImageWidth * origImageHeight) return null;
-                       
-        return RasterImageIO.readCellValue(imageFileName, col, row, band);
-        
-    }
+       /**
+        * Default value is NaN. The value can be different when data have been 
read,
+        * for example, from (ESRI) ASCII grid images
+        * 
+        * @return value that is written when a cell does not contain data
+        */
+       public double getNoDataValue() {
+               return noDataValue;
+       }
 
-    public Double getCellValue(double coordX, double coordY, int band) throws 
IOException {
-        
-        double cellSizeX = (originalImageEnvelope.getMaxX() - 
originalImageEnvelope.getMinX()) / origImageWidth;
-        double cellSizeY = (originalImageEnvelope.getMaxY() - 
originalImageEnvelope.getMinY()) / origImageHeight;
-        
-        int col = (int) Math.floor((coordX - originalImageEnvelope.getMinX()) 
/ cellSizeX);
-        int row = origImageHeight - (int) Math.floor((coordY - 
originalImageEnvelope.getMinY()) / cellSizeY) - 1;
-        
-        if(col <0 || col >= origImageWidth || row <0 || row >= 
origImageHeight) return null;
+       /**
+        * TODO: sstein test - 25.Sept.2013
+        * 
+        * @return number of bands

@@ Diff output truncated at 100000 characters. @@


_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to