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 }