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