    001    /*----------------------------------------------------------------------------
    002     This file is part of deegree, http://deegree.org/
    003     Copyright (C) 2001-2009 by:
    004       Department of Geography, University of Bonn
    005     and
    006       lat/lon GmbH
    007
    008     This library is free software; you can redistribute it and/or modify it under
    009     the terms of the GNU Lesser General Public License as published by the Free
    010     Software Foundation; either version 2.1 of the License, or (at your option)
    011     any later version.
    012     This library is distributed in the hope that it will be useful, but WITHOUT
    013     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    014     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    015     details.
    016     You should have received a copy of the GNU Lesser General Public License
    017     along with this library; if not, write to the Free Software Foundation, Inc.,
    018     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    019
    020     Contact information:
    021
    022     lat/lon GmbH
    023     Aennchenstr. 19, 53177 Bonn
    024     Germany
    025     http://lat-lon.de/
    026
    027     Department of Geography, University of Bonn
    028     Prof. Dr. Klaus Greve
    029     Postfach 1147, 53001 Bonn
    030     Germany
    031     http://www.geographie.uni-bonn.de/deegree/
    032
    033     e-mail: info@deegree.org
    034    ----------------------------------------------------------------------------*/
    035
    036    package org.deegree.tools.srs;
    037
    038    import java.io.BufferedReader;
    039    import java.io.FileReader;
    040    import java.io.IOException;
    041    import java.util.HashMap;
    042    import java.util.LinkedList;
    043    import java.util.List;
    044    import java.util.Map;
    045
    046    import javax.vecmath.Point3d;
    047
    048    import org.deegree.crs.components.Unit;
    049    import org.deegree.framework.log.ILogger;
    050    import org.deegree.framework.log.LoggerFactory;
    051    import org.deegree.model.crs.CRSFactory;
    052    import org.deegree.model.crs.CRSTransformationException;
    053    import org.deegree.model.crs.CoordinateSystem;
    054    import org.deegree.model.crs.GeoTransformer;
    055    import org.deegree.model.crs.UnknownCRSException;
    056    import org.deegree.model.spatialschema.GeometryFactory;
    057    import org.deegree.model.spatialschema.Point;
    058
    059    /**
    060     * The <code>DemoCRSTransform</code> is a sa(i)mple application for using deegree coordinate systems and their
    061     * transformations.
    062     *
    063     *
    064     * @version $Revision: 18195 $
    065     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    066     * @author last edited by: $Author: mschneider $
    067     *
    068     * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    069     */
    070    public class DemoCRSTransform {
    071
    072        private static ILogger LOG = LoggerFactory.getLogger( DemoCRSTransform.class );
    073
    074        private CoordinateSystem sourceCRS;
    075
    076        private CoordinateSystem targetCRS;
    077
    078        /**
    079         * Construct a demo crs with following coordinate systems.
    080         *
    081         * @param sourceCRS
    082         * @param targetCRS
    083         */
    084        public DemoCRSTransform( CoordinateSystem sourceCRS, CoordinateSystem targetCRS ) {
    085            this.sourceCRS = sourceCRS;
    086            this.targetCRS = targetCRS;
    087        }
    088
    089        /**
    090         * This method transforms the given coordinate (in the sourceCRS) into a coordinate of the targetCRS and back.
    091         *
    092         * @param coordinate
    093         *            to be transformed.
    094         * @param withInverse
    095         *            true if the inverse has to be calculated.
    096         */
    097        public void doTransform( Point3d coordinate, boolean withInverse ) {
    098            GeoTransformer gt = new GeoTransformer( targetCRS );
    099
    100            // point to transform
    101            Point point = GeometryFactory.createPoint( coordinate.x, coordinate.y, coordinate.z, sourceCRS );
    102
    103            outputPoint( "The original point in crs: " + sourceCRS.getIdentifier() + ": ", point, sourceCRS );
    104            Point pp = null;
    105            try {
    106                pp = (Point) gt.transform( point );
    107            } catch ( IllegalArgumentException e ) {
    108                LOG.logError( e.getMessage(), e );
    109            } catch ( CRSTransformationException e ) {
    110                LOG.logError( e.getMessage(), e );
    111            }
    112            outputPoint( "The transformed point in crs: " + targetCRS.getIdentifier() + ": ", pp, targetCRS );
    113            if ( withInverse ) {
    114
    115                // transform back to source CRS
    116                gt = new GeoTransformer( sourceCRS );
    117                try {
    118                    point = (Point) gt.transform( pp );
    119                } catch ( IllegalArgumentException e ) {
    120                    LOG.logError( e.getMessage(), e );
    121                } catch ( CRSTransformationException e ) {
    122                    LOG.logError( e.getMessage(), e );
    123                }
    124                outputPoint( "The inversed transformed point in crs: " + sourceCRS.getIdentifier() + ": ", point, sourceCRS );
    125            }
    126
    127        }
    128
    129        private void outputPoint( String outputString, Point coord, CoordinateSystem currentCRS ) {
    130            double resultX = coord.getX();
    131            double resultY = coord.getY();
    132            double resultZ = coord.getZ();
    133            Unit[] allUnits = currentCRS.getAxisUnits();
    134            System.out.println( outputString + resultX + allUnits[0] + ", " + resultY + allUnits[1]
    135                                + ( ( currentCRS.getDimension() == 3 ) ? ", " + resultZ + allUnits[2] : "" ) );
    136
    137        }
    138
    139        /**
    140         * a starter method to transform a given point or a serie of points read from a file.
    141         *
    142         * @param args
    143         * @throws UnknownCRSException
    144         * @throws IOException
    145         *             if the buffered reader could not read from the file
    146         */
    147        public static void main( String[] args )
    148                                throws UnknownCRSException, IOException {
    149            Map<String, String> params = new HashMap<String, String>( 5 );
    150            for ( int i = 0; i < args.length; i++ ) {
    151                String arg = args[i];
    152                if ( arg != null && !"".equals( arg.trim() ) ) {
    153                    arg = arg.trim().toLowerCase();
    154                    if ( arg.equalsIgnoreCase( "-?" ) || arg.equalsIgnoreCase( "-h" ) ) {
    155                        outputHelp();
    156                    } else {
    157                        if ( i + 1 < args.length ) {
    158                            String val = args[++i];
    159                            if ( val != null ) {
    160                                params.put( arg, val.trim() );
    161                            } else {
    162                                LOG.logInfo( "Invalid value for parameter: " + arg );
    163                            }
    164                        } else {
    165                            LOG.logInfo( "No value for parameter: " + arg );
    166                        }
    167                    }
    168                }
    169            }
    170
    171            /**
    172             * add crs and point here if using eclipse to start.
    173             */
    174            // String sourceCRS = "EPSG:25832";
    175            // String targetCRS = "EPSG:31466";
    176            // String coord = "370766.738,5685588.661";
    177
    178            String sourceCRS = "";
    179            String targetCRS = "";
    180            String coord = "";
    181
    182            if ( "".equals( sourceCRS ) ) {
    183                sourceCRS = params.get( "-sourcecrs" );
    184                if ( sourceCRS == null || "".equals( sourceCRS.trim() ) ) {
    185                    LOG.logError( "No source CRS given (-sourceCRS parameter)" );
    186                    System.exit( 1 );
    187                }
    188            }
    189            if ( "".equals( targetCRS ) ) {
    190                targetCRS = params.get( "-targetcrs" );
    191                if ( targetCRS == null || "".equals( targetCRS.trim() ) ) {
    192                    LOG.logError( "No target CRS given (-targetCRS parameter)" );
    193                    System.exit( 1 );
    194                }
    195            }
    196
    197            CoordinateSystem source = CRSFactory.create( sourceCRS );
    198            CoordinateSystem target = CRSFactory.create( targetCRS );
    199
    200            DemoCRSTransform demo = new DemoCRSTransform( source, target );
    201
    202            String sourceFile = params.get( "-sourcefile" );
    203            if ( "".equals( coord ) && sourceFile != null && !"".equals( sourceFile.trim() ) ) {
    204                String coordSep = params.get( "-coordsep" );
    205                if ( coordSep == null || "".equals( coordSep ) ) {
    206                    LOG.logInfo( "No coordinates separator given (-coordSep parameter), therefore using ' ' (a space) as separator" );
    207                    coordSep = " ";
    208                }
    209                BufferedReader br = new BufferedReader( new FileReader( sourceFile ) );
    210                String coords = br.readLine();
    211
    212                int lineCount = 1;
    213                final int sourceDim = source.getDimension();
    214                List<Point3d> coordinateList = new LinkedList<Point3d>();
    215                while ( coords != null ) {
    216                    if ( !coords.startsWith( "#" ) ) {
    217                        String[] coordinates = coords.split( coordSep );
    218                        if ( coordinates.length != sourceDim ) {
    219                            LOG.logError( lineCount
    220                                          + ") Each line must contain the number of coordinates fitting the dimension of the source crs ("
    221                                          + sourceDim + ") seperated by a '" + coordSep + "'." );
    222                        } else {
    223                            Point3d from = new Point3d();
    224                            from.x = Double.parseDouble( coordinates[0].replace( ",", "." ) );
    225                            from.y = Double.parseDouble( coordinates[1].replace( ",", "." ) );
    226                            if ( sourceDim == 3 ) {
    227                                from.z = Double.parseDouble( coordinates[2].replace( ",", "." ) );
    228                            }
    229                            coordinateList.add( from );
    230                        }
    231                    }
    232                    coords = br.readLine();
    233                    lineCount++;
    234                }
    235                if ( coordinateList.size() == 0 ) {
    236                    LOG.logError( "No valid points found in file: " + sourceFile );
    237                } else {
    238                    long time = System.currentTimeMillis();
    239                    for ( Point3d c : coordinateList ) {
    240                        demo.doTransform( c, false );
    241                    }
    242                    System.out.println( "Transformation took: " + ( ( System.currentTimeMillis() - time ) / 1000. )
    243                                        + " seconds" );
    244                }
    245            } else {
    246                if ( "".equals( coord ) ) {
    247                    coord = params.get( "-coord" );
    248                    if ( coord == null || "".equals( coord.trim() ) ) {
    249                        LOG.logError( "No coordinate(s) to transform, use the -coord or the -sourceFile parameter to define a coordinate (list)." );
    250                        System.exit( 1 );
    251                    }
    252                }
    253                String[] splitter = coord.split( "," );
    254                if ( splitter == null || splitter.length == 1 || splitter.length > 3 ) {
    255                    LOG.logError( "A coordinate must be comma separated and may only have two or three ordinates e.g. -coord \"3.1415 , 2.7182\"" );
    256                    System.exit( 1 );
    257                }
    258                double x = Double.parseDouble( splitter[0] );
    259                double y = Double.parseDouble( splitter[1] );
    260                double z = ( splitter.length == 3 ) ? Double.parseDouble( splitter[2] ) : 0;
    261                demo.doTransform( new Point3d( x, y, z ), true );
    262            }
    263        }
    264
    265        private static void outputHelp() {
    266            StringBuilder sb = new StringBuilder();
    267            sb.append( "The DemoCRSTransform program can be used to transform a single given coordinate or a set of coordinates read from a file.\n" );
    268            sb.append( "Following parameters are supported:\n" );
    269            sb.append( "-sourceCRS (required) the name of the source crs, e.g. EPSG:4326.\n" );
    270            sb.append( "-targetCRS (required) the name of the target crs, e.g. EPSG:31467.\n" );
    271            sb.append( "[-coord] parameter defining a coordinate (comma separated) in the source crs, e.g. '3.1415 , 2.7182' \n" );
    272            sb.append( "[-sourceFile] a /path/of/a_list_of_coordinates.txt containing a list of coordinate pairs/triples. If supplied the -coordSep (the separator between the ordinates will also be evalutated)..\n" );
    273            sb.append( "[-coordSep] (only valid with -sourceFile) defining a separator between the coords in the file e.g. a ';' or ',' if omitted a space is assumed.\n" );
    274            sb.append( "-?|-h output this text\n" );
    275            System.out.println( sb.toString() );
    276            System.exit( 1 );
    277        }
    278
    279    }