/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: klaus.greve@uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.tools.raster;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import org.deegree.graphics.Encoders;
import org.deegree.graphics.transformation.GeoTransform;
import org.deegree.graphics.transformation.WorldToScreenTransform;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.SeekableStream;
/**
* utility program to group several image tiles into one large image
*
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
* @author last edited by: $Author: poth $
*
* @version 1.1, $Revision: 1.7 $, $Date: 2006/07/12 14:46:18 $
*
* @since 1.1
*
* @deprecated use @see org.deegree.tools.raster.RasterTreeBuilder instead; this class
* will be removed from deegree at the end of 2007
*/
public class GlueTiles {
private String rootDir = null;
private String inputFileFormat = null;
private String outputFileFormat = null;
private double inputXSize = 0;
private double inputYSize = 0;
private double outputXSize = 0;
private double outputYSize = 0;
private double nX = 0;
private double nY = 0;
private String resInd = "";
GeoTransform gti = null;
/**
*
* @param rootDir
* @param inputFileFormat
* @param outputFileFormat
* @param inputXSize
* @param inputYSize
* @param outputXSize
* @param outputYSize
* @param minx
* @param miny
* @param maxx
* @param maxy
* @param nX
* @param nY
*/
public GlueTiles(String rootDir, String inputFileFormat, String outputFileFormat,
int outputXSize, int outputYSize,
double minx, double miny, double maxx, double maxy, double nX,
double nY, String resInd) {
this.rootDir = rootDir;
this.inputFileFormat = inputFileFormat;
this.outputFileFormat = outputFileFormat.toLowerCase();
this.outputXSize = outputXSize;
this.outputYSize = outputYSize;
this.nX = nX;
this.nY = nY;
gti = new WorldToScreenTransform( minx, miny, maxx, maxy, 0, 0,
outputXSize-1, outputYSize-1 );
this.resInd = resInd;
}
/**
* walk in a recursion through all directories under the passed one
* and returns the names/pathes of all contained XML-files
*
* @param dir directory to start from
* @return
*/
private List getFiles(String dir) {
List list = new ArrayList(200);
File file = new File( dir );
String[] lst = file.list(new DFileFilter());
for (int i = 0; i < lst.length; i++) {
File fl = new File( dir + '/' + lst[i] );
if ( fl.isDirectory() ) {
List l = getFiles( dir + '/' + lst[i] );
list.addAll( l );
} else {
list.add( dir + '/' + lst[i] );
}
}
return list;
}
/**
*
* @throws Exception
*/
private void readTiles()throws Exception{
if ( !rootDir.endsWith( "/" ) ) rootDir = rootDir+ "/";
List list = getFiles( rootDir );
String[] tiles = (String[])list.toArray(new String[list.size()]);
System.out.println("create IMG");
BufferedImage outBi =
new BufferedImage( (int)outputXSize, (int)outputYSize, BufferedImage.TYPE_INT_ARGB );
Graphics g = outBi.getGraphics();
g.setColor( Color.BLUE );
g.fillRect(0,0,(int)outputXSize, (int)outputYSize);
int t5 = (int)Math.round(tiles.length/100d * 5d);
int cnt = 0;
for (int i = 0; i < tiles.length; i++ ) {
if ( i % t5 == 0) {
System.out.println(cnt + "%");
cnt = cnt+5;
}
try {
Thread.sleep(80);
} catch(Exception e) {
e.printStackTrace();
}
File fil = new File( tiles[i] );
if ( !fil.exists() ) continue;
try {
double[] inBBox = readWorldFile( tiles[i] );
try {
Thread.sleep(20);
} catch(Exception e) {
e.printStackTrace();
}
SeekableStream sst = new FileSeekableStream( tiles[i] );
RenderedOp ro = JAI.create( "stream", sst );
BufferedImage bi = ro.getAsBufferedImage();
inputXSize = bi.getWidth();
inputYSize = bi.getHeight();
ParameterBlock pb = new ParameterBlock();
pb.addSource(ro); // The source image
pb.add( (float)((outputXSize/nX)/inputXSize) ); // The xScale
pb.add( (float)((outputYSize/nY)/inputYSize) ); // The yScale
pb.add(0.0F); // The x translation
pb.add(0.0F); // The y translation
pb.add(new InterpolationNearest() ); // The interpolation
// Create the scale operation
ro = JAI.create("scale", pb, null);
bi = ro.getAsBufferedImage();
sst.close();
try {
Thread.sleep(20);
} catch(Exception e) {
System.out.println(e);
}
int c = (int)Math.round( gti.getDestX( inBBox[0] ) );
int r = (int)Math.round( gti.getDestY( inBBox[3] ) );
int c1 = (int)Math.round( gti.getDestX( inBBox[2] ) );
int r2 = (int)Math.round( gti.getDestY( inBBox[1] ) );
g.drawImage( bi, c, r, Math.abs(c1-c), Math.abs(r2-r), null );
bi = null;
} catch(Exception ee) {
ee.printStackTrace();
}
System.gc();
}
FileOutputStream fileOut = new FileOutputStream( rootDir + "out." + outputFileFormat );
if ( outputFileFormat.equals( "jpg" ) ) {
Encoders.encodeJpeg(fileOut, outBi);
} else if ( outputFileFormat.equals( "bmp" ) ) {
Encoders.encodeBmp(fileOut, outBi);
} else if ( outputFileFormat.equals( "tif" ) ) {
Encoders.encodeTiff(fileOut, outBi);
} else if ( outputFileFormat.equals( "png" ) ) {
Encoders.encodePng(fileOut, outBi);
} else if ( outputFileFormat.equals( "gif" ) ) {
Encoders.encodeGif(fileOut, outBi);
}
fileOut.close();
System.gc();
}
/**
* Gets the latitude and longitude coordinates (xmin, ymin, xmax and ymax)
* of the image.
*/
private double[] readWorldFile( String filename ) throws Exception {
try {
// Gets the substring beginning at the specified beginIndex (0) - the
// beginning index, inclusive - and extends to the character at
// index endIndex (position of '.') - the ending index, exclusive.
String fname = null;
int pos = filename.lastIndexOf( "." );
filename = filename.substring( 0, pos );
//Looks for corresponding worldfiles.
if ( ( new File( filename + ".tfw" ) ).exists() ) {
fname = filename + ".tfw";
} else if ( ( new File( filename + ".wld" ) ).exists() ) {
fname = filename + ".wld";
} else if ( ( new File( filename + ".jgw" ) ).exists() ) {
fname = filename + ".jgw";
} else if ( ( new File( filename + ".jpgw" ) ).exists() ) {
fname = filename + ".jpgw";
} else if ( ( new File( filename + ".gfw" ) ).exists() ) {
fname = filename + ".gfw";
} else if ( ( new File( filename + ".gifw" ) ).exists() ) {
fname = filename + ".gifw";
} else if ( ( new File( filename + ".pgw" ) ).exists() ) {
fname = filename + ".pgw";
} else if ( ( new File( filename + ".pngw" ) ).exists() ) {
fname = filename + ".pngw";
} else {
throw new Exception( "Not a world file for: " + filename );
}
// Reads character files.
// The constructors of this class (FileReader) assume that the default character
// encoding and the default byte-buffer size are appropriate.
// The BufferedReader reads text from a character-input stream, buffering characters so as
// to provide for the efficient reading of characters
BufferedReader br = new BufferedReader( new FileReader( fname ) );
String s = null;
int cnt = 0;
double d1 = 0;
double d2 = 0;
double d3 = 0;
double d4 = 0;
while ( ( s = br.readLine() ) != null ) {
cnt++;
s = s.trim();
switch ( cnt ) {
case 1:
d1 = Double.parseDouble( s );
break;
case 4:
d2 = Double.parseDouble( s );
break;
case 5:
d3 = Double.parseDouble( s );
break;
case 6:
d4 = Double.parseDouble( s );
break;
}
}
br.close();
double d5 = d3 + ( inputXSize * d1 );
double d6 = d4 + ( inputYSize * d2 );
double[] bbox = new double[4];
bbox[0] = d3;
bbox[1] = d6;
bbox[2] = d5;
bbox[3] = d4;
return bbox;
} catch ( Exception ex ) {
ex.printStackTrace();
}
return null;
}
/**
* class: official version of a FilenameFilter
*/
private class DFileFilter implements FilenameFilter {
public String getDescription() {
return "*."+inputFileFormat;
}
public boolean accept(File f, String name) {
int pos = name.lastIndexOf(".");
String ext = name.substring( pos+1 );
File fl = new File( f.getAbsolutePath() + '/' + name );
if ( fl.isDirectory() ) {
System.out.println(f.getAbsolutePath() + '/' + name );
}
return (ext.equalsIgnoreCase(inputFileFormat) &&
f.getAbsolutePath().indexOf(resInd) > -1 ) || fl.isDirectory();
}
}
public static void main(String args[]) {
if ( args == null || args.length < 12 ) {
System.out.println("Parameter is missing: ");
System.out.println("Parameter in order as required: ");
System.out.println("root directory ");
System.out.println("image format of the tiles");
System.out.println("image format of the result ");
System.out.println("width of the result in pixel ");
System.out.println("height of the result in pixel ");
System.out.println("BBOX minx of the result");
System.out.println("BBOX miny of the result");
System.out.println("BBOX maxx of the result");
System.out.println("BBOX maxy of the result");
System.out.println("number of tiles in x direction");
System.out.println("number of tiles in y direction");
System.out.println("resolution prefix; e.g. l20.0 or l34.3");
System.exit(1);
}
GlueTiles l = new GlueTiles(args[0], args[1], args[2], Integer.parseInt(args[3]),
Integer.parseInt(args[4]), Double.parseDouble(args[5]),
Double.parseDouble(args[6]), Double.parseDouble(args[7]),
Double.parseDouble(args[8]), Integer.parseInt(args[9]),
Integer.parseInt(args[10]), args[11] );
try{
l.readTiles();
} catch (Exception ex) {
System.out.println(ex);
}
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: GlueTiles.java,v $
Revision 1.7 2006/07/12 14:46:18 poth
comment footer added
********************************************************************** */