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(const char* pszErrorMsg = NULL)
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 :
51 0 : if( pszErrorMsg != NULL )
52 0 : fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
53 :
54 0 : exit( 1 );
55 : }
56 :
57 : /************************************************************************/
58 : /* SanitizeSRS */
59 : /************************************************************************/
60 :
61 4 : char *SanitizeSRS( const char *pszUserInput )
62 :
63 : {
64 : OGRSpatialReferenceH hSRS;
65 4 : char *pszResult = NULL;
66 :
67 4 : CPLErrorReset();
68 :
69 4 : hSRS = OSRNewSpatialReference( NULL );
70 4 : if( OSRSetFromUserInput( hSRS, pszUserInput ) == OGRERR_NONE )
71 4 : OSRExportToWkt( hSRS, &pszResult );
72 : else
73 : {
74 : CPLError( CE_Failure, CPLE_AppDefined,
75 : "Translating source or target SRS failed:\n%s",
76 0 : pszUserInput );
77 0 : exit( 1 );
78 : }
79 :
80 4 : OSRDestroySpatialReference( hSRS );
81 :
82 4 : return pszResult;
83 : }
84 :
85 : /************************************************************************/
86 : /* main() */
87 : /************************************************************************/
88 :
89 : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
90 : do { if (i + nExtraArg >= argc) \
91 : Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
92 :
93 9 : int main( int argc, char ** argv )
94 :
95 : {
96 9 : const char *pszSrcFilename = NULL;
97 9 : const char *pszDstFilename = NULL;
98 9 : int nOrder = 0;
99 : void *hTransformArg;
100 9 : GDALTransformerFunc pfnTransformer = NULL;
101 9 : int nGCPCount = 0;
102 9 : GDAL_GCP *pasGCPs = NULL;
103 9 : int bInverse = FALSE;
104 9 : char **papszTO = NULL;
105 :
106 : /* Check that we are running against at least GDAL 1.5 */
107 : /* Note to developers : if we use newer API, please change the requirement */
108 9 : if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500)
109 : {
110 : fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
111 0 : "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
112 0 : exit(1);
113 : }
114 :
115 9 : GDALAllRegister();
116 9 : argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
117 9 : if( argc < 1 )
118 0 : exit( -argc );
119 :
120 : /* -------------------------------------------------------------------- */
121 : /* Parse arguments. */
122 : /* -------------------------------------------------------------------- */
123 : int i;
124 :
125 34 : for( i = 1; i < argc; i++ )
126 : {
127 26 : if( EQUAL(argv[i], "--utility_version") )
128 : {
129 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
130 1 : argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
131 1 : return 0;
132 : }
133 25 : else if( EQUAL(argv[i],"--help") )
134 0 : Usage();
135 25 : else if( EQUAL(argv[i],"-t_srs") )
136 : {
137 3 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
138 3 : char *pszSRS = SanitizeSRS(argv[++i]);
139 3 : papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSRS );
140 3 : CPLFree( pszSRS );
141 : }
142 22 : else if( EQUAL(argv[i],"-s_srs") )
143 : {
144 1 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
145 1 : char *pszSRS = SanitizeSRS(argv[++i]);
146 1 : papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSRS );
147 1 : CPLFree( pszSRS );
148 : }
149 21 : else if( EQUAL(argv[i],"-order") )
150 : {
151 1 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
152 1 : nOrder = atoi(argv[++i]);
153 1 : papszTO = CSLSetNameValue( papszTO, "MAX_GCP_ORDER", argv[i] );
154 : }
155 20 : else if( EQUAL(argv[i],"-tps") )
156 : {
157 1 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" );
158 1 : nOrder = -1;
159 : }
160 19 : else if( EQUAL(argv[i],"-rpc") )
161 : {
162 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "RPC" );
163 : }
164 19 : else if( EQUAL(argv[i],"-geoloc") )
165 : {
166 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GEOLOC_ARRAY" );
167 : }
168 19 : else if( EQUAL(argv[i],"-i") )
169 : {
170 1 : bInverse = TRUE;
171 : }
172 18 : else if( EQUAL(argv[i],"-to") )
173 : {
174 2 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
175 2 : papszTO = CSLAddString( papszTO, argv[++i] );
176 : }
177 16 : else if( EQUAL(argv[i],"-gcp") )
178 : {
179 12 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
180 12 : char* endptr = NULL;
181 : /* -gcp pixel line easting northing [elev] */
182 :
183 12 : nGCPCount++;
184 : pasGCPs = (GDAL_GCP *)
185 12 : CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
186 12 : GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
187 :
188 12 : pasGCPs[nGCPCount-1].dfGCPPixel = atof(argv[++i]);
189 12 : pasGCPs[nGCPCount-1].dfGCPLine = atof(argv[++i]);
190 12 : pasGCPs[nGCPCount-1].dfGCPX = atof(argv[++i]);
191 12 : pasGCPs[nGCPCount-1].dfGCPY = atof(argv[++i]);
192 30 : if( argv[i+1] != NULL
193 18 : && (CPLStrtod(argv[i+1], &endptr) != 0.0 || argv[i+1][0] == '0') )
194 : {
195 : /* Check that last argument is really a number and not a filename */
196 : /* looking like a number (see ticket #863) */
197 3 : if (endptr && *endptr == 0)
198 3 : pasGCPs[nGCPCount-1].dfGCPZ = atof(argv[++i]);
199 : }
200 :
201 : /* should set id and info? */
202 : }
203 :
204 4 : else if( argv[i][0] == '-' )
205 0 : Usage(CPLSPrintf("Unkown option name '%s'", argv[i]));
206 :
207 4 : else if( pszSrcFilename == NULL )
208 3 : pszSrcFilename = argv[i];
209 :
210 1 : else if( pszDstFilename == NULL )
211 1 : pszDstFilename = argv[i];
212 :
213 : else
214 0 : Usage("Too many command options.");
215 : }
216 :
217 : /* -------------------------------------------------------------------- */
218 : /* Open src and destination file, if appropriate. */
219 : /* -------------------------------------------------------------------- */
220 8 : GDALDatasetH hSrcDS = NULL, hDstDS = NULL;
221 :
222 8 : if( pszSrcFilename != NULL )
223 : {
224 3 : hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
225 3 : if( hSrcDS == NULL )
226 0 : exit( 1 );
227 : }
228 :
229 8 : if( pszDstFilename != NULL )
230 : {
231 1 : hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly );
232 1 : if( hDstDS == NULL )
233 0 : exit( 1 );
234 : }
235 :
236 8 : if( hSrcDS != NULL && nGCPCount > 0 )
237 : {
238 0 : fprintf( stderr, "Commandline GCPs and input file specified, specify one or the other.\n" );
239 0 : exit( 1 );
240 : }
241 :
242 : /* -------------------------------------------------------------------- */
243 : /* Create a transformation object from the source to */
244 : /* destination coordinate system. */
245 : /* -------------------------------------------------------------------- */
246 9 : if( nGCPCount != 0 && nOrder == -1 )
247 : {
248 1 : pfnTransformer = GDALTPSTransform;
249 : hTransformArg =
250 1 : GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE );
251 : }
252 7 : else if( nGCPCount != 0 )
253 : {
254 2 : pfnTransformer = GDALGCPTransform;
255 : hTransformArg =
256 2 : GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE );
257 : }
258 : else
259 : {
260 5 : pfnTransformer = GDALGenImgProjTransform;
261 : hTransformArg =
262 5 : GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO );
263 : }
264 :
265 8 : CSLDestroy( papszTO );
266 :
267 8 : if( hTransformArg == NULL )
268 : {
269 0 : exit( 1 );
270 : }
271 :
272 : /* -------------------------------------------------------------------- */
273 : /* Read points from stdin, transform and write to stdout. */
274 : /* -------------------------------------------------------------------- */
275 34 : while( !feof(stdin) )
276 : {
277 : char szLine[1024];
278 :
279 26 : if( fgets( szLine, sizeof(szLine)-1, stdin ) == NULL )
280 8 : break;
281 :
282 18 : char **papszTokens = CSLTokenizeString(szLine);
283 18 : double dfX, dfY, dfZ = 0.0;
284 18 : int bSuccess = TRUE;
285 :
286 18 : if( CSLCount(papszTokens) < 2 )
287 : {
288 0 : CSLDestroy(papszTokens);
289 0 : continue;
290 : }
291 :
292 18 : dfX = atof(papszTokens[0]);
293 18 : dfY = atof(papszTokens[1]);
294 18 : if( CSLCount(papszTokens) >= 3 )
295 3 : dfZ = atof(papszTokens[2]);
296 :
297 18 : if( pfnTransformer( hTransformArg, bInverse, 1,
298 : &dfX, &dfY, &dfZ, &bSuccess )
299 : && bSuccess )
300 : {
301 18 : printf( "%.15g %.15g %.15g\n", dfX, dfY, dfZ );
302 : }
303 : else
304 : {
305 0 : printf( "transformation failed.\n" );
306 : }
307 :
308 18 : CSLDestroy(papszTokens);
309 : }
310 :
311 9 : if( nGCPCount != 0 && nOrder == -1 )
312 : {
313 1 : GDALDestroyTPSTransformer(hTransformArg);
314 : }
315 7 : else if( nGCPCount != 0 )
316 : {
317 2 : GDALDestroyGCPTransformer(hTransformArg);
318 : }
319 : else
320 : {
321 5 : GDALDestroyGenImgProjTransformer(hTransformArg);
322 : }
323 :
324 8 : if (nGCPCount)
325 : {
326 3 : GDALDeinitGCPs( nGCPCount, pasGCPs );
327 3 : CPLFree( pasGCPs );
328 : }
329 :
330 8 : if (hSrcDS)
331 3 : GDALClose(hSrcDS);
332 :
333 8 : if (hDstDS)
334 1 : GDALClose(hDstDS);
335 :
336 8 : GDALDumpOpenDatasets( stderr );
337 8 : GDALDestroyDriverManager();
338 :
339 8 : CSLDestroy( argv );
340 :
341 8 : return 0;
342 : }
|