skip to main content
Programmer's documentation > Programming with JViews Maps > Introducing the main classes > Raster image management
 
Raster image management
Describes the management of raster images including tile loading, subsampling, persistence, and storage.
*Raster image management classes
*Describes the classes for managing raster images.
*The IlvRasterAbstractReader class
*Describes the main class for readers of raster image formats.
*Image tiling and subsampling
*Describes the method for tile loading and subsampling of raster image data.
*Persistence of images
*Describes the facilities for persistence of raster image data.
*The IlvRasterMappedBuffer class
*Describes the class for buffering raster data.
*The IlvRasterProperties class
*Describes the class for storing raster image information.
Raster image management classes
The class diagram for raster image management is shown in Raster Image Management UML Diagram.
Raster Image Management UML Diagram
The source code for the Map Builder demonstration, which contains all of the code described in this section, can be found at <installdir> /jviews-maps/samples/mapbuilder/index.html.
The IlvRasterAbstractReader class
The IlvRasterAbstractReader class contains the methods for all readers of raster image formats. It contains a built-in tiling mechanism for tiling the image to be displayed.
Geo-referenced image list
The IlvRasterAbstractReader class is an abstract class that handles an indexed list of geo-referenced images. Each image consists of two objects:
*The raster data (the pixel table values) that are managed by an IlvRasterMappedBuffer.
*The raster properties (color model, size, location, and so on) that are stored in an IlvRasterProperties.
Subclasses should provide a method (often called addImage ) that creates both an IlvRasterProperties and an IlvRasterMappedBuffer and adds them to the list using the addRaster method.
Projection transformation
The IlvRasterAbstractReader needs the projection of the original raster and the projection to use in the view. From these it can dynamically (on-demand) compute every pixel visible in the tile to be loaded. Sub-classes must implement getInternalTransformation in order to provide the coordinate system in which the original data is stored. As the getLowerRightCorner and getUpperLeftCorner methods return the IlvRasterProperties bounds, these bounds must be provided in the same coordinate system.
Image metadata
Image metadata subclasses also have to implement the getProperties method to provide the IlvFeatureAttributeProperty attached to each of the images.
Image tiling and subsampling
Image data is loaded asynchronously (potentially in another thread) into the view using the tile loading mechanism of the getTileLoader method, which returns an IlvRasterTileLoader.
The tile loader is created through the createRasterTileLoader method, which you can override if you want to implement a specific mechanism (for example, to load some of the file content on demand). By default, this method returns either an IlvRasterSubsamplingLoader or an IlvRasterTileLoader according to the value of the subsampling parameter.
The getDefaultFeatureRenderer method returns an IlvRasterImageRenderer that creates an IlvRasterIcon linked to the IlvRasterTileLoader.
The loader getScaledImageProducer method can be invoked by the IlvRasterIcon when the zoom factor changes, or when a styling parameter changes the image properties (such as the color model) in order to re-create the Java™ Image object displayed on the view.
Persistence of images
The base reader is made persistent through the implementation of the IlvPersistentObject interface. This implies implementing a specific constructor (to retrieve data from an input stream) and writing methods.
To manage dataless persistence, it is also necessary to implement a reload method, able to read the raw files from serialized information (such as file names), see Writing a raster reader for DEM data.
The IlvRasterMappedBuffer class
The IlvRasterMappedBuffer class manages raster data for readers. It uses temporary files to store the data when it is not needed.
The buffer stores a table of [width x height] pixel values. Pixel values can use different primitive types, such as byte, short or integer values. The pixel value type must be compatible with the color model of the associated IlvRasterProperties object. The buffer is backed up by two mechanism to reduce memory consumption:
*Memory mapped temporary files: image data is saved in a temporary file that is then mapped in memory (as in the case of the java.nio.MappedByteBuffer class), giving access times close to those of direct memory storage.
*Random access files: image data is saved in a temporary file. When a pixel value needs to be read, it is accessed through a java.io.RandomAccessFile.
If machine dependant constraints prevent the memory mapped mechanism from succeeding (on 32 bits machines, for example, this happens when more than 2-4GB of images have been loaded), the random access file mechanism is put in place immediately.
The IlvRasterTemporaryFileManager class handles temporary files. The temporary file folder can become cluttered, for example, after an application has been interrupted brutally by errors, exceptions, or even debugging session stops. To clean the temporary file folder, you can call:
IlvRasterTemporaryFileManager.removeAllFiles();
This call searches for all temporary files created by JViews Maps applications and try to remove them. Temporary files that are in use, for example, if another application is running, are not removed.
NOTE >> When using the IlvRasterMappedBuffer class in unsigned applets, the creation of temporary files is forbidden. Before loading the data into the model (usually through an addMap call), the application must change the memory policy management to avoid the creation of temporary files. This is done using:
IlvRasterMappedBuffer.setDefaultMemoryPolicy(IlvRasterMappedBuffer.
USE_MEMORY);
With this call, all operations use direct memory to store pixel data. An alternative solution is to sign the applet to allow temporary file creation.
You can even improve this mechanism by providing a Just In Time (JIT) loader. Instead of loading and filling the image bytes at creation, you can provide an instance of JITLoader, that loads the image bytes only when the image is about to be displayed. For example:
IlvRasterMappedBuffer.JITDataLoader jitLoader = new
   IlvRasterMappedBuffer.JITDataLoader() {
      public void loadData(IlvRasterMappedBuffer source, IlvRasterProperties
          properties) {
             System.out.println("loading "+properties.getBaseName());
             // load the data...
          }
      public void unloadData(IlvRasterMappedBuffer source,
         IlvRasterProperties properties) {
         // raz the stored bytes.
      source.setBytes(new byte[0]);
      }
   };
