001 //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/tools/raster/SimpleText2Tiff.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53177 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: klaus.greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.tools.raster; 044 045 import java.awt.color.ColorSpace; 046 import java.awt.image.BufferedImage; 047 import java.awt.image.ComponentColorModel; 048 import java.awt.image.DataBuffer; 049 import java.awt.image.Raster; 050 import java.awt.image.WritableRaster; 051 import java.io.BufferedReader; 052 import java.io.File; 053 import java.io.FileReader; 054 import java.io.IOException; 055 import java.util.ArrayList; 056 import java.util.Hashtable; 057 import java.util.List; 058 import java.util.Properties; 059 060 import org.deegree.framework.util.ConvenienceFileFilter; 061 import org.deegree.framework.util.ImageUtils; 062 import org.deegree.framework.util.StringTools; 063 import org.deegree.model.coverage.grid.WorldFile; 064 import org.deegree.model.spatialschema.Envelope; 065 import org.deegree.model.spatialschema.GeometryFactory; 066 067 /** 068 * This class ist similar to Text2Tiff. The major difference is that SimpleText2Tiff just is able to 069 * transform x y z formateted textfiles into 16BIT tiff images if the text files contains equal 070 * distance rasters. Missing raster cells will be filled with '0'.<br> 071 * The major advantage of SimpleText2Tiff is its speed. It is significantly faster than Text2Tiff 072 * because several checks and calculations can be skippted. 073 * 074 * 075 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 076 * @author last edited by: $Author: poth $ 077 * 078 * @version. $Revision: 6251 $, $Date: 2007-03-19 16:59:28 +0100 (Mo, 19 Mrz 2007) $ 079 */ 080 public class SimpleText2Tiff { 081 082 private File[] files; 083 084 private double resolution; 085 086 private float offset = 0; 087 088 private float scaleFactor = 1; 089 090 private boolean use32Bit = false; 091 092 /** 093 * 094 * @param files 095 * list of text files to tranform 096 * @param resolution 097 * desired target resolution 098 * @param offset 099 * desired z-value offset 100 * @param scaleFactor 101 * desired z-value scale factor [value = (z + offset) * scaleFactor] 102 * @param use32Bit 103 */ 104 public SimpleText2Tiff( File[] files, double resolution, float offset, float scaleFactor, boolean use32Bit ) { 105 this.files = files; 106 this.resolution = resolution; 107 this.offset = offset; 108 this.scaleFactor = scaleFactor; 109 this.use32Bit = use32Bit; 110 } 111 112 /** 113 * starts transformation 114 * 115 * @throws Exception 116 */ 117 public void perform() 118 throws Exception { 119 for ( int i = 0; i < files.length; i++ ) { 120 System.out.println( "process: " + files[i] ); 121 text2tiff( files[i] ); 122 } 123 } 124 125 /** 126 * 127 * @param file 128 * @throws Exception 129 */ 130 private void text2tiff( File file ) 131 throws Exception { 132 Envelope bbox = getBoundingBox( file ); 133 int width = (int) Math.round( bbox.getWidth() / resolution ) + 1; 134 int height = (int) Math.round( bbox.getHeight() / resolution ) + 1; 135 136 BufferedImage out = null; 137 if ( use32Bit ) { 138 out = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); 139 } else { 140 ComponentColorModel ccm = new ComponentColorModel( ColorSpace.getInstance( ColorSpace.CS_GRAY ), null, 141 false, false, BufferedImage.OPAQUE, 142 DataBuffer.TYPE_USHORT ); 143 WritableRaster wr = ccm.createCompatibleWritableRaster( width, height ); 144 out = new BufferedImage( ccm, wr, false, new Hashtable() ); 145 } 146 DataBuffer buffer = out.getRaster().getDataBuffer(); 147 148 BufferedReader br = new BufferedReader( new FileReader( file ) ); 149 String line = null; 150 while ( ( line = br.readLine() ) != null ) { 151 double[] d = StringTools.toArrayDouble( line.trim(), " \t" ); 152 int x = (int) Math.round( ( d[0] - bbox.getMin().getX() ) / resolution ); 153 int y = height - (int) Math.round( ( d[1] - bbox.getMin().getY() ) / resolution ) - 1; 154 int pos = width * y + x; 155 156 try { 157 if ( use32Bit ) { 158 buffer.setElem( pos, Float.floatToIntBits( (float) ( ( d[2] + offset ) * scaleFactor ) ) ); 159 } else { 160 // buffer.setElemFloat( pos, (float) ( ( d[2] + offset ) * scaleFactor ) ); 161 buffer.setElem( pos, (int) Math.round( ( d[2] + offset ) * scaleFactor ) ); 162 } 163 buffer.setElem( pos, Float.floatToIntBits( (float) d[2] ) ); 164 } catch ( Exception e ) { 165 System.out.println( "-------------------------------" ); 166 System.out.println( buffer.getSize() ); 167 System.out.println( "file bbox: " + bbox ); 168 System.out.println( "last line read: " + line ); 169 throw e; 170 } 171 } 172 br.close(); 173 out.setData( Raster.createRaster( out.getSampleModel(), buffer, null ) ); 174 175 int pos = file.getAbsolutePath().lastIndexOf( '.' ); 176 if ( pos < 0 ) { 177 pos = file.getAbsolutePath().length(); 178 } 179 String fileName = file.getAbsolutePath().substring( 0, pos ) + ".tif"; 180 ImageUtils.saveImage( out, fileName, 1 ); 181 WorldFile wf = new WorldFile( resolution, resolution, 0, 0, bbox ); 182 WorldFile.writeWorldFile( wf, file.getAbsolutePath().substring( 0, pos ) ); 183 184 } 185 186 /** 187 * 188 * @param file 189 * @return 190 * @throws IOException 191 */ 192 private Envelope getBoundingBox( File file ) 193 throws IOException { 194 BufferedReader br = new BufferedReader( new FileReader( file ) ); 195 String line = null; 196 double minx = Double.MAX_VALUE; 197 double miny = Double.MAX_VALUE; 198 double maxx = Double.MIN_VALUE; 199 double maxy = Double.MIN_VALUE; 200 201 while ( ( line = br.readLine() ) != null ) { 202 double[] d = StringTools.toArrayDouble( line.trim(), " \t" ); 203 if ( d[0] < minx ) { 204 minx = d[0]; 205 } 206 if ( d[0] > maxx ) { 207 maxx = d[0]; 208 } 209 210 if ( d[1] < miny ) { 211 miny = d[1]; 212 } 213 if ( d[1] > maxy ) { 214 maxy = d[1]; 215 } 216 } 217 br.close(); 218 return GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null ); 219 } 220 221 /** 222 * @param args 223 * @throws IOException 224 */ 225 public static void main( String[] args ) 226 throws Exception { 227 228 Properties map = new Properties(); 229 for ( int i = 0; i < args.length; i += 2 ) { 230 map.put( args[i], args[i + 1] ); 231 } 232 if ( !validate( map ) ) { 233 System.out.println( "Parameters: -rootDir, -resolution, -offset and -scaleFactor must be set" ); 234 return; 235 } 236 237 List<File> fileList = new ArrayList<File>( 1000 ); 238 File dir = new File( map.getProperty( "-rootDir" ) ); 239 File[] files = null; 240 ConvenienceFileFilter cff = null; 241 if ( map.getProperty( "-extension" ) != null ) { 242 cff = new ConvenienceFileFilter( true, map.getProperty( "-extension" ) ); 243 files = dir.listFiles( cff ); 244 } else { 245 files = dir.listFiles(); 246 } 247 for ( int i = 0; i < files.length; i++ ) { 248 if ( files[i].isDirectory() ) { 249 readSubDirs( files[i], fileList, cff ); 250 } else { 251 fileList.add( files[i] ); 252 } 253 } 254 255 double resolution = Double.parseDouble( map.getProperty( "-resolution" ) ); 256 float offset = Float.parseFloat( map.getProperty( "-offset" ) ); 257 float scaleFactor = Float.parseFloat( map.getProperty( "-scaleFactor" ) ); 258 boolean use32Bit = "true".equals( map.getProperty( "-use32Bit" ) ); 259 SimpleText2Tiff t2t = new SimpleText2Tiff( fileList.toArray( new File[fileList.size()] ), resolution, offset, 260 scaleFactor, use32Bit ); 261 t2t.perform(); 262 263 } 264 265 /** 266 * 267 * @param file 268 * @param list 269 * @param cff 270 * @return list of files 271 */ 272 private static List<File> readSubDirs( File file, List<File> list, ConvenienceFileFilter cff ) { 273 File[] entries = null; 274 if ( cff != null ) { 275 entries = file.listFiles( cff ); 276 } else { 277 entries = file.listFiles(); 278 } 279 if ( entries != null ) { 280 for ( int i = 0; i < entries.length; i++ ) { 281 if ( entries[i].isDirectory() ) { 282 list = readSubDirs( entries[i], list, cff ); 283 } else { 284 list.add( entries[i] ); 285 } 286 } 287 } 288 return list; 289 } 290 291 /** 292 * 293 * @param param 294 * @return true if everything is correct 295 * @throws Exception 296 */ 297 private static boolean validate( Properties param ) 298 throws Exception { 299 300 if ( param.get( "-rootDir" ) == null ) { 301 System.out.println( "parameter -rootDir must be set" ); 302 return false; 303 } 304 if ( param.get( "-resolution" ) == null ) { 305 System.out.println( "parameter -resolution must be set" ); 306 return false; 307 } 308 if ( param.get( "-offset" ) == null ) { 309 System.out.println( "parameter -offset must be set" ); 310 return false; 311 } 312 if ( param.get( "-scaleFactor" ) == null ) { 313 System.out.println( "parameter -scaleFactor must be set" ); 314 return false; 315 } 316 317 return true; 318 } 319 320 }