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 }