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 4 : char *SanitizeSRS( const char *pszUserInput )
58 :
59 : {
60 : OGRSpatialReferenceH hSRS;
61 4 : char *pszResult = NULL;
62 :
63 4 : CPLErrorReset();
64 :
65 4 : hSRS = OSRNewSpatialReference( NULL );
66 4 : if( OSRSetFromUserInput( hSRS, pszUserInput ) == OGRERR_NONE )
67 4 : 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 4 : OSRDestroySpatialReference( hSRS );
77 :
78 4 : return pszResult;
79 : }
80 :
81 : /************************************************************************/
82 : /* main() */
83 : /************************************************************************/
84 :
85 9 : int main( int argc, char ** argv )
86 :
87 : {
88 9 : const char *pszSrcFilename = NULL;
89 9 : const char *pszDstFilename = NULL;
90 9 : int nOrder = 0;
91 : void *hTransformArg;
92 9 : GDALTransformerFunc pfnTransformer = NULL;
93 9 : int nGCPCount = 0;
94 9 : GDAL_GCP *pasGCPs = NULL;
95 9 : int bInverse = FALSE;
96 9 : 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 9 : 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 9 : GDALAllRegister();
108 9 : argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
109 9 : if( argc < 1 )
110 0 : exit( -argc );
111 :
112 : /* -------------------------------------------------------------------- */
113 : /* Parse arguments. */
114 : /* -------------------------------------------------------------------- */
115 : int i;
116 :
117 34 : for( i = 1; i < argc; i++ )
118 : {
119 26 : if( EQUAL(argv[i], "--utility_version") )
120 : {
121 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
122 1 : argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
123 1 : return 0;
124 : }
125 28 : else if( EQUAL(argv[i],"-t_srs") && i < argc-1 )
126 : {
127 3 : char *pszSRS = SanitizeSRS(argv[++i]);
128 3 : papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSRS );
129 3 : CPLFree( pszSRS );
130 : }
131 23 : else if( EQUAL(argv[i],"-s_srs") && i < argc-1 )
132 : {
133 1 : char *pszSRS = SanitizeSRS(argv[++i]);
134 1 : papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSRS );
135 1 : CPLFree( pszSRS );
136 : }
137 22 : else if( EQUAL(argv[i],"-order") && i < argc-1 )
138 : {
139 1 : nOrder = atoi(argv[++i]);
140 1 : papszTO = CSLSetNameValue( papszTO, "MAX_GCP_ORDER", argv[i] );
141 : }
142 20 : else if( EQUAL(argv[i],"-tps") )
143 : {
144 1 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" );
145 1 : nOrder = -1;
146 : }
147 19 : else if( EQUAL(argv[i],"-rpc") )
148 : {
149 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "RPC" );
150 : }
151 19 : else if( EQUAL(argv[i],"-geoloc") )
152 : {
153 0 : papszTO = CSLSetNameValue( papszTO, "METHOD", "GEOLOC_ARRAY" );
154 : }
155 19 : else if( EQUAL(argv[i],"-i") )
156 : {
157 1 : bInverse = TRUE;
158 : }
159 20 : else if( EQUAL(argv[i],"-to") && i < argc-1 )
160 : {
161 2 : papszTO = CSLAddString( papszTO, argv[++i] );
162 : }
163 28 : else if( EQUAL(argv[i],"-gcp") && i < argc - 4 )
164 : {
165 12 : char* endptr = NULL;
166 : /* -gcp pixel line easting northing [elev] */
167 :
168 12 : nGCPCount++;
169 : pasGCPs = (GDAL_GCP *)
170 12 : CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
171 12 : GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
172 :
173 12 : pasGCPs[nGCPCount-1].dfGCPPixel = atof(argv[++i]);
174 12 : pasGCPs[nGCPCount-1].dfGCPLine = atof(argv[++i]);
175 12 : pasGCPs[nGCPCount-1].dfGCPX = atof(argv[++i]);
176 12 : pasGCPs[nGCPCount-1].dfGCPY = atof(argv[++i]);
177 30 : if( argv[i+1] != NULL
178 18 : && (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 3 : if (endptr && *endptr == 0)
183 3 : pasGCPs[nGCPCount-1].dfGCPZ = atof(argv[++i]);
184 : }
185 :
186 : /* should set id and info? */
187 : }
188 :
189 4 : else if( argv[i][0] == '-' )
190 0 : Usage();
191 :
192 4 : else if( pszSrcFilename == NULL )
193 3 : pszSrcFilename = argv[i];
194 :
195 1 : else if( pszDstFilename == NULL )
196 1 : pszDstFilename = argv[i];
197 :
198 : else
199 0 : Usage();
200 : }
201 :
202 : /* -------------------------------------------------------------------- */
203 : /* Open src and destination file, if appropriate. */
204 : /* -------------------------------------------------------------------- */
205 8 : GDALDatasetH hSrcDS = NULL, hDstDS = NULL;
206 :
207 8 : if( pszSrcFilename != NULL )
208 : {
209 3 : hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
210 3 : if( hSrcDS == NULL )
211 0 : exit( 1 );
212 : }
213 :
214 8 : if( pszDstFilename != NULL )
215 : {
216 1 : hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly );
217 1 : if( hDstDS == NULL )
218 0 : exit( 1 );
219 : }
220 :
221 8 : 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 9 : if( nGCPCount != 0 && nOrder == -1 )
232 : {
233 1 : pfnTransformer = GDALTPSTransform;
234 : hTransformArg =
235 1 : GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE );
236 : }
237 7 : else if( nGCPCount != 0 )
238 : {
239 2 : pfnTransformer = GDALGCPTransform;
240 : hTransformArg =
241 2 : GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE );
242 : }
243 : else
244 : {
245 5 : pfnTransformer = GDALGenImgProjTransform;
246 : hTransformArg =
247 5 : GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO );
248 : }
249 :
250 8 : CSLDestroy( papszTO );
251 :
252 8 : if( hTransformArg == NULL )
253 : {
254 0 : exit( 1 );
255 : }
256 :
257 : /* -------------------------------------------------------------------- */
258 : /* Read points from stdin, transform and write to stdout. */
259 : /* -------------------------------------------------------------------- */
260 34 : while( !feof(stdin) )
261 : {
262 : char szLine[1024];
263 :
264 26 : if( fgets( szLine, sizeof(szLine)-1, stdin ) == NULL )
265 8 : break;
266 :
267 18 : char **papszTokens = CSLTokenizeString(szLine);
268 18 : double dfX, dfY, dfZ = 0.0;
269 18 : int bSuccess = TRUE;
270 :
271 18 : if( CSLCount(papszTokens) < 2 )
272 : {
273 0 : CSLDestroy(papszTokens);
274 0 : continue;
275 : }
276 :
277 18 : dfX = atof(papszTokens[0]);
278 18 : dfY = atof(papszTokens[1]);
279 18 : if( CSLCount(papszTokens) >= 3 )
280 3 : dfZ = atof(papszTokens[2]);
281 :
282 18 : if( pfnTransformer( hTransformArg, bInverse, 1,
283 : &dfX, &dfY, &dfZ, &bSuccess )
284 : && bSuccess )
285 : {
286 18 : printf( "%.15g %.15g %.15g\n", dfX, dfY, dfZ );
287 : }
288 : else
289 : {
290 0 : printf( "transformation failed.\n" );
291 : }
292 :
293 18 : CSLDestroy(papszTokens);
294 : }
295 :
296 9 : if( nGCPCount != 0 && nOrder == -1 )
297 : {
298 1 : GDALDestroyTPSTransformer(hTransformArg);
299 : }
300 7 : else if( nGCPCount != 0 )
301 : {
302 2 : GDALDestroyGCPTransformer(hTransformArg);
303 : }
304 : else
305 : {
306 5 : GDALDestroyGenImgProjTransformer(hTransformArg);
307 : }
308 :
309 8 : if (nGCPCount)
310 : {
311 3 : GDALDeinitGCPs( nGCPCount, pasGCPs );
312 3 : CPLFree( pasGCPs );
313 : }
314 :
315 8 : if (hSrcDS)
316 3 : GDALClose(hSrcDS);
317 :
318 8 : if (hDstDS)
319 1 : GDALClose(hDstDS);
320 :
321 8 : GDALDumpOpenDatasets( stderr );
322 8 : GDALDestroyDriverManager();
323 :
324 8 : CSLDestroy( argv );
325 :
326 8 : return 0;
327 : }
|