1 : /******************************************************************************
2 : * $Id: ogrinfo.cpp 23119 2011-09-24 16:15:21Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Simple client for viewing OGR driver data.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
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 "ogr_api.h"
31 : #include "ogrsf_frmts.h"
32 : #include "ogr_p.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 : #include "cpl_multiproc.h"
36 :
37 : CPL_CVSID("$Id: ogrinfo.cpp 23119 2011-09-24 16:15:21Z rouault $");
38 :
39 : int bReadOnly = FALSE;
40 : int bVerbose = TRUE;
41 : int bSummaryOnly = FALSE;
42 : int nFetchFID = OGRNullFID;
43 : char** papszOptions = NULL;
44 :
45 : static void Usage();
46 :
47 : static void ReportOnLayer( OGRLayer *, const char *, OGRGeometry * );
48 :
49 : /************************************************************************/
50 : /* main() */
51 : /************************************************************************/
52 :
53 42 : int main( int nArgc, char ** papszArgv )
54 :
55 : {
56 42 : const char *pszWHERE = NULL;
57 42 : const char *pszDataSource = NULL;
58 42 : char **papszLayers = NULL;
59 42 : OGRGeometry *poSpatialFilter = NULL;
60 42 : int nRepeatCount = 1, bAllLayers = FALSE;
61 42 : const char *pszSQLStatement = NULL;
62 42 : const char *pszDialect = NULL;
63 42 : int nRet = 0;
64 :
65 : /* Check strict compilation and runtime library version as we use C++ API */
66 42 : if (! GDAL_CHECK_VERSION(papszArgv[0]))
67 0 : exit(1);
68 : /* -------------------------------------------------------------------- */
69 : /* Register format(s). */
70 : /* -------------------------------------------------------------------- */
71 42 : OGRRegisterAll();
72 :
73 : /* -------------------------------------------------------------------- */
74 : /* Processing command line arguments. */
75 : /* -------------------------------------------------------------------- */
76 42 : nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
77 :
78 42 : if( nArgc < 1 )
79 0 : exit( -nArgc );
80 :
81 134 : for( int iArg = 1; iArg < nArgc; iArg++ )
82 : {
83 94 : if( EQUAL(papszArgv[iArg], "--utility_version") )
84 : {
85 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
86 2 : papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
87 2 : return 0;
88 : }
89 92 : else if( EQUAL(papszArgv[iArg],"-ro") )
90 4 : bReadOnly = TRUE;
91 88 : else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet"))
92 0 : bVerbose = FALSE;
93 90 : else if( EQUAL(papszArgv[iArg],"-fid") && iArg < nArgc-1 )
94 2 : nFetchFID = atoi(papszArgv[++iArg]);
95 96 : else if( EQUAL(papszArgv[iArg],"-spat")
96 2 : && papszArgv[iArg+1] != NULL
97 2 : && papszArgv[iArg+2] != NULL
98 2 : && papszArgv[iArg+3] != NULL
99 2 : && papszArgv[iArg+4] != NULL )
100 : {
101 2 : OGRLinearRing oRing;
102 :
103 2 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
104 2 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
105 2 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
106 2 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
107 2 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
108 :
109 2 : poSpatialFilter = new OGRPolygon();
110 2 : ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
111 2 : iArg += 4;
112 : }
113 86 : else if( EQUAL(papszArgv[iArg],"-where") && papszArgv[iArg+1] != NULL )
114 : {
115 2 : pszWHERE = papszArgv[++iArg];
116 : }
117 100 : else if( EQUAL(papszArgv[iArg],"-sql") && papszArgv[iArg+1] != NULL )
118 : {
119 18 : pszSQLStatement = papszArgv[++iArg];
120 : }
121 64 : else if( EQUAL(papszArgv[iArg],"-dialect")
122 0 : && papszArgv[iArg+1] != NULL )
123 : {
124 0 : pszDialect = papszArgv[++iArg];
125 : }
126 64 : else if( EQUAL(papszArgv[iArg],"-rc") && papszArgv[iArg+1] != NULL )
127 : {
128 0 : nRepeatCount = atoi(papszArgv[++iArg]);
129 : }
130 64 : else if( EQUAL(papszArgv[iArg],"-al") )
131 : {
132 4 : bAllLayers = TRUE;
133 : }
134 120 : else if( EQUAL(papszArgv[iArg],"-so")
135 60 : || EQUAL(papszArgv[iArg],"-summary") )
136 : {
137 0 : bSummaryOnly = TRUE;
138 : }
139 60 : else if( EQUALN(papszArgv[iArg],"-fields=", strlen("-fields=")) )
140 : {
141 2 : char* pszTemp = (char*)CPLMalloc(32 + strlen(papszArgv[iArg]));
142 2 : sprintf(pszTemp, "DISPLAY_FIELDS=%s", papszArgv[iArg] + strlen("-fields="));
143 2 : papszOptions = CSLAddString(papszOptions, pszTemp);
144 2 : CPLFree(pszTemp);
145 : }
146 58 : else if( EQUALN(papszArgv[iArg],"-geom=", strlen("-geom=")) )
147 : {
148 4 : char* pszTemp = (char*)CPLMalloc(32 + strlen(papszArgv[iArg]));
149 4 : sprintf(pszTemp, "DISPLAY_GEOMETRY=%s", papszArgv[iArg] + strlen("-geom="));
150 4 : papszOptions = CSLAddString(papszOptions, pszTemp);
151 4 : CPLFree(pszTemp);
152 : }
153 54 : else if( papszArgv[iArg][0] == '-' )
154 : {
155 0 : Usage();
156 : }
157 54 : else if( pszDataSource == NULL )
158 40 : pszDataSource = papszArgv[iArg];
159 : else
160 : {
161 14 : papszLayers = CSLAddString( papszLayers, papszArgv[iArg] );
162 14 : bAllLayers = FALSE;
163 : }
164 : }
165 :
166 40 : if( pszDataSource == NULL )
167 0 : Usage();
168 :
169 : /* -------------------------------------------------------------------- */
170 : /* Open data source. */
171 : /* -------------------------------------------------------------------- */
172 40 : OGRDataSource *poDS = NULL;
173 40 : OGRSFDriver *poDriver = NULL;
174 :
175 40 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, !bReadOnly, &poDriver );
176 40 : if( poDS == NULL && !bReadOnly )
177 : {
178 0 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, &poDriver );
179 0 : if( poDS != NULL && bVerbose )
180 : {
181 0 : printf( "Had to open data source read-only.\n" );
182 0 : bReadOnly = TRUE;
183 : }
184 : }
185 :
186 : /* -------------------------------------------------------------------- */
187 : /* Report failure */
188 : /* -------------------------------------------------------------------- */
189 40 : if( poDS == NULL )
190 : {
191 0 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
192 :
193 : printf( "FAILURE:\n"
194 : "Unable to open datasource `%s' with the following drivers.\n",
195 0 : pszDataSource );
196 :
197 0 : for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
198 : {
199 0 : printf( " -> %s\n", poR->GetDriver(iDriver)->GetName() );
200 : }
201 :
202 0 : nRet = 1;
203 0 : goto end;
204 : }
205 :
206 40 : CPLAssert( poDriver != NULL);
207 :
208 : /* -------------------------------------------------------------------- */
209 : /* Some information messages. */
210 : /* -------------------------------------------------------------------- */
211 40 : if( bVerbose )
212 : printf( "INFO: Open of `%s'\n"
213 : " using driver `%s' successful.\n",
214 40 : pszDataSource, poDriver->GetName() );
215 :
216 40 : if( bVerbose && !EQUAL(pszDataSource,poDS->GetName()) )
217 : {
218 : printf( "INFO: Internal data source name `%s'\n"
219 : " different from user name `%s'.\n",
220 2 : poDS->GetName(), pszDataSource );
221 : }
222 :
223 : /* -------------------------------------------------------------------- */
224 : /* Special case for -sql clause. No source layers required. */
225 : /* -------------------------------------------------------------------- */
226 40 : if( pszSQLStatement != NULL )
227 : {
228 18 : OGRLayer *poResultSet = NULL;
229 :
230 18 : nRepeatCount = 0; // skip layer reporting.
231 :
232 18 : if( CSLCount(papszLayers) > 0 )
233 0 : printf( "layer names ignored in combination with -sql.\n" );
234 :
235 : poResultSet = poDS->ExecuteSQL( pszSQLStatement, poSpatialFilter,
236 18 : pszDialect );
237 :
238 18 : if( poResultSet != NULL )
239 : {
240 2 : if( pszWHERE != NULL )
241 : {
242 0 : if (poResultSet->SetAttributeFilter( pszWHERE ) != OGRERR_NONE )
243 : {
244 0 : printf( "FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE );
245 0 : exit(1);
246 : }
247 : }
248 :
249 2 : ReportOnLayer( poResultSet, NULL, NULL );
250 2 : poDS->ReleaseResultSet( poResultSet );
251 : }
252 : }
253 :
254 40 : CPLDebug( "OGR", "GetLayerCount() = %d\n", poDS->GetLayerCount() );
255 :
256 62 : for( int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++ )
257 : {
258 22 : if ( CSLCount(papszLayers) == 0 )
259 : {
260 : /* -------------------------------------------------------------------- */
261 : /* Process each data source layer. */
262 : /* -------------------------------------------------------------------- */
263 16 : for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
264 : {
265 8 : OGRLayer *poLayer = poDS->GetLayer(iLayer);
266 :
267 8 : if( poLayer == NULL )
268 : {
269 : printf( "FAILURE: Couldn't fetch advertised layer %d!\n",
270 0 : iLayer );
271 0 : exit( 1 );
272 : }
273 :
274 8 : if (!bAllLayers)
275 : {
276 : printf( "%d: %s",
277 : iLayer+1,
278 4 : poLayer->GetName() );
279 :
280 4 : if( poLayer->GetGeomType() != wkbUnknown )
281 : printf( " (%s)",
282 : OGRGeometryTypeToName(
283 4 : poLayer->GetGeomType() ) );
284 :
285 4 : printf( "\n" );
286 : }
287 : else
288 : {
289 4 : if( iRepeat != 0 )
290 0 : poLayer->ResetReading();
291 :
292 4 : ReportOnLayer( poLayer, pszWHERE, poSpatialFilter );
293 : }
294 : }
295 : }
296 : else
297 : {
298 : /* -------------------------------------------------------------------- */
299 : /* Process specified data source layers. */
300 : /* -------------------------------------------------------------------- */
301 14 : char** papszIter = papszLayers;
302 28 : for( ; *papszIter != NULL; papszIter++ )
303 : {
304 14 : OGRLayer *poLayer = poDS->GetLayerByName(*papszIter);
305 :
306 14 : if( poLayer == NULL )
307 : {
308 : printf( "FAILURE: Couldn't fetch requested layer %s!\n",
309 0 : *papszIter );
310 0 : exit( 1 );
311 : }
312 :
313 14 : if( iRepeat != 0 )
314 0 : poLayer->ResetReading();
315 :
316 14 : ReportOnLayer( poLayer, pszWHERE, poSpatialFilter );
317 : }
318 : }
319 : }
320 :
321 : /* -------------------------------------------------------------------- */
322 : /* Close down. */
323 : /* -------------------------------------------------------------------- */
324 : end:
325 40 : CSLDestroy( papszArgv );
326 40 : CSLDestroy( papszLayers );
327 40 : CSLDestroy( papszOptions );
328 40 : OGRDataSource::DestroyDataSource( poDS );
329 40 : if (poSpatialFilter)
330 2 : OGRGeometryFactory::destroyGeometry( poSpatialFilter );
331 :
332 40 : OGRCleanupAll();
333 :
334 40 : return nRet;
335 : }
336 :
337 : /************************************************************************/
338 : /* Usage() */
339 : /************************************************************************/
340 :
341 0 : static void Usage()
342 :
343 : {
344 : printf( "Usage: ogrinfo [--help-general] [-ro] [-q] [-where restricted_where]\n"
345 : " [-spat xmin ymin xmax ymax] [-fid fid]\n"
346 : " [-sql statement] [-dialect sql_dialect] [-al] [-so] [-fields={YES/NO}]\n"
347 : " [-geom={YES/NO/SUMMARY}][--formats]\n"
348 0 : " datasource_name [layer [layer ...]]\n");
349 0 : exit( 1 );
350 : }
351 :
352 : /************************************************************************/
353 : /* ReportOnLayer() */
354 : /************************************************************************/
355 :
356 20 : static void ReportOnLayer( OGRLayer * poLayer, const char *pszWHERE,
357 : OGRGeometry *poSpatialFilter )
358 :
359 : {
360 20 : OGRFeatureDefn *poDefn = poLayer->GetLayerDefn();
361 :
362 : /* -------------------------------------------------------------------- */
363 : /* Set filters if provided. */
364 : /* -------------------------------------------------------------------- */
365 20 : if( pszWHERE != NULL )
366 : {
367 2 : if (poLayer->SetAttributeFilter( pszWHERE ) != OGRERR_NONE )
368 : {
369 0 : printf( "FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE );
370 0 : exit(1);
371 : }
372 : }
373 :
374 20 : if( poSpatialFilter != NULL )
375 2 : poLayer->SetSpatialFilter( poSpatialFilter );
376 :
377 : /* -------------------------------------------------------------------- */
378 : /* Report various overall information. */
379 : /* -------------------------------------------------------------------- */
380 20 : printf( "\n" );
381 :
382 20 : printf( "Layer name: %s\n", poLayer->GetName() );
383 :
384 20 : if( bVerbose )
385 : {
386 : printf( "Geometry: %s\n",
387 20 : OGRGeometryTypeToName( poLayer->GetGeomType() ) );
388 :
389 20 : printf( "Feature Count: %d\n", poLayer->GetFeatureCount() );
390 :
391 20 : OGREnvelope oExt;
392 20 : if (poLayer->GetExtent(&oExt, TRUE) == OGRERR_NONE)
393 : {
394 : printf("Extent: (%f, %f) - (%f, %f)\n",
395 20 : oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
396 : }
397 :
398 : char *pszWKT;
399 :
400 20 : if( poLayer->GetSpatialRef() == NULL )
401 0 : pszWKT = CPLStrdup( "(unknown)" );
402 : else
403 : {
404 20 : poLayer->GetSpatialRef()->exportToPrettyWkt( &pszWKT );
405 : }
406 :
407 20 : printf( "Layer SRS WKT:\n%s\n", pszWKT );
408 20 : CPLFree( pszWKT );
409 :
410 20 : if( strlen(poLayer->GetFIDColumn()) > 0 )
411 : printf( "FID Column = %s\n",
412 0 : poLayer->GetFIDColumn() );
413 :
414 20 : if( strlen(poLayer->GetGeometryColumn()) > 0 )
415 : printf( "Geometry Column = %s\n",
416 0 : poLayer->GetGeometryColumn() );
417 :
418 74 : for( int iAttr = 0; iAttr < poDefn->GetFieldCount(); iAttr++ )
419 : {
420 54 : OGRFieldDefn *poField = poDefn->GetFieldDefn( iAttr );
421 :
422 : printf( "%s: %s (%d.%d)\n",
423 : poField->GetNameRef(),
424 : poField->GetFieldTypeName( poField->GetType() ),
425 : poField->GetWidth(),
426 54 : poField->GetPrecision() );
427 : }
428 : }
429 :
430 : /* -------------------------------------------------------------------- */
431 : /* Read, and dump features. */
432 : /* -------------------------------------------------------------------- */
433 20 : OGRFeature *poFeature = NULL;
434 :
435 38 : if( nFetchFID == OGRNullFID && !bSummaryOnly )
436 : {
437 168 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
438 : {
439 132 : poFeature->DumpReadable( NULL, papszOptions );
440 132 : OGRFeature::DestroyFeature( poFeature );
441 : }
442 : }
443 2 : else if( nFetchFID != OGRNullFID )
444 : {
445 2 : poFeature = poLayer->GetFeature( nFetchFID );
446 2 : if( poFeature == NULL )
447 : {
448 : printf( "Unable to locate feature id %d on this layer.\n",
449 0 : nFetchFID );
450 : }
451 : else
452 : {
453 2 : poFeature->DumpReadable( NULL, papszOptions );
454 2 : OGRFeature::DestroyFeature( poFeature );
455 : }
456 : }
457 20 : }
|