/* * Created on 01.07.2005 * * CVS information: * $Author: LBST-PF-3\orahn $ * $Date: 2006-10-06 10:01:50 +0000 (Fr, 06 Okt 2006) $ * $ID$ * $Rev: 2509 $ * $Id: WorldFileHandler.java 2509 2006-10-06 10:01:50Z LBST-PF-3\orahn $ * $Log: WorldFileHandler.java,v $ * Revision 1.2 2006/05/03 14:25:33 orahn * kleine Verbesserung im Worldfilehandler * * Revision 1.1 2006/01/04 18:11:04 orahn * new model for raster image support - may require yet core patch * * Revision 1.5 2005/07/13 10:11:26 orahn * +HandlerToMakeYourLifeEasier * * Revision 1.4 2005/07/05 16:35:39 orahn * todo raus * * Revision 1.3 2005/07/05 13:01:06 orahn * bugfix: Fehler beim Schreiben von world files * * Revision 1.2 2005/07/05 11:33:04 orahn * warnings raus * * Revision 1.1 2005/07/01 20:38:36 orahn * verbesserte Lade-Reihenfolge und verallgemeinertes Handling vom WorldFiles * */ package org.openjump.core.rasterimage; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.openjump.core.apitools.HandlerToMakeYourLifeEasier; import com.vividsolutions.jts.geom.Envelope; /** * * class to create a ESRI-Worldfile for RasterImages that are exported from Jump, * also for reading existent world files. * * @author Ole Rahn * <br> * <br>FH Osnabrück - University of Applied Sciences Osnabrück, * <br>Project: PIROL (2005), * <br>Subproject: Daten- und Wissensmanagement * * @version $Rev: 2509 $ * modified: [sstein]: 16.Feb.2009 changed logger-entries to comments */ public class WorldFileHandler implements HandlerToMakeYourLifeEasier{ protected String worldFileName = null; protected String imageFileName = null; private boolean allwaysLookForTFWExtension = true; //protected PersonalLogger logger = new PersonalLogger(DebugUserIds.OLE); /** * @param imageFileName name of the image file the world file is for * @param allwaysLookForTFWExtension if true the worldFileHandler will look for * world files with the extension <code>.tfw</code> even if the image file format * would suggest an other extension, like <code>.pgw</code> - this parameter has no influence * on the writing of world files! */ public WorldFileHandler(String imageFileName, boolean allwaysLookForTFWExtension) { super(); this.imageFileName = imageFileName; this.allwaysLookForTFWExtension = allwaysLookForTFWExtension; this.worldFileName = this.isWorldFileExistentForImage(); if (this.worldFileName == null) this.worldFileName = (String)this.createListOfWorldFileNamesForImage().get(0); } /** * Method that writes a world file according to the given coordinate * and image information. * @param imageCoordinates real world coordinates of the image * @param imgWidth width (in pixel) of the image * @param imgHeight height (in pixel) of the image * @return true if a world file was written, else false */ public boolean writeWorldFile(Envelope imageCoordinates, int imgWidth, int imgHeight){ double faktorA, faktorB, faktorC, faktorD, CoordX, CoordY; double maxx = imageCoordinates.getMaxX(); double minx = imageCoordinates.getMinX(); double maxy = imageCoordinates.getMaxY(); double miny = imageCoordinates.getMinY(); try { FileWriter worldfileWriter = new FileWriter(this.worldFileName, false); faktorA = (maxx - minx) / imgWidth; faktorB = 0; faktorC = 0; faktorD = (miny - maxy) / imgHeight; CoordX = minx; CoordY = maxy; //-- [sstein] Dec.2009 -- we need to move corner coordinates toward the pixel center // by 0.5 pixel, since thats what the specifications say double px05x = ((maxx-minx) / imgWidth)*0.5; double px05y = ((maxy-miny) / imgHeight)*0.5; CoordX = CoordX + px05x; CoordY = CoordY - px05y; //-- [sstein] end worldfileWriter.write(Double.toString(faktorA) + "\n"); worldfileWriter.write(Double.toString(faktorB) + "\n"); worldfileWriter.write(Double.toString(faktorC) + "\n"); worldfileWriter.write(Double.toString(faktorD) + "\n"); worldfileWriter.write(Double.toString(CoordX) + "\n"); worldfileWriter.write(Double.toString(CoordY)); worldfileWriter.close(); } catch (IOException e) { //this.logger.printError("Worldfile was not written: " + e.getMessage()); return false; } //this.logger.printDebug("world file " + this.worldFileName + " was written"); return true; } /** * Retrieve the real world coordinates of the image from the world file * @param imgWidth width (in pixel) of the image * @param imgHeight height (in pixel) of the image * @return real world coordinates of the image */ public Envelope readWorldFile(int imgWidth, int imgHeight){ FileReader worldFileReader; try { worldFileReader = new FileReader(this.worldFileName); } catch (FileNotFoundException e1) { //this.logger.printError("Worldfile not found: " + e1.getMessage()); return null; } BufferedReader bufferedWorldFileReader = new BufferedReader(worldFileReader); double minx, maxx, miny, maxy; double faktorA, faktorB, faktorC, faktorD, CoordX, CoordY; String number = null; try { number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); faktorA = Double.parseDouble(number); number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); faktorB = Double.parseDouble(number); number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); faktorC = Double.parseDouble(number); number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); faktorD = Double.parseDouble(number); number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); CoordX = Double.parseDouble(number); number = bufferedWorldFileReader.readLine().replaceAll("[,]","."); CoordY = Double.parseDouble(number); } catch (Exception e) { //this.logger.printError("Can not read worldfile: " + e.getMessage()); return null; } //[sstein] Feb.2009 -- the use of CoordX (Easting) and CoordY (Northing) below does not // respect that the coordinates are given for the // center of the upper left pixel and not the corner. minx = faktorA * 0. + faktorC * 0. + CoordX; maxy = faktorB * 0. + faktorD * 0. + CoordY; maxx = faktorA * imgWidth + faktorC * imgHeight + CoordX; miny = faktorB * imgWidth + faktorD * imgHeight + CoordY; //-- [sstein] Feb.2009 -- so we move the final envelope by 0.5 pixel double px05x = ((maxx-minx) / imgWidth)*0.5; double px05y = ((maxy-miny) / imgHeight)*0.5; // I am using different params for x,y due to possible image transforms minx = minx-px05x; maxx = maxx-px05x; miny = miny+px05y; maxy = maxy+px05y; //-- sstein:end return new Envelope(minx, maxx, miny, maxy); } /** * creates a list of possible worldfile names for the given image * file name. The first one meets the naming conventions from ESRI, * the other names are variations that we got from ArcView, far away * from conventions... * @return a list of possible worldfile names */ protected List createListOfWorldFileNamesForImage(){ String worldFileName = this.imageFileName.substring(0, this.imageFileName.lastIndexOf(".")); String imageExtension = this.imageFileName.substring(this.imageFileName.lastIndexOf(".") + 1).toLowerCase(); List possibleWorldFileNames = new ArrayList(); possibleWorldFileNames.add(worldFileName + "." + imageExtension.substring(0, 1) + imageExtension.substring(imageExtension.length() - 1) + "w"); possibleWorldFileNames.add((worldFileName + "." + imageExtension.substring(0, 1).toUpperCase() + imageExtension.substring(imageExtension.length() - 1) + "w").toUpperCase()); possibleWorldFileNames.add(worldFileName + "." + imageExtension + "w"); possibleWorldFileNames.add(worldFileName + "." + (imageExtension + "w").toUpperCase()); if (allwaysLookForTFWExtension) { possibleWorldFileNames.add(worldFileName + ".tfw"); possibleWorldFileNames.add(worldFileName + ".tfw".toUpperCase()); } return possibleWorldFileNames; } /** * Method that checks if a world file for the given image name can be found. * If so, it's name will be returned and also be stored internally. * @return the name of the worldfile if existent, else null */ public String isWorldFileExistentForImage(){ List possibleWorldFileNames = this.createListOfWorldFileNamesForImage(); File worldFile = null; String wfName; for (int i = 0; i < possibleWorldFileNames.size(); i++) { wfName = ((String) possibleWorldFileNames.get(i)); worldFile = new File(wfName); //this.logger.printDebug("checking for world file named " + wfName); if (worldFile.exists()) { return (this.worldFileName = wfName); } } return null; } /** * @return Returns the allwaysLookForTFWExtension. */ public boolean isAllwaysLookForTFWExtension() { return allwaysLookForTFWExtension; } /** * @param allwaysLookForTFWExtension The allwaysLookForTFWExtension to set. */ public void setAllwaysLookForTFWExtension(boolean allwaysLookForTFWExtension) { this.allwaysLookForTFWExtension = allwaysLookForTFWExtension; } /** * @return Returns the imageFileName. */ public String getImageFileName() { return imageFileName; } /** * @param imageFileName The imageFileName to set. */ public void setImageFileName(String imageFileName) { this.imageFileName = imageFileName; } /** * @return Returns the worldFileName. */ public String getWorldFileName() { return worldFileName; } }