package gov.nasa.worldwind.examples;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.layers.*;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.formats.tiff.*;
import gov.nasa.worldwind.util.*;
import javax.imageio.*;
import javax.imageio.spi.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
/**
* @author tag
* @version $Id: SurfaceImageLayer.java 5202 2008-04-29 00:49:43Z tgaskins $
*/
public class SurfaceImageLayer extends RenderableLayer
{
static
{
IIORegistry reg = IIORegistry.getDefaultInstance();
reg.registerServiceProvider(GeotiffImageReaderSpi.inst());
}
private ConcurrentHashMap<String, SurfaceImage> imageTable = new ConcurrentHashMap<String, SurfaceImage>();
public void addImage(String imagePath) throws IOException
{
if (imagePath == null)
{
String message = Logging.getMessage("nullValue.ImageSourceIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
File imageFile = new File(imagePath);
BufferedImage image = ImageIO.read(imageFile);
File worldFile = getWorldFile(imageFile.getAbsoluteFile());
if (worldFile == null || !worldFile.exists())
{
System.out.println("World file for " + imagePath + "does not exist"); // TODO
}
Sector sector = decodeWorldFile(worldFile, image.getWidth(), image.getHeight());
if (sector == null)
{
System.out.println("World file for " + imagePath + "can not be decoded"); // TODO
}
if (this.imageTable.contains(imagePath))
this.removeImage(imagePath);
SurfaceImage si = new SurfaceImage(image, sector);
si.setOpacity(this.getOpacity());
this.addRenderable(si);
this.imageTable.put(imagePath, si);
}
public void removeImage(String imagePath)
{
SurfaceImage si = this.imageTable.get(imagePath);
if (si != null)
{
this.removeRenderable(si);
this.imageTable.remove(imagePath);
}
}
@Override
public void setOpacity(double opacity)
{
super.setOpacity(opacity);
for (Map.Entry<String, SurfaceImage> entry : this.imageTable.entrySet())
{
entry.getValue().setOpacity(opacity);
}
}
private static File getWorldFile(File imageFile)
{
File dir = imageFile.getParentFile();
final String base = WWIO.replaceSuffix(imageFile.getName(), "");
File[] wfiles = dir.listFiles(new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return name.startsWith(base) && name.toLowerCase().endsWith("w");
}
});
return (wfiles != null && wfiles.length > 0) ? wfiles[0] : null;
}
private static Sector decodeWorldFile(File wf, int imageWidth, int imageHeight) throws FileNotFoundException
{
Scanner scanner = new Scanner(wf);
double[] values = new double[6];
for (int i = 0; i < 6; i++)
{
if (scanner.hasNextDouble())
{
values[i] = scanner.nextDouble();
}
else
{
System.out.println("World file missing value at line " + (i + 1));
return null;
}
}
Sector sector = parseDegrees(values, imageWidth, imageHeight);
return sector;
}
private static Sector parseDegrees(double[] values, int imageWidth, int imageHeight)
{
Angle latOrigin = Angle.fromDegrees(values[5]);
Angle latOffset = latOrigin.addDegrees(values[3] * imageHeight);
Angle lonOrigin = Angle.fromDegrees(values[4]);
Angle lonOffset = lonOrigin.addDegrees(values[0] * imageWidth);
Angle minLon, maxLon;
if (lonOrigin.degrees < lonOffset.degrees)
{
minLon = lonOrigin;
maxLon = lonOffset;
}
else
{
minLon = lonOffset;
maxLon = lonOrigin;
}
Angle minLat, maxLat;
if (lonOrigin.degrees < lonOffset.degrees)
{
minLat = latOrigin;
maxLat = latOffset;
}
else
{
minLat = latOffset;
maxLat = latOrigin;
}
return new Sector(minLat, maxLat, minLon, maxLon);
}
}