package org.openjump.core.rasterimage;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.NoninvertibleTransformException;
import java.io.File;
import java.io.IOException;
import org.openjump.core.ui.plugin.file.OpenRecentPlugIn;
import org.openjump.core.ui.plugin.file.open.ChooseProjectPanel;
import org.openjump.core.ui.plugin.layer.pirolraster.LoadSextanteRasterImagePlugIn;
import org.openjump.core.ui.plugin.layer.pirolraster.RasterImageWizardPanel;
import org.openjump.core.ui.swing.wizard.AbstractWizardGroup;
import org.openjump.io.PropertiesHandler;
import org.openjump.util.metaData.MetaInformationHandler;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.TIFFDirectory;
import com.sun.media.jai.codec.TIFFField;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.task.TaskMonitor;
import com.vividsolutions.jump.workbench.WorkbenchContext;
import com.vividsolutions.jump.workbench.model.Category;
import com.vividsolutions.jump.workbench.model.Layerable;
import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
import com.vividsolutions.jump.workbench.ui.GUIUtil;
import com.vividsolutions.jump.workbench.ui.Viewport;
import com.vividsolutions.jump.workbench.ui.images.famfam.IconLoaderFamFam;
import com.vividsolutions.jump.workbench.ui.wizard.WizardDialog;
import com.vividsolutions.jump.workbench.ui.wizard.WizardPanel;
public class AddRasterImageLayerWizard extends AbstractWizardGroup {
public static final String KEY = AddRasterImageLayerWizard.class.getName();
private WorkbenchContext workbenchContext;
private ChooseProjectPanel chooseProjectPanel;
private SelectRasterImageFilesPanel selectFilesPanel;
private File[] files;
//--- pirol image variables ----
protected PropertiesHandler properties = null;
protected WorldFileHandler worldFileHandler = null;
protected static String propertiesFile = "RasterImage.properties";
protected String KEY_ALLWAYSACCEPT_TWF_EXT = "allwaysCheckForTWFExtension";
protected String KEY_ZOOM_TO_INSERTED_IMAGE = "zoomToImage";
protected boolean allwaysLookForTFWExtension = true;
protected boolean zoomToInsertedImage = true;
private String imageFileName = "";
private String cachedLayer = "default-layer-name";
//------
public AddRasterImageLayerWizard(WorkbenchContext workbenchContext) {
super(I18N.get("org.openjump.core.rasterimage.AddRasterImageLayerWizard.Sextante-Raster-Image"), IconLoaderFamFam.icon("image.png"),
SelectRasterImageFilesPanel.KEY);
this.workbenchContext = workbenchContext;
}
public AddRasterImageLayerWizard(final WorkbenchContext workbenchContext,
final File[] files) {
this.workbenchContext = workbenchContext;
this.files = files;
//initPanels(workbenchContext);
}
public void initialize(WorkbenchContext workbenchContext, WizardDialog dialog) {
initPanels(workbenchContext);
selectFilesPanel.setDialog(dialog);
}
private void initPanels(final WorkbenchContext workbenchContext) {
selectFilesPanel = new SelectRasterImageFilesPanel(workbenchContext);
addPanel(selectFilesPanel);
}
/**
* Load the files selected in the wizard.
*
* @param monitor The task monitor.
*/
public void run(WizardDialog dialog, TaskMonitor monitor) {
this.properties = new PropertiesHandler(AddRasterImageLayerWizard.propertiesFile);
if (files == null) {
File[] selectedFiles = selectFilesPanel.getSelectedFiles();
open(selectedFiles, monitor);
} else {
open(files, monitor);
}
}
private void open(File[] files, TaskMonitor monitor) {
for (File file : files) {
open(file, monitor);
}
}
public void open(File file, TaskMonitor monitor) {
try {
//workbenchContext.getWorkbench().getFrame().warnUser("would load: " + file.getName());
try {
this.properties.setProperty(LoadSextanteRasterImagePlugIn.KEY_PATH, file.getPath());
this.properties.store(" " + this.KEY_ZOOM_TO_INSERTED_IMAGE + I18N.get("RasterImagePlugIn.28") + this.KEY_ALLWAYSACCEPT_TWF_EXT + I18N.get("RasterImagePlugIn.29") + LoadSextanteRasterImagePlugIn.KEY_PATH + I18N.get("RasterImagePlugIn.30"));
String selectedFilename = file.getPath();
this.imageFileName = selectedFilename;
this.cachedLayer = selectedFilename.substring(selectedFilename
.lastIndexOf(File.separator) + 1, selectedFilename
.lastIndexOf("."));
boolean imageAdded = false;
Point imageDimensions = RasterImageLayer.getImageDimensions(workbenchContext, selectedFilename);
Envelope env = this.getGeoReferencing(selectedFilename, this.allwaysLookForTFWExtension, imageDimensions, this.workbenchContext);
if (env != null){
imageAdded = this.addImage(workbenchContext, env, imageDimensions);
}
OpenRecentPlugIn.get(workbenchContext).addRecentFile(file);
} finally {
//reader.close();
}
} catch (Exception e) {
monitor.report(e);
}
}
private boolean addImage(WorkbenchContext context, Envelope envelope, Point imageDimensions) {
String newLayerName = context.getLayerManager().uniqueLayerName(cachedLayer);
String catName = StandardCategoryNames.WORKING;
try {
catName = ((Category) context.createPlugInContext()
.getLayerNamePanel().getSelectedCategories().toArray()[0])
.getName();
} catch (RuntimeException e1) {
//logger.printDebug(e1.getMessage());
}
int layersAsideImage = context.getLayerManager().getLayerables(Layerable.class).size();
RasterImageLayer rLayer = new RasterImageLayer(newLayerName, context.getLayerManager(), this.imageFileName, null, null, envelope);
// #################################
MetaInformationHandler mih = new MetaInformationHandler(rLayer);
// [sstein 28.Feb.2009] -- not sure if these keys should be translated
mih.addMetaInformation("file-name", this.imageFileName);
mih.addMetaInformation("resolution", imageDimensions.x + " (px) x " + imageDimensions.y + " (px)");
mih.addMetaInformation("real-world-width", new Double(envelope.getWidth()));
mih.addMetaInformation("real-world-height", new Double(envelope.getHeight()));
// ###################################
context.getLayerManager().addLayerable( catName, rLayer );
if (zoomToInsertedImage || layersAsideImage==0){
//logger.printDebug("zooming to image, layers: " + layersAsideImage);
try {
context.getLayerViewPanel().getViewport().zoom(envelope);
} catch (NoninvertibleTransformException e) {
//logger.printDebug(e.getMessage());
}
}
return true;
}
/**
* TODO: [sstein] Feb.2009 - I discovered a 0.5px offset towards south-east for
* the envelope, in comparison with images loaded with Jon's/VividSolutions implementation,
* if the envelope is obtained from a worldfile.
* Not sure what is correct. I.e. this implementation seems to assume that the worldfile
* coordinate system origin is the corner of the first pixel and not the center.
* I have corrected this in WorldFileHandler.readWorldFile()
* @param fileName
* @param allwaysLookForTFWExtension
* @param imageDimensions
* @param context
* @return the RasterImage Envelope
* @throws IOException
* @throws NoninvertibleTransformException
*/
protected Envelope getGeoReferencing(String fileName, boolean allwaysLookForTFWExtension, Point imageDimensions, WorkbenchContext context) throws IOException, NoninvertibleTransformException{
double minx, maxx, miny, maxy;
Envelope env = null;
this.worldFileHandler = new WorldFileHandler(fileName, allwaysLookForTFWExtension);
if (imageDimensions == null){
//logger.printError("can not determine image dimensions");
context.getWorkbench().getFrame().warnUser(I18N.get("org.openjump.core.rasterimage.AddRasterImageLayerWizard.can-not-determine-image-dimensions"));
return null;
}
if (this.worldFileHandler.isWorldFileExistentForImage()!=null) {
//logger.printDebug(PirolPlugInMessages.getString("worldfile-found"));
env = this.worldFileHandler.readWorldFile(imageDimensions.x, imageDimensions.y);
}
if (env == null) {
boolean isGeoTiff = false;
if ( fileName.toLowerCase().endsWith(".tif") || fileName.toLowerCase().endsWith(".tiff") ) {
//logger.printDebug("checking for GeoTIFF");
Coordinate tiePoint = null, pixelOffset = null, pixelScale = null;
double[] doubles = null;
FileSeekableStream fileSeekableStream = new FileSeekableStream(fileName);
TIFFDirectory tiffDirectory = new TIFFDirectory(fileSeekableStream, 0);
TIFFField[] availTags = tiffDirectory.getFields();
for (int i=0; i<availTags.length; i++){
if (availTags[i].getTag() == GeoTiffConstants.ModelTiepointTag){
doubles = availTags[i].getAsDoubles();
if (doubles.length != 6){
//logger.printError("unsupported value for ModelTiepointTag (" + GeoTiffConstants.ModelTiepointTag + ")");
context.getWorkbench().getFrame().warnUser("unsupported value for ModelTiepointTag (" + GeoTiffConstants.ModelTiepointTag + ")");
break;
}
if (doubles[0]!=0 || doubles[1]!=0 || doubles[2]!=0){
if (doubles[2]==0)
pixelOffset = new Coordinate(doubles[0],doubles[1]);
else
pixelOffset = new Coordinate(doubles[0],doubles[1],doubles[2]);
}
if (doubles[5]==0)
tiePoint = new Coordinate(doubles[3],doubles[4]);
else
tiePoint = new Coordinate(doubles[3],doubles[4],doubles[5]);
//logger.printDebug("ModelTiepointTag (po): " + pixelOffset);
//logger.printDebug("ModelTiepointTag (tp): " + tiePoint);
} else if (availTags[i].getTag() == GeoTiffConstants.ModelPixelScaleTag){
// Karteneinheiten pro pixel x bzw. y
doubles = availTags[i].getAsDoubles();
if (doubles[2]==0)
pixelScale = new Coordinate(doubles[0],doubles[1]);
else
pixelScale = new Coordinate(doubles[0],doubles[1],doubles[2]);
//logger.printDebug("ModelPixelScaleTag (ps): " + pixelScale);
} else {
//logger.printDebug("tiff field: " + availTags[i].getType() + ", "+ availTags[i].getTag() + ", "+ availTags[i].getCount());
}
}
fileSeekableStream.close();
if (tiePoint!=null && pixelScale!=null){
isGeoTiff = true;
Coordinate upperLeft = null, lowerRight = null;
if (pixelOffset==null){
upperLeft = tiePoint;
} else {
upperLeft = new Coordinate( tiePoint.x - (pixelOffset.x * pixelScale.x), tiePoint.y - (pixelOffset.y * pixelScale.y));
}
lowerRight = new Coordinate( upperLeft.x + (imageDimensions.x * pixelScale.x), upperLeft.y - (imageDimensions.y * pixelScale.y));
//logger.printDebug("upperLeft: " + upperLeft);
//logger.printDebug("lowerRight: " + lowerRight);
env = new Envelope(upperLeft, lowerRight);
}
}else if(fileName.toLowerCase().endsWith(".flt")){
isGeoTiff = true;
GridFloat gf = new GridFloat(fileName);
Coordinate upperLeft = new Coordinate(gf.getXllCorner(), gf.getYllCorner() + gf.getnRows() * gf.getCellSize());
Coordinate lowerRight = new Coordinate(gf.getXllCorner() + gf.getnCols() * gf.getCellSize(), gf.getYllCorner());
env = new Envelope(upperLeft, lowerRight);
}else if(fileName.toLowerCase().endsWith(".asc")){
isGeoTiff = true;
GridAscii ga = new GridAscii(fileName);
Coordinate upperLeft = new Coordinate(ga.getXllCorner(), ga.getYllCorner() + ga.getnRows() * ga.getCellSize());
Coordinate lowerRight = new Coordinate(ga.getXllCorner() + ga.getnCols() * ga.getCellSize(), ga.getYllCorner());
env = new Envelope(upperLeft, lowerRight);
}
if (!isGeoTiff || env==null){
//logger.printDebug(PirolPlugInMessages.getString("no-worldfile-found"));
context.getWorkbench().getFrame().warnUser(I18N.get("org.openjump.core.rasterimage.AddRasterImageLayerWizard.no-worldfile-found"));
WizardDialog d = new WizardDialog(
context.getWorkbench().getFrame(),
I18N.get("RasterImagePlugIn.34")
+ this.worldFileHandler.getWorldFileName()
+ I18N.get("RasterImagePlugIn.35"),
context.getErrorHandler());
d.init(new WizardPanel[] { new RasterImageWizardPanel() });
//Set size after #init, because #init calls #pack. [Jon Aquino]
d.setSize(500, 400);
GUIUtil.centreOnWindow(d);
d.setVisible(true);
if (!d.wasFinishPressed()) {
//logger.printWarning("user canceled");
return null;
}
try {
minx = Double.parseDouble((String) d
.getData(RasterImageWizardPanel.MINX_KEY));
maxx = Double.parseDouble((String) d
.getData(RasterImageWizardPanel.MAXX_KEY));
miny = Double.parseDouble((String) d
.getData(RasterImageWizardPanel.MINY_KEY));
maxy = Double.parseDouble((String) d
.getData(RasterImageWizardPanel.MAXY_KEY));
env = new Envelope(minx, maxx, miny, maxy);
}
catch(java.lang.NumberFormatException e) {
Viewport viewport = context.getLayerViewPanel().getViewport();
Rectangle visibleRect = viewport.getPanel().getVisibleRect();
int visibleX1 = visibleRect.x;
int visibleY1 = visibleRect.y;
int visibleX2 = visibleX1 + visibleRect.width;
int visibleY2 = visibleY1 + visibleRect.height;
Coordinate upperLeftVisible = viewport.toModelCoordinate(new Point(0,0));
Coordinate lowerRightVisible = viewport.toModelCoordinate(new Point(visibleX2, visibleY2));
env = new Envelope(upperLeftVisible.x, lowerRightVisible.x, upperLeftVisible.y, lowerRightVisible.y);
}
}
// creating world file
this.worldFileHandler = new WorldFileHandler(fileName, this.allwaysLookForTFWExtension);
this.worldFileHandler.writeWorldFile(env, imageDimensions.x, imageDimensions.y);
}
return env;
}
}