2
#/******************************************************************************
3
# * $Id: gdalinfo.py 22986 2011-08-27 14:20:16Z rouault $
5
# * Project: GDAL Utilities
6
# * Purpose: Python port of Commandline application to list info about a file.
7
# * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
9
# * Port from gdalinfo.c whose author is Frank Warmerdam
11
# ******************************************************************************
12
# * Copyright (c) 2010, Even Rouault
13
# * Copyright (c) 1998, Frank Warmerdam
15
# * Permission is hereby granted, free of charge, to any person obtaining a
16
# * copy of this software and associated documentation files (the "Software"),
17
# * to deal in the Software without restriction, including without limitation
18
# * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19
# * and/or sell copies of the Software, and to permit persons to whom the
20
# * Software is furnished to do so, subject to the following conditions:
22
# * The above copyright notice and this permission notice shall be included
23
# * in all copies or substantial portions of the Software.
25
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26
# * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
# * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28
# * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
# * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30
# * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31
# * DEALINGS IN THE SOFTWARE.
32
# ****************************************************************************/
36
from osgeo import gdal
42
#/************************************************************************/
44
#/************************************************************************/
47
print( "Usage: gdalinfo [--help-general] [-mm] [-stats] [-hist] [-nogcp] [-nomd]\n" + \
48
" [-norat] [-noct] [-nofl] [-checksum] [-mdd domain]* datasetname" )
53
return a.lower() == b.lower()
55
#/************************************************************************/
57
#/************************************************************************/
59
def main( argv = None ):
61
bComputeMinMax = False
68
bShowColorTable = True
69
bComputeChecksum = False
70
bReportHistograms = False
72
papszExtraMDDomains = [ ]
77
#/* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
78
#/* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
79
#/* for the --format or --formats options */
80
#for( i = 1; i < argc; i++ )
82
# if EQUAL(argv[i],"--config") and i + 2 < argc and EQUAL(argv[i + 1], "GDAL_SKIP"):
84
# CPLSetConfigOption( argv[i+1], argv[i+2] );
95
argv = gdal.GeneralCmdLineProcessor( argv )
101
#/* -------------------------------------------------------------------- */
102
#/* Parse arguments. */
103
#/* -------------------------------------------------------------------- */
107
if EQUAL(argv[i], "--utility_version"):
108
print("%s is running against GDAL %s" %
109
(argv[0], gdal.VersionInfo("RELEASE_NAME")))
111
elif EQUAL(argv[i], "-mm"):
112
bComputeMinMax = True
113
elif EQUAL(argv[i], "-hist"):
114
bReportHistograms = True
115
elif EQUAL(argv[i], "-stats"):
118
elif EQUAL(argv[i], "-approx_stats"):
121
elif EQUAL(argv[i], "-sample"):
123
elif EQUAL(argv[i], "-checksum"):
124
bComputeChecksum = True
125
elif EQUAL(argv[i], "-nogcp"):
127
elif EQUAL(argv[i], "-nomd"):
128
bShowMetadata = False
129
elif EQUAL(argv[i], "-norat"):
131
elif EQUAL(argv[i], "-noct"):
132
bShowColorTable = False
133
elif EQUAL(argv[i], "-mdd") and i < nArgc-1:
135
papszExtraMDDomains.append( argv[i] )
136
elif EQUAL(argv[i], "-nofl"):
137
bShowFileList = False
138
elif argv[i][0] == '-':
140
elif pszFilename is None:
141
pszFilename = argv[i]
147
if pszFilename is None:
150
#/* -------------------------------------------------------------------- */
152
#/* -------------------------------------------------------------------- */
153
hDataset = gdal.Open( pszFilename, gdal.GA_ReadOnly )
157
print("gdalinfo failed - unable to open '%s'." % pszFilename )
161
#/* -------------------------------------------------------------------- */
162
#/* Report general info. */
163
#/* -------------------------------------------------------------------- */
164
hDriver = hDataset.GetDriver();
165
print( "Driver: %s/%s" % ( \
169
papszFileList = hDataset.GetFileList();
170
if papszFileList is None or len(papszFileList) == 0:
171
print( "Files: none associated" )
173
print( "Files: %s" % papszFileList[0] )
175
for i in range(1, len(papszFileList)):
176
print( " %s" % papszFileList[i] )
178
print( "Size is %d, %d" % (hDataset.RasterXSize, hDataset.RasterYSize))
180
#/* -------------------------------------------------------------------- */
181
#/* Report projection. */
182
#/* -------------------------------------------------------------------- */
183
pszProjection = hDataset.GetProjectionRef()
184
if pszProjection is not None:
186
hSRS = osr.SpatialReference()
187
if hSRS.ImportFromWkt(pszProjection ) == gdal.CE_None:
188
pszPrettyWkt = hSRS.ExportToPrettyWkt(False)
190
print( "Coordinate System is:\n%s" % pszPrettyWkt )
192
print( "Coordinate System is `%s'" % pszProjection )
194
#/* -------------------------------------------------------------------- */
195
#/* Report Geotransform. */
196
#/* -------------------------------------------------------------------- */
197
adfGeoTransform = hDataset.GetGeoTransform(can_return_null = True)
198
if adfGeoTransform is not None:
200
if adfGeoTransform[2] == 0.0 and adfGeoTransform[4] == 0.0:
201
print( "Origin = (%.15f,%.15f)" % ( \
202
adfGeoTransform[0], adfGeoTransform[3] ))
204
print( "Pixel Size = (%.15f,%.15f)" % ( \
205
adfGeoTransform[1], adfGeoTransform[5] ))
208
print( "GeoTransform =\n" \
209
" %.16g, %.16g, %.16g\n" \
210
" %.16g, %.16g, %.16g" % ( \
211
adfGeoTransform[0], \
212
adfGeoTransform[1], \
213
adfGeoTransform[2], \
214
adfGeoTransform[3], \
215
adfGeoTransform[4], \
216
adfGeoTransform[5] ))
218
#/* -------------------------------------------------------------------- */
220
#/* -------------------------------------------------------------------- */
221
if bShowGCPs and hDataset.GetGCPCount() > 0:
223
pszProjection = hDataset.GetGCPProjection()
224
if pszProjection is not None:
226
hSRS = osr.SpatialReference()
227
if hSRS.ImportFromWkt(pszProjection ) == gdal.CE_None:
228
pszPrettyWkt = hSRS.ExportToPrettyWkt(False)
229
print( "GCP Projection = \n%s" % pszPrettyWkt )
232
print( "GCP Projection = %s" % \
235
gcps = hDataset.GetGCPs()
239
print( "GCP[%3d]: Id=%s, Info=%s\n" \
240
" (%.15g,%.15g) -> (%.15g,%.15g,%.15g)" % ( \
241
i, gcp.Id, gcp.Info, \
242
gcp.GCPPixel, gcp.GCPLine, \
243
gcp.GCPX, gcp.GCPY, gcp.GCPZ ))
246
#/* -------------------------------------------------------------------- */
247
#/* Report metadata. */
248
#/* -------------------------------------------------------------------- */
250
papszMetadata = hDataset.GetMetadata_List()
253
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
255
for metadata in papszMetadata:
256
print( " %s" % metadata )
259
for extra_domain in papszExtraMDDomains:
260
papszMetadata = hDataset.GetMetadata_List(extra_domain)
261
if papszMetadata is not None and len(papszMetadata) > 0 :
262
print( "Metadata (%s):" % extra_domain)
263
for metadata in papszMetadata:
264
print( " %s" % metadata )
266
#/* -------------------------------------------------------------------- */
267
#/* Report "IMAGE_STRUCTURE" metadata. */
268
#/* -------------------------------------------------------------------- */
270
papszMetadata = hDataset.GetMetadata_List("IMAGE_STRUCTURE")
273
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
274
print( "Image Structure Metadata:" )
275
for metadata in papszMetadata:
276
print( " %s" % metadata )
278
#/* -------------------------------------------------------------------- */
279
#/* Report subdatasets. */
280
#/* -------------------------------------------------------------------- */
281
papszMetadata = hDataset.GetMetadata_List("SUBDATASETS")
282
if papszMetadata is not None and len(papszMetadata) > 0 :
283
print( "Subdatasets:" )
284
for metadata in papszMetadata:
285
print( " %s" % metadata )
287
#/* -------------------------------------------------------------------- */
288
#/* Report geolocation. */
289
#/* -------------------------------------------------------------------- */
291
papszMetadata = hDataset.GetMetadata_List("GEOLOCATION")
294
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
295
print( "Geolocation:" )
296
for metadata in papszMetadata:
297
print( " %s" % metadata )
299
#/* -------------------------------------------------------------------- */
301
#/* -------------------------------------------------------------------- */
303
papszMetadata = hDataset.GetMetadata_List("RPC")
306
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
307
print( "RPC Metadata:" )
308
for metadata in papszMetadata:
309
print( " %s" % metadata )
311
#/* -------------------------------------------------------------------- */
312
#/* Setup projected to lat/long transform if appropriate. */
313
#/* -------------------------------------------------------------------- */
314
if pszProjection is not None and len(pszProjection) > 0:
315
hProj = osr.SpatialReference( pszProjection )
316
if hProj is not None:
317
hLatLong = hProj.CloneGeogCS()
319
if hLatLong is not None:
320
gdal.PushErrorHandler( 'CPLQuietErrorHandler' )
321
hTransform = osr.CoordinateTransformation( hProj, hLatLong )
322
gdal.PopErrorHandler()
323
if gdal.GetLastErrorMsg().find( 'Unable to load PROJ.4 library' ) != -1:
326
#/* -------------------------------------------------------------------- */
327
#/* Report corners. */
328
#/* -------------------------------------------------------------------- */
329
print( "Corner Coordinates:" )
330
GDALInfoReportCorner( hDataset, hTransform, "Upper Left", \
332
GDALInfoReportCorner( hDataset, hTransform, "Lower Left", \
333
0.0, hDataset.RasterYSize);
334
GDALInfoReportCorner( hDataset, hTransform, "Upper Right", \
335
hDataset.RasterXSize, 0.0 );
336
GDALInfoReportCorner( hDataset, hTransform, "Lower Right", \
337
hDataset.RasterXSize, \
338
hDataset.RasterYSize );
339
GDALInfoReportCorner( hDataset, hTransform, "Center", \
340
hDataset.RasterXSize/2.0, \
341
hDataset.RasterYSize/2.0 );
343
#/* ==================================================================== */
344
#/* Loop over bands. */
345
#/* ==================================================================== */
346
for iBand in range(hDataset.RasterCount):
348
hBand = hDataset.GetRasterBand(iBand+1 )
352
# float afSample[10000];
355
# nCount = GDALGetRandomRasterSample( hBand, 10000, afSample );
356
# print( "Got %d samples.\n", nCount );
359
(nBlockXSize, nBlockYSize) = hBand.GetBlockSize()
360
print( "Band %d Block=%dx%d Type=%s, ColorInterp=%s" % ( iBand+1, \
361
nBlockXSize, nBlockYSize, \
362
gdal.GetDataTypeName(hBand.DataType), \
363
gdal.GetColorInterpretationName( \
364
hBand.GetRasterColorInterpretation()) ))
366
if hBand.GetDescription() is not None \
367
and len(hBand.GetDescription()) > 0 :
368
print( " Description = %s" % hBand.GetDescription() )
370
dfMin = hBand.GetMinimum()
371
dfMax = hBand.GetMaximum()
372
if dfMin is not None or dfMax is not None or bComputeMinMax:
375
if dfMin is not None:
376
line = line + ("Min=%.3f " % dfMin)
377
if dfMax is not None:
378
line = line + ("Max=%.3f " % dfMax)
382
adfCMinMax = hBand.ComputeRasterMinMax(False)
383
if gdal.GetLastErrorType() == gdal.CE_None:
384
line = line + ( " Computed Min/Max=%.3f,%.3f" % ( \
385
adfCMinMax[0], adfCMinMax[1] ))
389
stats = hBand.GetStatistics( bApproxStats, bStats)
390
# Dirty hack to recognize if stats are valid. If invalid, the returned
393
print( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f" % ( \
394
stats[0], stats[1], stats[2], stats[3] ))
396
if bReportHistograms:
398
hist = hBand.GetDefaultHistogram(force = True, callback = gdal.TermProgress)
402
nBucketCount = hist[2]
403
panHistogram = hist[3]
405
print( " %d buckets from %g to %g:" % ( \
406
nBucketCount, dfMin, dfMax ))
408
for bucket in panHistogram:
409
line = line + ("%d " % bucket)
414
print( " Checksum=%d" % hBand.Checksum())
416
dfNoData = hBand.GetNoDataValue()
417
if dfNoData is not None:
418
if dfNoData != dfNoData:
419
print( " NoData Value=nan" )
421
print( " NoData Value=%.18g" % dfNoData )
423
if hBand.GetOverviewCount() > 0:
425
line = " Overviews: "
426
for iOverview in range(hBand.GetOverviewCount()):
431
hOverview = hBand.GetOverview( iOverview );
432
if hOverview is not None:
434
line = line + ( "%dx%d" % (hOverview.XSize, hOverview.YSize))
437
hOverview.GetMetadataItem( "RESAMPLING", "" )
439
if pszResampling is not None \
440
and len(pszResampling) >= 12 \
441
and EQUAL(pszResampling[0:12],"AVERAGE_BIT2"):
445
line = line + "(null)"
451
line = " Overviews checksum: "
452
for iOverview in range(hBand.GetOverviewCount()):
457
hOverview = hBand.GetOverview( iOverview );
458
if hOverview is not None:
459
line = line + ( "%d" % hOverview.Checksum())
461
line = line + "(null)"
464
if hBand.HasArbitraryOverviews():
465
print( " Overviews: arbitrary" )
467
nMaskFlags = hBand.GetMaskFlags()
468
if (nMaskFlags & (gdal.GMF_NODATA|gdal.GMF_ALL_VALID)) == 0:
470
hMaskBand = hBand.GetMaskBand()
472
line = " Mask Flags: "
473
if (nMaskFlags & gdal.GMF_PER_DATASET) != 0:
474
line = line + "PER_DATASET "
475
if (nMaskFlags & gdal.GMF_ALPHA) != 0:
476
line = line + "ALPHA "
477
if (nMaskFlags & gdal.GMF_NODATA) != 0:
478
line = line + "NODATA "
479
if (nMaskFlags & gdal.GMF_ALL_VALID) != 0:
480
line = line + "ALL_VALID "
483
if hMaskBand is not None and \
484
hMaskBand.GetOverviewCount() > 0:
486
line = " Overviews of mask band: "
487
for iOverview in range(hMaskBand.GetOverviewCount()):
492
hOverview = hMaskBand.GetOverview( iOverview );
493
if hOverview is not None:
494
line = line + ( "%d" % hOverview.Checksum())
496
line = line + "(null)"
498
if len(hBand.GetUnitType()) > 0:
499
print( " Unit Type: %s" % hBand.GetUnitType())
501
papszCategories = hBand.GetRasterCategoryNames()
502
if papszCategories is not None:
504
print( " Categories:" );
506
for category in papszCategories:
507
print( " %3d: %s" % (i, category) )
510
if hBand.GetScale() != 1.0 or hBand.GetOffset() != 0.0:
511
print( " Offset: %.15g, Scale:%.15g" % \
512
( hBand.GetOffset(), hBand.GetScale()))
515
papszMetadata = hBand.GetMetadata_List()
518
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
519
print( " Metadata:" )
520
for metadata in papszMetadata:
521
print( " %s" % metadata )
525
papszMetadata = hBand.GetMetadata_List("IMAGE_STRUCTURE")
528
if bShowMetadata and papszMetadata is not None and len(papszMetadata) > 0 :
529
print( " Image Structure Metadata:" )
530
for metadata in papszMetadata:
531
print( " %s" % metadata )
534
hTable = hBand.GetRasterColorTable()
535
if hBand.GetRasterColorInterpretation() == gdal.GCI_PaletteIndex \
536
and hTable is not None:
538
print( " Color Table (%s with %d entries)" % (\
539
gdal.GetPaletteInterpretationName( \
540
hTable.GetPaletteInterpretation( )), \
545
for i in range(hTable.GetCount()):
546
sEntry = hTable.GetColorEntry(i)
547
print( " %3d: %d,%d,%d,%d" % ( \
555
hRAT = hBand.GetDefaultRAT()
557
#GDALRATDumpReadable( hRAT, None );
561
#/************************************************************************/
562
#/* GDALInfoReportCorner() */
563
#/************************************************************************/
565
def GDALInfoReportCorner( hDataset, hTransform, corner_name, x, y ):
568
line = "%-11s " % corner_name
570
#/* -------------------------------------------------------------------- */
571
#/* Transform the point into georeferenced coordinates. */
572
#/* -------------------------------------------------------------------- */
573
adfGeoTransform = hDataset.GetGeoTransform(can_return_null = True)
574
if adfGeoTransform is not None:
575
dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x \
576
+ adfGeoTransform[2] * y
577
dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x \
578
+ adfGeoTransform[5] * y
581
line = line + ("(%7.1f,%7.1f)" % (x, y ))
585
#/* -------------------------------------------------------------------- */
586
#/* Report the georeferenced coordinates. */
587
#/* -------------------------------------------------------------------- */
588
if abs(dfGeoX) < 181 and abs(dfGeoY) < 91:
589
line = line + ( "(%12.7f,%12.7f) " % (dfGeoX, dfGeoY ))
592
line = line + ( "(%12.3f,%12.3f) " % (dfGeoX, dfGeoY ))
594
#/* -------------------------------------------------------------------- */
595
#/* Transform to latlong and report. */
596
#/* -------------------------------------------------------------------- */
597
if hTransform is not None:
598
pnt = hTransform.TransformPoint(dfGeoX, dfGeoY, 0)
600
line = line + ( "(%s," % gdal.DecToDMS( pnt[0], "Long", 2 ) )
601
line = line + ( "%s)" % gdal.DecToDMS( pnt[1], "Lat", 2 ) )
607
if __name__ == '__main__':
608
version_num = int(gdal.VersionInfo('VERSION_NUM'))
609
if version_num < 1800: # because of GetGeoTransform(can_return_null)
610
print('ERROR: Python bindings of GDAL 1.8.0 or later required')
613
sys.exit(main(sys.argv))