1 : /******************************************************************************
2 : * $Id: gdalwarp.cpp 12380 2007-10-12 17:35:00Z rouault $
3 : *
4 : * Project: GDAL
5 : * Purpose: Commandline point transformer.
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdalwarper.h"
31 : #include "cpl_string.h"
32 : #include "ogr_spatialref.h"
33 :
34 : CPL_CVSID("$Id: gdaltransform.cpp 12380 2007-10-12 17:35:00Z rouault $");
35 :
36 : /************************************************************************/
37 : /* Usage() */
38 : /************************************************************************/
39 :
40 0 : static void Usage()
41 :
42 : {
43 : printf(
44 : "Usage: gdaltransform [--help-general]\n"
45 : " [-i] [-s_srs srs_def] [-t_srs srs_def] [-to \"NAME=VALUE\"]\n"
46 : " [-order n] [-tps] [-rpc] [-geoloc] \n"
47 : " [-gcp pixel line easting northing [elevation]]*\n"
48 : " [srcfile [dstfile]]\n"
49 0 : "\n" );
50 0 : exit( 1 );
51 : }
52 :
53 : /************************************************************************/
54 : /* SanitizeSRS */
55 : /************************************************************************/
56 :
57 8 : char *SanitizeSRS( const char *pszUserInput )
58 :
59 : {
60 : OGRSpatialReferenceH hSRS;
61 8 : char *pszResult = NULL;
62 :
63 8 : CPLErrorReset();
64 :
65 8 : hSRS = OSRNewSpatialReference( NULL );
66 8 : if( OSRSetFromUserInput( hSRS, pszUserInput ) == OGRERR_NONE )
67 8 : OSRExportToWkt( hSRS, &pszResult );
68 : else
69 : {
70 : CPLError( CE_Failure, CPLE_AppDefined,
71 : "Translating source or target SRS failed:\n%s",
72 0 : pszUserInput );
73 0 : exit( 1 );
74 : }
75 :
76 8 : OSRDestroySpatialReference( hSRS );
77 :
78 8 : return pszResult;
79 : }
80 :
81 : /************************************************************************/
82 : /* main() */
83 : /************************************************************************/
84 :
85 18 : int main( int argc, char ** argv )
86 :
87 : {
88 18 : const char *pszSrcFilename = NULL;
89 18 : const char *pszDstFilename = NULL;
90 18 : int nOrder = 0;
91 : void *hTransformArg;
92 18 : GDALTransformerFunc pfnTransformer = NULL;
93 18 : int nGCPCount = 0;
94 18 : GDAL_GCP *pasGCPs = NULL;
95 18 : int bInverse = FALSE;
96 18 : char **papszTO = NULL;
97 :
98 : /* Check that we are running against at least GDAL 1.5 */
99 : /* Note to developers : if we use newer API, please change the requirement */
100 18 : if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500)
101 : {
102 : fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
103 0 : "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
104 0 : exit(1);
105 : }
106 :
107 18 : GDALAllRegister();
108 18 : argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
109 18 : if( argc < 1 )
110 0 : exit( -argc );
111 :
112 : /* -------------------------------------------------------------------- */
113 : /* Parse arguments. */
114 : /* -------------------------------------------------------------------- */
115 : int i;
116 :
117 68 : for( i = 1; i < argc; i++ )
118 : {
119 52 : if( EQUAL(argv[i], "--utility_version") )
120 : {
121 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
122 2 : argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
123 2 : return 0;
124 : }
125 56 : else if( EQUAL(argv[i],"-t_srs") && i < argc-1 )
126 : {
127 6 : char *pszSRS = SanitizeSRS(argv[++i]);
128 6 : papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSRS );
129 6 : CPLFree( pszSRS );
130 : }
131 46 : else if( EQUAL(argv[i],"-s_srs") && i < argc-1 )
132 : {
133 2 : char *pszSRS = SanitizeSRS(argv[++i]);
134 2 : papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSRS );
135 2 : CPLFree( pszSRS );
136 : }
137 44 : else if( EQUAL(argv[i],"-order") && i < argc-1 )
138 : {
139 2 : nOrder = atoi(argv[++i]);
140 2 : papszTO = CSLSetNameValue( papszTO, "MAX_GCP_ORDER", argv[i] );
141 : }
142 40 : else if( EQUAL(argv[i],"-tps") )
143 : {
144 2 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" );
145 2 : nOrder = -1;
146 : }
147 38 : else if( EQUAL(argv[i],"-rpc") )
148 : {
149 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "RPC" );
150 : }
151 38 : else if( EQUAL(argv[i],"-geoloc") )
152 : {
153 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GEOLOC_ARRAY" );
154 : }
155 38 : else if( EQUAL(argv[i],"-i") )
156 : {
157 2 : bInverse = TRUE;
158 : }
159 40 : else if( EQUAL(argv[i],"-to") && i < argc-1 )
160 : {
161 4 : papszTO = CSLAddString( papszTO, argv[++i] );
162 : }
163 56 : else if( EQUAL(argv[i],"-gcp") && i < argc - 4 )
164 : {
165 24 : char* endptr = NULL;
166 : /* -gcp pixel line easting northing [elev] */
167 :
168 24 : nGCPCount++;
169 : pasGCPs = (GDAL_GCP *)
170 24 : CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
171 24 : GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
172 :
173 24 : pasGCPs[nGCPCount-1].dfGCPPixel = atof(argv[++i]);
174 24 : pasGCPs[nGCPCount-1].dfGCPLine = atof(argv[++i]);
175 24 : pasGCPs[nGCPCount-1].dfGCPX = atof(argv[++i]);
176 24 : pasGCPs[nGCPCount-1].dfGCPY = atof(argv[++i]);
177 60 : if( argv[i+1] != NULL
178 36 : && (CPLStrtod(argv[i+1], &endptr) != 0.0 || argv[i+1][0] == '0') )
179 : {
180 : /* Check that last argument is really a number and not a filename */
181 : /* looking like a number (see ticket #863) */
182 6 : if (endptr && *endptr == 0)
183 6 : pasGCPs[nGCPCount-1].dfGCPZ = atof(argv[++i]);
184 : }
185 :
186 : /* should set id and info? */
187 : }
188 :
189 8 : else if( argv[i][0] == '-' )
190 0 : Usage();
191 :
192 8 : else if( pszSrcFilename == NULL )
193 6 : pszSrcFilename = argv[i];
194 :
195 2 : else if( pszDstFilename == NULL )
196 2 : pszDstFilename = argv[i];
197 :
198 : else
199 0 : Usage();
200 : }
201 :
202 : /* -------------------------------------------------------------------- */
203 : /* Open src and destination file, if appropriate. */
204 : /* -------------------------------------------------------------------- */
205 16 : GDALDatasetH hSrcDS = NULL, hDstDS = NULL;
206 :
207 16 : if( pszSrcFilename != NULL )
208 : {
209 6 : hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
210 6 : if( hSrcDS == NULL )
211 0 : exit( 1 );
212 : }
213 :
214 16 : if( pszDstFilename != NULL )
215 : {
216 2 : hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly );
217 2 : if( hDstDS == NULL )
218 0 : exit( 1 );
219 : }
220 :
221 16 : if( hSrcDS != NULL && nGCPCount > 0 )
222 : {
223 0 : fprintf( stderr, "Commandline GCPs and input file specified, specify one or the other.\n" );
224 0 : exit( 1 );
225 : }
226 :
227 : /* -------------------------------------------------------------------- */
228 : /* Create a transformation object from the source to */
229 : /* destination coordinate system. */
230 : /* -------------------------------------------------------------------- */
231 18 : if( nGCPCount != 0 && nOrder == -1 )
232 : {
233 2 : pfnTransformer = GDALTPSTransform;
234 : hTransformArg =
235 2 : GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE );
236 : }
237 14 : else if( nGCPCount != 0 )
238 : {
239 4 : pfnTransformer = GDALGCPTransform;
240 : hTransformArg =
241 4 : GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE );
242 : }
243 : else
244 : {
245 10 : pfnTransformer = GDALGenImgProjTransform;
246 : hTransformArg =
247 10 : GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO );
248 : }
249 :
250 16 : CSLDestroy( papszTO );
251 :
252 16 : if( hTransformArg == NULL )
253 : {
254 0 : exit( 1 );
255 : }
256 :
257 : /* -------------------------------------------------------------------- */
258 : /* Read points from stdin, transform and write to stdout. */
259 : /* -------------------------------------------------------------------- */
260 68 : while( !feof(stdin) )
261 : {
262 : char szLine[1024];
263 :
264 52 : if( fgets( szLine, sizeof(szLine)-1, stdin ) == NULL )
265 16 : break;
266 :
267 36 : char **papszTokens = CSLTokenizeString(szLine);
268 36 : double dfX, dfY, dfZ = 0.0;
269 36 : int bSuccess = TRUE;
270 :
271 36 : if( CSLCount(papszTokens) < 2 )
272 : {
273 0 : CSLDestroy(papszTokens);
274 0 : continue;
275 : }
276 :
277 36 : dfX = atof(papszTokens[0]);
278 36 : dfY = atof(papszTokens[1]);
279 36 : if( CSLCount(papszTokens) >= 3 )
280 6 : dfZ = atof(papszTokens[2]);
281 :
282 36 : if( pfnTransformer( hTransformArg, bInverse, 1,
283 : &dfX, &dfY, &dfZ, &bSuccess )
284 : && bSuccess )
285 : {
286 36 : printf( "%.15g %.15g %.15g\n", dfX, dfY, dfZ );
287 : }
288 : else
289 : {
290 0 : printf( "transformation failed.\n" );
291 : }
292 :
293 36 : CSLDestroy(papszTokens);
294 : }
295 :
296 18 : if( nGCPCount != 0 && nOrder == -1 )
297 : {
298 2 : GDALDestroyTPSTransformer(hTransformArg);
299 : }
300 14 : else if( nGCPCount != 0 )
301 : {
302 4 : GDALDestroyGCPTransformer(hTransformArg);
303 : }
304 : else
305 : {
306 10 : GDALDestroyGenImgProjTransformer(hTransformArg);
307 : }
308 :
309 16 : if (nGCPCount)
310 : {
311 6 : GDALDeinitGCPs( nGCPCount, pasGCPs );
312 6 : CPLFree( pasGCPs );
313 : }
314 :
315 16 : if (hSrcDS)
316 6 : GDALClose(hSrcDS);
317 :
318 16 : if (hDstDS)
319 2 : GDALClose(hDstDS);
320 :
321 16 : GDALDumpOpenDatasets( stderr );
322 16 : GDALDestroyDriverManager();
323 :
324 16 : CSLDestroy( argv );
325 :
326 16 : return 0;
327 : }
|