001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/tools/raster/Text2Tiff.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.ColorModel;
048    import java.awt.image.ComponentColorModel;
049    import java.awt.image.DataBuffer;
050    import java.awt.image.Raster;
051    import java.awt.image.WritableRaster;
052    import java.io.BufferedReader;
053    import java.io.File;
054    import java.io.FileOutputStream;
055    import java.io.FileReader;
056    import java.io.IOException;
057    import java.io.PrintStream;
058    import java.util.ArrayList;
059    import java.util.Arrays;
060    import java.util.Hashtable;
061    import java.util.List;
062    import java.util.StringTokenizer;
063    
064    import org.deegree.datatypes.values.Interval;
065    import org.deegree.datatypes.values.TypedLiteral;
066    import org.deegree.datatypes.values.Values;
067    import org.deegree.framework.util.ConvenienceFileFilter;
068    import org.deegree.framework.util.ImageUtils;
069    import org.deegree.io.quadtree.IndexException;
070    import org.deegree.io.quadtree.MemPointQuadtree;
071    import org.deegree.io.quadtree.Quadtree;
072    import org.deegree.model.coverage.grid.WorldFile;
073    import org.deegree.model.spatialschema.Envelope;
074    import org.deegree.model.spatialschema.GeometryFactory;
075    import org.deegree.model.spatialschema.Point;
076    import org.deegree.processing.raster.interpolation.DataTuple;
077    import org.deegree.processing.raster.interpolation.InterpolationException;
078    import org.deegree.processing.raster.interpolation.InverseDistanceToPower;
079    
080    /**
081     * This class converts geodata and special values from a simple text file format to a .tiff file
082     * format. The values are written as 32 bit float values. The <code>main</code> method should be
083     * used to utilise this class as a command line tool.
084     * 
085     * 
086     * @version $Revision: 9346 $
087     * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
088     * @author last edited by: $Author: apoth $
089     * 
090     * @version 1.0. $Revision: 9346 $, $Date: 2007-12-27 17:39:07 +0100 (Do, 27 Dez 2007) $
091     * 
092     * @since 2.0
093     */
094    public class Text2Tiff {
095    
096        // parameters
097        private int columnNumber = 0;
098    
099        private double resolution = 0;
100    
101        private String columnName = null;
102    
103        private List<String> inputFilenames = new ArrayList<String>();
104    
105        private String outputFilename = null;
106    
107        private boolean readHeader = false;
108    
109        private boolean oracle = false;
110    
111        private Envelope boundingBox = null;
112    
113        private boolean interpolate = false;
114    
115        private boolean use32Bits = false;
116    
117        // data
118        private BufferedReader in;
119    
120        private Raster raster;
121    
122        private Quadtree quadtree;
123    
124        private BufferedImage image;
125    
126        private int imageWidth;
127    
128        private int imageHeight;
129    
130        private DataBuffer buffer;
131    
132        private float offset = 0;
133    
134        // interpolating options
135        private double interpolatePower = 2;
136    
137        private int interpolateMinData = 5;
138    
139        private int interpolateMaxData = 20;
140    
141        private double interpolateNoValue = 0;
142    
143        private double interpolateRadiusX = 2;
144    
145        private double interpolateRadiusY = 2;
146    
147        private double interpolateRadiusIncreaseX = 0;
148    
149        private double interpolateRadiusIncreaseY = 0;
150    
151        private Values ignoreValues = null;
152    
153        /**
154         * The only constructor, called usually by the main method with command line arguments.
155         * 
156         * @param args
157         */
158        public Text2Tiff( String[] args ) {
159            if ( args.length < 3 ) {
160                printUsage( "Not enough arguments." );
161            }
162    
163            parseArgs( args );
164    
165            // check for consistency
166            if ( ( columnName != null ) && !readHeader ) {
167                printUsage( "If a column name is given, I have to read the header!" );
168            }
169    
170            if ( inputFilenames.size() == 0 ) {
171                printUsage( "No input filename given." );
172            }
173    
174            if ( outputFilename == null ) {
175                printUsage( "No output filename given." );
176            }
177    
178            if ( columnName == null && columnNumber == 0 ) {
179                printUsage( "No column specified." );
180            }
181    
182            if ( !readHeader ) {
183                --columnNumber;
184            }
185        }
186    
187        private void parseArgs( String[] args ) {
188            List<Interval> intervals = new ArrayList<Interval>();
189    
190            // parse options
191            try {
192                for ( int i = 0; i < ( args.length - 1 ); ++i ) {
193                    if ( args[i].equals( "--image-type" ) ) {
194                        use32Bits = args[i + 1].equals( "32" );
195                        ++i;
196                    } else if ( args[i].equals( "--offset" ) ) {
197                        offset = Float.parseFloat( args[i + 1] );
198                        ++i;
199                    } else if ( args[i].equals( "--image-width" ) ) {
200                        imageWidth = Integer.parseInt( args[i + 1] );
201                        ++i;
202                    } else if ( args[i].equals( "--image-height" ) ) {
203                        imageHeight = Integer.parseInt( args[i + 1] );
204                        ++i;
205                    } else if ( args[i].equals( "-c" ) || args[i].equals( "--column-number" ) ) {
206                        columnNumber = Integer.parseInt( args[i + 1] );
207                        ++i;
208                    } else if ( args[i].equals( "-h" ) || args[i].equals( "--no-read-header" ) ) {
209                        readHeader = false;
210                    } else if ( args[i].equals( "-o" ) || args[i].equals( "--oracle" ) ) {
211                        oracle = true;
212                    } else if ( args[i].equals( "+h" ) || args[i].equals( "--read-header" ) ) {
213                        readHeader = true;
214                    } else if ( args[i].equals( "-cn" ) || args[i].equals( "--column-name" ) ) {
215                        columnName = args[i + 1];
216                        ++i;
217                    } else if ( args[i].equals( "-r" ) || args[i].equals( "--resolution" ) ) {
218                        resolution = Double.parseDouble( args[i + 1] );
219                        ++i;
220                    } else if ( args[i].equals( "-i" ) || args[i].equals( "--interpolate" ) ) {
221                        interpolate = true;
222                    } else if ( args[i].equals( "--interpolate-power" ) ) {
223                        interpolatePower = Double.parseDouble( args[i + 1] );
224                        ++i;
225                    } else if ( args[i].equals( "--interpolate-min-data" ) ) {
226                        interpolateMinData = Integer.parseInt( args[i + 1] );
227                        ++i;
228                    } else if ( args[i].equals( "--interpolate-max-data" ) ) {
229                        interpolateMaxData = Integer.parseInt( args[i + 1] );
230                        ++i;
231                    } else if ( args[i].equals( "--interpolate-no-value" ) ) {
232                        interpolateNoValue = Double.parseDouble( args[i + 1] );
233                        ++i;
234                    } else if ( args[i].equals( "--interpolate-radius-x" ) ) {
235                        interpolateRadiusX = Double.parseDouble( args[i + 1] );
236                        ++i;
237                    } else if ( args[i].equals( "--interpolate-radius-y" ) ) {
238                        interpolateRadiusY = Double.parseDouble( args[i + 1] );
239                        ++i;
240                    } else if ( args[i].equals( "--interpolate-radius-increase-x" ) ) {
241                        interpolateRadiusIncreaseX = Double.parseDouble( args[i + 1] );
242                        ++i;
243                    } else if ( args[i].equals( "--interpolate-radius-increase-y" ) ) {
244                        interpolateRadiusIncreaseY = Double.parseDouble( args[i + 1] );
245                        ++i;
246                    } else if ( args[i].equals( "--interpolate-ignore-range" ) ) {
247                        TypedLiteral min = new TypedLiteral( args[i + 1], null );
248                        TypedLiteral max = new TypedLiteral( args[i + 2], null );
249                        Interval interval = new Interval( min, max, null, null, null );
250                        intervals.add( interval );
251                        i += 2;
252                    } else if ( args[i].equals( "--help" ) ) {
253                        printUsage( null );
254                    } else if ( args[i].equals( "-help" ) ) {
255                        printUsage( null );
256                    } else {
257                        File file = new File( args[i] );
258                        if ( file.isDirectory() ) {
259                            File[] files = file.listFiles( new ConvenienceFileFilter( false, "XYZ,TXT" ) );
260                            for ( int j = 0; j < files.length; j++ ) {
261                                inputFilenames.add( files[j].getAbsolutePath() );
262                            }
263                        } else {
264                            inputFilenames.add( args[i] );
265                        }
266                    }
267    
268                }
269            } catch ( NumberFormatException nfe ) {
270                printUsage( "Illegal argument, number expected." );
271            }
272    
273            // get file names
274            outputFilename = args[args.length - 1];
275            if ( intervals.size() != 0 ) {
276                ignoreValues = new Values( intervals.toArray( new Interval[intervals.size()] ), null, null );
277            }
278        }
279    
280        // reads the first line
281        private void readHeader()
282                                throws IOException {
283            if ( !readHeader ) {
284                return;
285            }
286    
287            String s = in.readLine();
288    
289            columnNumber = 0;
290    
291            // get the right index for the column
292            if ( columnName != null ) {
293                StringTokenizer tok = new StringTokenizer( s );
294                while ( tok.hasMoreTokens() ) {
295                    String t = tok.nextToken();
296                    if ( t.equals( columnName ) ) {
297                        break;
298                    }
299                    ++columnNumber;
300                }
301            } else {
302                --columnNumber;
303            }
304        }
305    
306        // reads all data into the array lists
307        private ArrayList<DataTuple> readValues( String filename )
308                                throws IOException, NumberFormatException {
309    
310            readHeader();
311    
312            File file = new File( filename );
313            int size = (int) ( file.length() / 30 );
314    
315            ArrayList<DataTuple> values = new ArrayList<DataTuple>( size );
316            BufferedReader in = new BufferedReader( new FileReader( filename ) );
317            int counter = 0;
318            while ( in.ready() ) {
319                StringTokenizer tokenizer = new StringTokenizer( in.readLine() );
320                int idx = 0;
321                double x = 0;
322                double y = 0;
323                while ( tokenizer.hasMoreTokens() ) {
324                    if ( idx == 0 ) {
325                        x = Double.parseDouble( tokenizer.nextToken() );
326                    } else if ( idx == 1 ) {
327                        y = Double.parseDouble( tokenizer.nextToken() );
328                    } else if ( idx == columnNumber ) {
329                        values.add( new DataTuple( x, y, Double.parseDouble( tokenizer.nextToken() ) ) );
330                        break;
331                    } else
332                        tokenizer.nextToken();
333                    ++idx;
334                }
335                if ( ++counter % 10000 == 0 ) {
336                    System.out.print( "Read " + counter / 1000 + " thousand lines.\r" );
337                }
338            }
339            System.out.println();
340            in.close();
341    
342            return values;
343        }
344    
345        // calculate resolution and bbox
346        private void preprocessFiles()
347                                throws IOException {
348            double minx = Double.MAX_VALUE;
349            double miny = Double.MAX_VALUE;
350            double maxx = Double.MIN_VALUE;
351            double maxy = Double.MIN_VALUE;
352            boolean calcResolution = ( resolution == 0 );
353            if ( imageWidth != 0 && imageHeight != 0 ) {
354                calcResolution = false;
355            }
356    
357            if ( calcResolution ) {
358                resolution = Double.MAX_VALUE;
359            }
360    
361            for ( String filename : inputFilenames ) {
362                System.out.println( "Reading file " + filename );
363                ArrayList<DataTuple> values = readValues( filename );
364    
365                // Collections.sort( values );
366    
367                double[] ys = null;
368                DataTuple prev = null;
369                double cur;
370                if ( calcResolution ) {
371                    ys = new double[values.size()];
372                    prev = values.get( 0 );
373                    cur = 0;
374                }
375    
376                for ( int i = 0; i < values.size(); ++i ) {
377                    DataTuple tuple = values.get( i );
378    
379                    if ( maxx < tuple.x ) {
380                        maxx = tuple.x;
381                    }
382                    if ( maxy < tuple.y ) {
383                        maxy = tuple.y;
384                    }
385                    if ( minx > tuple.x ) {
386                        minx = tuple.x;
387                    }
388                    if ( miny > tuple.y ) {
389                        miny = tuple.y;
390                    }
391    
392                    if ( calcResolution ) {
393                        cur = Math.abs( tuple.x - prev.x );
394                        if ( ( cur != 0 ) && ( resolution > cur ) ) {
395                            resolution = cur;
396                        }
397                        ys[i] = tuple.y;
398                        prev = tuple;
399                    }
400                }
401    
402                if ( calcResolution ) {
403                    Arrays.sort( ys );
404    
405                    for ( int i = 0; i < ys.length - 1; ++i ) {
406                        cur = Math.abs( ys[i] - ys[i + 1] );
407                        if ( cur != 0 && cur < resolution ) {
408                            resolution = cur;
409                        }
410                    }
411                }
412            }
413    
414            System.out.println( "Covered area:" );
415            System.out.println( minx + " - " + maxx );
416            System.out.println( miny + " - " + maxy );
417    
418            boundingBox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null );
419    
420            if ( !calcResolution && resolution == 0 ) {
421                resolution = Math.abs( ( maxy - miny ) / ( imageHeight ) );
422                double h = Math.abs( ( maxx - minx ) / ( imageWidth ) );
423                if ( h < resolution ) {
424                    resolution = h;
425                }
426            }
427            if ( imageWidth == 0 && imageHeight == 0 ) {
428                imageWidth = (int) ( boundingBox.getWidth() / resolution ) + 1;
429                imageHeight = (int) ( boundingBox.getHeight() / resolution ) + 1;
430            }
431    
432            System.gc();
433    
434            System.out.println( "Resolution: " + resolution );
435    
436        }
437    
438        // creates the buffered image with the right size
439        private void createImage() {
440    
441            ColorModel ccm;
442    
443            if ( use32Bits ) {
444                image = new BufferedImage( imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB );
445            } else {
446                ccm = new ComponentColorModel( ColorSpace.getInstance( ColorSpace.CS_GRAY ), null, false, false,
447                                               BufferedImage.OPAQUE, DataBuffer.TYPE_USHORT );
448                WritableRaster wr = ccm.createCompatibleWritableRaster( imageWidth, imageHeight );
449    
450                image = new BufferedImage( ccm, wr, false, new Hashtable<Object, Object>() );
451            }
452    
453            raster = image.getData();
454    
455            buffer = raster.getDataBuffer();
456    
457        }
458    
459        // calculates the index of the desired position (in regard to a DataBuffer of a Raster)
460        private int calculatePosition( double x, double y ) {
461    
462            double tmp = ( x - boundingBox.getMin().getX() ) / resolution;
463    
464            double ypos = imageHeight - ( ( y - boundingBox.getMin().getY() ) / resolution ) - 1;
465            return (int) Math.round( tmp + ( ypos * imageWidth ) );
466    
467        }
468    
469        // inserts all values into the image
470        private void insertValue( double x, double y, double val ) {
471    
472            int pos = Math.abs( calculatePosition( x, y ) );
473            if ( use32Bits ) {
474                buffer.setElem( pos, Float.floatToIntBits( ( (float) val ) + offset ) );
475            } else {
476                buffer.setElem( pos, (int) Math.round( ( ( val + offset ) * 10 ) ) );
477            }
478    
479        }
480    
481        // creates the worldfile, depends on minimum values (call after createImage)
482        private void writeWorldfile()
483                                throws IOException {
484            if ( oracle ) {
485                PrintStream out = new PrintStream( new FileOutputStream( outputFilename + ".tfw" ) );
486                out.println( resolution );
487                out.println( "0.0" );
488                out.println( "0.0" );
489                out.println( -resolution );
490                if ( oracle ) {
491                    out.println( boundingBox.getMin().getX() - resolution / 2 );
492                } else {
493                    out.println( boundingBox.getMin().getX() );
494                }
495                if ( oracle ) {
496                    out.println( boundingBox.getMax().getY() + resolution / 2 );
497                } else {
498                    out.println( boundingBox.getMax().getY() );
499                }
500                out.println();
501            } else {
502                WorldFile wf = new WorldFile( resolution, -resolution, 0, 0, boundingBox );
503                WorldFile.writeWorldFile( wf, outputFilename );
504            }
505        }
506    
507        private void buildQuadtree()
508                                throws IOException, IndexException {
509            for ( String filename : inputFilenames ) {
510                readHeader();
511    
512                BufferedReader in = new BufferedReader( new FileReader( filename ) );
513                int counter = 0;
514                while ( in.ready() ) {
515                    StringTokenizer tokenizer = new StringTokenizer( in.readLine() );
516                    int idx = 0;
517                    double x = 0;
518                    double y = 0;
519                    while ( tokenizer.hasMoreTokens() ) {
520                        if ( idx == 0 ) {
521                            x = Double.parseDouble( tokenizer.nextToken() );
522                        } else if ( idx == 1 ) {
523                            y = Double.parseDouble( tokenizer.nextToken() );
524                        } else if ( idx == columnNumber ) {
525                            Point point = GeometryFactory.createPoint( x, y, null );
526                            quadtree.insert( new DataTuple( x, y, Double.parseDouble( tokenizer.nextToken() ) ), point );
527                            break;
528                        } else
529                            tokenizer.nextToken();
530                        ++idx;
531                    }
532                    if ( ++counter % 10000 == 0 ) {
533                        System.out.print( "Read " + counter / 1000 + " thousand lines.\r" );
534                    }
535                }
536                in.close();
537                System.out.println();
538    
539            }
540    
541        }
542    
543        /**
544         * This method executes all steps that are required to transform the text file into a tiff file.
545         * 
546         */
547        private void transform() {
548            try {
549                preprocessFiles();
550    
551                quadtree = new MemPointQuadtree( boundingBox );
552    
553                buildQuadtree();
554    
555                createImage();
556    
557                interpolate();
558    
559                image.setData( raster );
560    
561                System.out.println( "Writing output files..." );
562                ImageUtils.saveImage( image, new File( outputFilename + ".tif" ), 1 );
563                writeWorldfile();
564                System.out.println( "Done." );
565                // testOutput();
566            } catch ( IOException ioe ) {
567                System.out.println( "Could not read or write a file, reason:" );
568                ioe.printStackTrace();
569                System.exit( 0 );
570            } catch ( NumberFormatException nfe ) {
571                System.out.println( "A number could not be parsed correctly. Reason: " );
572                nfe.printStackTrace();
573                System.exit( 0 );
574            } catch ( InterpolationException e ) {
575                System.out.println( "Could not interpolate missing values. Reason: " );
576                e.printStackTrace();
577                System.exit( 0 );
578            } catch ( IndexException e ) {
579                System.out.println( "Could not build Quadtree. Reason: " );
580                e.printStackTrace();
581                System.exit( 0 );
582            }
583        }
584    
585        private void interpolate()
586                                throws InterpolationException {
587    
588            InverseDistanceToPower interpolator = new InverseDistanceToPower( quadtree, ignoreValues, interpolateRadiusX,
589                                                                              interpolateRadiusY, 0, interpolateMinData,
590                                                                              interpolateMaxData, interpolateNoValue,
591                                                                              interpolateRadiusIncreaseX,
592                                                                              interpolateRadiusIncreaseY, interpolatePower );
593    
594            double minx = boundingBox.getMin().getX();
595            double miny = boundingBox.getMin().getY();
596    
597            int count = imageWidth * imageHeight;
598    
599            int counter = 0;
600    
601            int interpolatedCounter = 0;
602    
603            for ( int xipos = 0; xipos < imageWidth; ++xipos ) {
604                for ( int yipos = 0; yipos < imageHeight; ++yipos ) {
605                    double xpos = minx + resolution * xipos;
606                    double ypos = miny + resolution * yipos;
607    
608                    Envelope env = GeometryFactory.createEnvelope( xpos - 0.01, ypos - 0.01, xpos + 0.01, ypos + 0.01, null );
609    
610                    try {
611                        List<?> list = quadtree.query( env );
612                        double val = 0;
613                        if ( list.size() == 0 ) {
614                            if ( interpolate ) {
615                                val = interpolator.calcInterpolatedValue( xpos, ypos, interpolateRadiusX,
616                                                                          interpolateRadiusY );
617                                ++interpolatedCounter;
618                            }
619                        } else {
620                            val = ( (DataTuple) list.get( 0 ) ).value;
621                        }
622    
623                        insertValue( xpos, ypos, val );
624    
625                    } catch ( IndexException e ) {
626                        throw new InterpolationException( "Could not interpolate.", e );
627                    }
628    
629                    if ( ++counter % 1000 == 0 ) {
630                        System.out.print( counter + "/" + count + "\r" );
631                    }
632                }
633            }
634    
635            System.out.println( counter + '/' + count + ", interpolated " + interpolatedCounter + " values" );
636        }
637    
638        /**
639         * Prints out an error message and general usage information of the tool.
640         * 
641         * @param error
642         *            an error message
643         */
644        public void printUsage( String error ) {
645            if ( error != null ) {
646                System.out.println( "Error: " + error );
647                System.out.println();
648            }
649            System.out.println( "java Text2Tiff <options> <inputfile[s]> <outputfile>" );
650            System.out.println( "Options:" );
651            System.out.println();
652            System.out.println( "    --help, -help:" );
653            System.out.println( "              print this message" );
654            System.out.println( "    --read-header, +h:" );
655            System.out.println( "    --no-read-header, -h:" );
656            System.out.println( "              Do/Do not read a header line in the input file. If enabled," );
657            System.out.println( "              one can specify column names instead of column numbers as" );
658            System.out.println( "              seen below. Default is no." );
659            System.out.println( "    --column-number n, -c n:" );
660            System.out.println( "              Use the column number n as input column. Must be specified" );
661            System.out.println( "              if column name below is not given. Counting starts with one," );
662            System.out.println( "              so '3' means actually the third column, not the fourth." );
663            System.out.println( "    --column-name n, -cn n:" );
664            System.out.println( "              Use the column named n as input column. Must be specified" );
665            System.out.println( "              if no column number is given." );
666            System.out.println( "    --oracle, -o:" );
667            System.out.println( "              Write the worldfile as Oracle expects it, using the outer" );
668            System.out.println( "              bounds of the bbox and not the point centers. Default is no." );
669            System.out.println( "    --image-type n:" );
670            System.out.println( "              n can be either 16 or 32. If n is 16, an image of type USHORT" );
671            System.out.println( "              will be created, and the values will be stored as shorts," );
672            System.out.println( "              multiplied by 10. If n is 32, the float values will be" );
673            System.out.println( "              stored in an image of type integer, as can be seen in" );
674            System.out.println( "              Java's Float.floatToIntBits() method. Default is 16." );
675            System.out.println( "    --image-width n:" );
676            System.out.println( "    --image-height n:" );
677            System.out.println( "              If set, an image of this size will be created. If not set" );
678            System.out.println( "              (default), the size will be determined by the resolution" );
679            System.out.println( "              either determined automatically or set by hand." );
680            System.out.println( "    --offset n:" );
681            System.out.println( "              use this as offset value for the result tiff. If result tiff" );
682            System.out.println( "              shall be a 16Bit tiff first offset will be added to value" );
683            System.out.println( "              before it will be multiplyed by 10" );
684            System.out.println( "    --resolution n, -r n:" );
685            System.out.println( "              Set geo resolution to n. If omitted, the resolution will be" );
686            System.out.println( "              set to the smallest value found in the input data." );
687            System.out.println( "    --interpolate, i:" );
688            System.out.println( "              Interpolate missing values. By default, no interpolation" );
689            System.out.println( "              will be performed." );
690            System.out.println( "    --interpolate-power n:" );
691            System.out.println( "              Interpolate using n as power. Default is " + interpolatePower + "." );
692            System.out.println( "    --interpolate-min-data n:" );
693            System.out.println( "              Interpolate only in the presence of n values within the search" );
694            System.out.println( "              radius. Default is " + interpolateMinData + "." );
695            System.out.println( "    --interpolate-max-data n:" );
696            System.out.println( "              Interpolate using a maximum of n values from within the search" );
697            System.out.println( "              radius. If more values are found, the n nearest will be used." );
698            System.out.println( "              Default is " + interpolateMaxData + "." );
699            System.out.println( "    --interpolate-no-value n:" );
700            System.out.println( "              The value to be used if insufficient data is in the search" );
701            System.out.println( "              radius. See also the radius-increase options below. Default" );
702            System.out.println( "              is " + interpolateNoValue + "." );
703            System.out.println( "    --interpolate-radius-x n:" );
704            System.out.println( "              Interpolate using a search radius of n in the x direction." );
705            System.out.println( "              Default is " + interpolateRadiusX + "." );
706            System.out.println( "    --interpolate-radius-y n:" );
707            System.out.println( "              Interpolate using a search radius of n in the y direction." );
708            System.out.println( "              Default is " + interpolateRadiusY + "." );
709            System.out.println( "    --interpolate-radius-increase-x n:" );
710            System.out.println( "              Automatically increase the x search radius by n if less than" );
711            System.out.println( "              --i-min-data values are found. If specified and not 0, the" );
712            System.out.println( "              value --i-no-value will be ignored. Default is 0." );
713            System.out.println( "    --interpolate-radius-increase-y n:" );
714            System.out.println( "              Automatically increase the y search radius by n if less than" );
715            System.out.println( "              --i-min-data values are found. If specified and not 0, the" );
716            System.out.println( "              value --i-no-value will be ignored. Default is 0." );
717            System.out.println( "    --interpolate-ignore-range min max:" );
718            System.out.println( "              Adds a new range of values to be ignored while interpolating." );
719            System.out.println();
720            System.out.println( ".tif/.tfw will be appended to the <outputfile> parameter." );
721            System.out.println();
722    
723            if ( error == null ) {
724                System.exit( 0 );
725            } else {
726                System.exit( 1 );
727            }
728        }
729    
730        /**
731         * This method is used from the command line.
732         * 
733         * @param args
734         *            the command line arguments.
735         */
736        public static void main( String[] args ) {
737            new Text2Tiff( args ).transform();
738        }
739    
740    }