source.setLoader(jitLoader);
If your memory policy is USE_MAP, and you use a JIT loader (or a raster format that internally uses one, such as GeoTIFF, DTED® or CADRG), you should be aware that the loading will first happen in memory. To save load time, the creation of the disk-mapped memory will happen in a background thread. This means that the memory necessary to store the image pixels will be kept for some time in the JVM™, until the disk map is ready to use. In some cases, for example when your application loads lots of large images at the same time, this can lead to out of memory errors, which are by default ignored (the image load restarts again after some time). See also callJITLoaderIfNecessary and setLoadRetryingOnOutOfMemory for more control on this.
The IlvRasterProperties class
The IlvRasterProperties class collects information about the raster image to be tiled and the image to be displayed. This information comprises:
*The raster bounds (coherent with the coordinate system chosen).
*The pixel density (in most cases, this is the ratio between image size and pixel count in each direction).
*The number of blocks in the raster and the number of pixels in a line and in a column of a block. (usually 1).
*The ordering of the pixels in the lines and columns of a block.
*The size that the destination tiles of the raster should adopt.
*The number of pixels the raster has in both directions.
*The transparent pixel value (if any).
*The ColorModel to use with the image.
To create and set up raster properties, you can write, for example:
IlvAdjustableDelegateColorModel csm=new
IlvAdjustableDelegateColorModel(myColorModel);
IlvRasterProperties p=new IlvRasterProperties(csm);
p.setX(xmin);
p.setY(ymax);
p.setWidth(xmax-xmin);
p.setHeight(ymin-ymax);
p.setColumnPixelCount(nbCols);
p.setLinePixelCount(nbRows);
p.setTransparentColorIndex(noDataValue);
p.setHorizontalPixelDensity(p.getWidth() / p.getColumnPixelCount());
p.setVerticalPixelDensity(p.getHeight() / p.getLinePixelCount());
In the example above, the IlvAdjustableDelegateColorModel is needed to provide brightness, saturation and contrast settings for the user.
If the variables xmin / xmax and ymin / ymax are in longitudes, latitudes in radians, and the attached coordinate system is IlvGeographicCoordinateSystem, the reader uses the WGS84 transformation to be coherent with these raster properties.
 IlvCoordinateTransformation.CreateTransformation(
     IlvGeographicCoordinateSystem.KERNEL,
     IlvGeographicCoordinateSystem.WGS84).getTransform();

Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.