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 }