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