001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/tools/srs/PolynomialParameterCreator.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    
037    package org.deegree.tools.srs;
038    
039    import java.io.BufferedReader;
040    import java.io.File;
041    import java.io.FileReader;
042    import java.io.IOException;
043    import java.util.ArrayList;
044    import java.util.HashMap;
045    import java.util.LinkedList;
046    import java.util.List;
047    import java.util.Map;
048    
049    import javax.vecmath.Point3d;
050    
051    import org.deegree.crs.Identifiable;
052    import org.deegree.crs.transformations.polynomial.LeastSquareApproximation;
053    import org.deegree.crs.transformations.polynomial.PolynomialTransformation;
054    import org.deegree.framework.log.ILogger;
055    import org.deegree.framework.log.LoggerFactory;
056    import org.deegree.model.crs.CRSFactory;
057    import org.deegree.model.crs.CoordinateSystem;
058    import org.deegree.model.crs.UnknownCRSException;
059    
060    /**
061     * <code>PolynomialParameterCreator</code> allows for the calculation of a
062     *
063     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
064     *
065     * @author last edited by: $Author: mschneider $
066     *
067     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
068     *
069     */
070    public class PolynomialParameterCreator {
071    
072        private static ILogger LOG = LoggerFactory.getLogger( PolynomialParameterCreator.class );
073    
074        /**
075         * Simple constructor which reads coordinate pairs from a different files (using the separator) and stores them in a
076         * list.
077         *
078         * @param sourceFile
079         *            to read the source coordinates from
080         * @param targetFile
081         *            to read the target coordinates from.
082         *
083         * @param seperator
084         *            which separates the coordinates (e.g. ; or , )
085         * @param source
086         *            the source crs in which the first read points are given
087         * @param target
088         *            the target crs in which the read points are defined.
089         * @param transformationClass
090         *            to use
091         * @param order
092         *            of the polynomial.
093         * @throws IOException
094         *             if the file could not be read.
095         */
096        public PolynomialParameterCreator( File sourceFile, File targetFile, String seperator, CoordinateSystem source,
097                                           CoordinateSystem target, String transformationClass, final int order )
098                                throws IOException {
099    
100            List<Point3d> from = readFromFile( sourceFile, source.getDimension(), seperator );
101            List<Point3d> to = readFromFile( targetFile, target.getDimension(), seperator );
102            if ( from.size() != to.size() ) {
103                LOG.logError( "The number of coordinates in the from file( " + from.size()
104                              + ") differ from the targetFile (" + to.size() + ") , this maynot be!" );
105                System.exit( 1 );
106            }
107            if ( transformationClass == null || "".equals( transformationClass.trim() ) ) {
108                throw new IllegalArgumentException( "The transformation class may not be null" );
109            }
110    
111            PolynomialTransformation transform = null;
112            List<Double> params = new LinkedList<Double>();
113            // 48.01903, 0.002305167, -0.0011897635, 1.0666529E-5, -8.303933E-6, 4.4940844E-6, -3.8565862E-11,
114            // 5.0593762E-11, -2.230412E-11, 2.968846E-12
115            // 3.0465062, -1.5860682E-4, 4.3924665E-4, 1.2747373E-6, -1.103672E-6, 5.936716E-7, -2.3854978E-12,
116            // 3.0211528E-12, -1.2788576E-12, 1.4953932E-13
117    
118            params.add( new Double( 1 ) );
119            if ( "leastsquares".equals( transformationClass.toLowerCase().trim() ) ) {
120                transform = new LeastSquareApproximation( params, params, source.getCRS(), target.getCRS(), 1, 1,
121                                                          new Identifiable( "Tmp ID" ) );
122            }
123            if ( transform != null ) {
124                float[][] calculatedParams = transform.createVariables( from, to, order );
125                StringBuilder sb = new StringBuilder();
126                for ( int i = 0; i < calculatedParams.length; ++i ) {
127                    String t = "crs:" + ( i == 0 ? "x" : "y" ) + "Parameters>";
128                    sb.append( "<" ).append( t );
129                    for ( int y = 0; y < calculatedParams[i].length; ++y ) {
130                        sb.append( calculatedParams[i][y] );
131                        if ( ( y + 1 ) < calculatedParams[i].length ) {
132                            sb.append( " " );
133                        }
134                    }
135                    sb.append( "</" ).append( t ).append( "\n" );
136                }
137                LOG.logInfo( "Resulted params:\n" + sb.toString() );
138            }
139        }
140    
141        private List<Point3d> readFromFile( File f, int dim, String seperator )
142                                throws IOException {
143            LOG.logInfo( "Trying to read reference points from file: " + f );
144            List<Point3d> result = new ArrayList<Point3d>();
145            BufferedReader br = new BufferedReader( new FileReader( f ) );
146            String coords = br.readLine();
147            int lineCount = 1;
148            while ( coords != null ) {
149                if ( !coords.startsWith( "#" ) ) {
150                    String[] coordinates = coords.split( seperator );
151                    if ( coordinates.length != dim ) {
152                        LOG.logWarning( lineCount
153                                        + ") Each line must contain the number of coordinates fitting the dimension of crs ("
154                                        + dim + ") seperated by a '" + seperator + "'." );
155                    } else {
156                        Point3d coord = new Point3d();
157                        coord.x = Double.parseDouble( coordinates[0].replace( ",", "." ) );
158                        coord.y = Double.parseDouble( coordinates[1].replace( ",", "." ) );
159                        if ( dim == 3 ) {
160                            coord.z = Double.parseDouble( coordinates[2].replace( ",", "." ) );
161                        }
162                        result.add( coord );
163                    }
164                }
165                lineCount++;
166                coords = br.readLine();
167            }
168            br.close();
169            return result;
170    
171        }
172    
173        /**
174         * a starter method to test the quality of projections.
175         *
176         * @param args
177         */
178        public static void main( String[] args ) {
179            if ( args.length == 0 ) {
180                outputHelp();
181            }
182            Map<String, String> params = new HashMap<String, String>( 5 );
183            for ( int i = 0; i < args.length; i++ ) {
184                String arg = args[i];
185                if ( arg != null && !"".equals( arg.trim() ) ) {
186                    arg = arg.trim();
187                    if ( arg.equalsIgnoreCase( "-?" ) || arg.equalsIgnoreCase( "-h" ) ) {
188                        outputHelp();
189                    } else {
190                        if ( i + 1 < args.length ) {
191                            String val = args[++i];
192                            if ( val != null ) {
193                                params.put( arg, val.trim() );
194                            } else {
195                                System.out.println( "Invalid value for parameter: " + arg );
196                            }
197                        } else {
198                            System.out.println( "No value for parameter: " + arg );
199                        }
200                    }
201                }
202            }
203            String sourceFile = params.get( "-sourceFile" );
204            if ( sourceFile == null || "".equals( sourceFile.trim() ) ) {
205                LOG.logError( "No file with reference points in the source CRS given (-sourceFile parameter)" );
206                System.exit( 1 );
207            }
208    
209            String sourceCRS = params.get( "-sourceCRS" );
210            if ( sourceCRS == null || "".equals( sourceCRS.trim() ) ) {
211                LOG.logError( "No source CRS given (-sourceCRS parameter)" );
212                System.exit( 1 );
213            }
214            String targetCRS = params.get( "-targetCRS" );
215            if ( targetCRS == null || "".equals( targetCRS.trim() ) ) {
216                LOG.logError( "No target CRS given (-targetCRS parameter)" );
217                System.exit( 1 );
218            }
219    
220            String targetFile = params.get( "-targetFile" );
221            if ( targetFile == null || "".equals( targetFile.trim() ) ) {
222                LOG.logError( "No file with reference points in the target CRS given (-targetFile parameter)" );
223                System.exit( 1 );
224            }
225    
226            String polyOrder = params.get( "-order" );
227            int order = 0;
228            if ( polyOrder == null || "".equals( polyOrder.trim() ) ) {
229                LOG.logError( "No polynomial order (-order parameter) given. Not continuing." );
230                System.exit( 1 );
231            }
232            order = Integer.parseInt( polyOrder );
233    
234            String transformClass = params.get( "-transformClass" );
235            if ( polyOrder == null || "".equals( polyOrder.trim() ) ) {
236                LOG.logError( "No transformation class (-transformClass parameter) given. Not continuing." );
237                System.exit( 1 );
238            }
239    
240            String coordSep = params.get( "-coordSep" );
241            if ( coordSep == null || "".equals( coordSep ) ) {
242                LOG.logInfo( "No coordinates separator given (-coordSep parameter), therefore using ' ' (a space) as separator" );
243                coordSep = " ";
244            }
245    
246            LOG.logInfo( "Trying to convert coordinates from: " + sourceCRS + " to: " + targetCRS );
247    
248            try {
249                CoordinateSystem source = CRSFactory.create( sourceCRS );
250                CoordinateSystem target = CRSFactory.create( targetCRS );
251                new PolynomialParameterCreator( new File( sourceFile ), new File( targetFile ), coordSep, source, target,
252                                                transformClass, order );
253    
254            } catch ( IOException e ) {
255                LOG.logError( e.getMessage(), e );
256            } catch ( UnknownCRSException e ) {
257                LOG.logError( e.getMessage(), e );
258            }
259    
260        }
261    
262        private static void outputHelp() {
263            StringBuilder sb = new StringBuilder();
264            sb.append( "The PolynomialParamter program can be used to create the polynomial variables to approximate a given\n" );
265            sb.append( "function, which is defined by two list of coordinates.\n" );
266            sb.append( "Following parameters are supported:\n" );
267            sb.append( "-sourceFile the /path/of/the_source_crs_reference_points -file\n" );
268            sb.append( "-srcCRS the name of the source crs, e.g. EPSG:4326.\n" );
269            sb.append( "-targetCRS the name of the target crs, e.g. EPSG:31467.\n" );
270            sb.append( "-targetFile the /path/to/the_target_crs_reference_points.\n" );
271            sb.append( "-order the polynomial order to calculate the values for.\n" );
272            sb.append( "-transformClass the simple name of the transformation polynomial at the moment following values are supported:\n" );
273            sb.append( "\t - leastsquares\n" );
274            sb.append( "[-coordSep] separator of between the coords in the file(s), e.g. ; or ' ', if omitted a space is assumed.\n" );
275            sb.append( "-?|-h output this text\n" );
276            System.out.println( sb.toString() );
277            System.exit( 1 );
278        }
279    
280    }