Package osgeo :: Package utils :: Module gdal_edit
[hide private]
[frames] | no frames]

Source Code for Module osgeo.utils.gdal_edit

  1  #!/usr/bin/env python3 
  2  # -*- coding: utf-8 -*- 
  3  ############################################################################### 
  4  # $Id$ 
  5  # 
  6  #  Project:  GDAL samples 
  7  #  Purpose:  Edit in place various information of an existing GDAL dataset 
  8  #  Author:   Even Rouault <even dot rouault at spatialys.com> 
  9  # 
 10  ############################################################################### 
 11  #  Copyright (c) 2011-2013, Even Rouault <even dot rouault at spatialys.com> 
 12  # 
 13  #  Permission is hereby granted, free of charge, to any person obtaining a 
 14  #  copy of this software and associated documentation files (the "Software"), 
 15  #  to deal in the Software without restriction, including without limitation 
 16  #  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 17  #  and/or sell copies of the Software, and to permit persons to whom the 
 18  #  Software is furnished to do so, subject to the following conditions: 
 19  # 
 20  #  The above copyright notice and this permission notice shall be included 
 21  #  in all copies or substantial portions of the Software. 
 22  # 
 23  #  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 24  #  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 25  #  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 26  #  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 27  #  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 28  #  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 29  #  DEALINGS IN THE SOFTWARE. 
 30  ############################################################################### 
 31   
 32  import sys 
 33  from osgeo import gdal 
 34  from osgeo import osr 
 35   
 36   
37 -def Usage():
38 print('Usage: gdal_edit [--help-general] [-ro] [-a_srs srs_def]') 39 print(' [-a_ullr ulx uly lrx lry] [-a_ulurll ulx uly urx ury llx lly]') 40 print(' [-tr xres yres] [-unsetgt] [-unsetrpc] [-a_nodata value] [-unsetnodata]') 41 print(' [-offset value] [-scale value] [-units value]') 42 print(' [-colorinterp_X red|green|blue|alpha|gray|undefined]*') 43 print(' [-unsetstats] [-stats] [-approx_stats]') 44 print(' [-setstats min max mean stddev]') 45 print(' [-gcp pixel line easting northing [elevation]]*') 46 print(' [-unsetmd] [-oo NAME=VALUE]* [-mo "META-TAG=VALUE"]* datasetname') 47 print('') 48 print('Edit in place various information of an existing GDAL dataset.') 49 return -1
50 51
52 -def ArgIsNumeric(s):
53 i = 0 54 55 while i < len(s): 56 if (s[i] < '0' or s[i] > '9') and s[i] != '.' and s[i] != 'e' and s[i] != '+' and s[i] != '-': 57 return False 58 i = i + 1 59 60 return True
61 62
63 -def gdal_edit(argv):
64 65 argv = gdal.GeneralCmdLineProcessor(argv) 66 if argv is None: 67 return -1 68 69 datasetname = None 70 srs = None 71 ulx = None 72 uly = None 73 urx = None 74 ury = None 75 llx = None 76 lly = None 77 lrx = None 78 lry = None 79 nodata = None 80 unsetnodata = False 81 units = None 82 xres = None 83 yres = None 84 unsetgt = False 85 unsetstats = False 86 stats = False 87 setstats = False 88 approx_stats = False 89 unsetmd = False 90 ro = False 91 molist = [] 92 gcp_list = [] 93 open_options = [] 94 offset = [] 95 scale = [] 96 colorinterp = {} 97 unsetrpc = False 98 99 i = 1 100 argc = len(argv) 101 while i < argc: 102 if argv[i] == '-ro': 103 ro = True 104 elif argv[i] == '-a_srs' and i < len(argv) - 1: 105 srs = argv[i + 1] 106 i = i + 1 107 elif argv[i] == '-a_ullr' and i < len(argv) - 4: 108 ulx = float(argv[i + 1]) 109 i = i + 1 110 uly = float(argv[i + 1]) 111 i = i + 1 112 lrx = float(argv[i + 1]) 113 i = i + 1 114 lry = float(argv[i + 1]) 115 i = i + 1 116 elif argv[i] == '-a_ulurll' and i < len(argv) - 6: 117 ulx = float(argv[i + 1]) 118 i = i + 1 119 uly = float(argv[i + 1]) 120 i = i + 1 121 urx = float(argv[i + 1]) 122 i = i + 1 123 ury = float(argv[i + 1]) 124 i = i + 1 125 llx = float(argv[i + 1]) 126 i = i + 1 127 lly = float(argv[i + 1]) 128 i = i + 1 129 elif argv[i] == '-tr' and i < len(argv) - 2: 130 xres = float(argv[i + 1]) 131 i = i + 1 132 yres = float(argv[i + 1]) 133 i = i + 1 134 elif argv[i] == '-a_nodata' and i < len(argv) - 1: 135 nodata = float(argv[i + 1]) 136 i = i + 1 137 elif argv[i] == '-scale' and i < len(argv) : 138 scale.append(float(argv[i+1])) 139 i = i + 1 140 while i < len(argv) - 1 and ArgIsNumeric(argv[i+1]): 141 scale.append(float(argv[i+1])) 142 i = i + 1 143 elif argv[i] == '-offset' and i < len(argv) - 1: 144 offset.append(float(argv[i+1])) 145 i = i + 1 146 while i < len(argv) - 1 and ArgIsNumeric(argv[i+1]): 147 offset.append(float(argv[i+1])) 148 i = i + 1 149 elif argv[i] == '-mo' and i < len(argv) - 1: 150 molist.append(argv[i + 1]) 151 i = i + 1 152 elif argv[i] == '-gcp' and i + 4 < len(argv): 153 pixel = float(argv[i + 1]) 154 i = i + 1 155 line = float(argv[i + 1]) 156 i = i + 1 157 x = float(argv[i + 1]) 158 i = i + 1 159 y = float(argv[i + 1]) 160 i = i + 1 161 if i + 1 < len(argv) and ArgIsNumeric(argv[i + 1]): 162 z = float(argv[i + 1]) 163 i = i + 1 164 else: 165 z = 0 166 gcp = gdal.GCP(x, y, z, pixel, line) 167 gcp_list.append(gcp) 168 elif argv[i] == '-unsetgt': 169 unsetgt = True 170 elif argv[i] == '-unsetrpc': 171 unsetrpc = True 172 elif argv[i] == '-unsetstats': 173 unsetstats = True 174 elif argv[i] == '-approx_stats': 175 stats = True 176 approx_stats = True 177 elif argv[i] == '-stats': 178 stats = True 179 elif argv[i] == '-setstats' and i < len(argv)-4: 180 stats = True 181 setstats = True 182 if argv[i + 1] != 'None': 183 statsmin = float(argv[i + 1]) 184 else: 185 statsmin = None 186 i = i + 1 187 if argv[i + 1] != 'None': 188 statsmax = float(argv[i + 1]) 189 else: 190 statsmax = None 191 i = i + 1 192 if argv[i + 1] != 'None': 193 statsmean = float(argv[i + 1]) 194 else: 195 statsmean = None 196 i = i + 1 197 if argv[i + 1] != 'None': 198 statsdev = float(argv[i + 1]) 199 else: 200 statsdev = None 201 i = i + 1 202 elif argv[i] == '-units' and i < len(argv) - 1: 203 units = argv[i + 1] 204 i = i + 1 205 elif argv[i] == '-unsetmd': 206 unsetmd = True 207 elif argv[i] == '-unsetnodata': 208 unsetnodata = True 209 elif argv[i] == '-oo' and i < len(argv) - 1: 210 open_options.append(argv[i + 1]) 211 i = i + 1 212 elif argv[i].startswith('-colorinterp_')and i < len(argv) - 1: 213 band = int(argv[i][len('-colorinterp_'):]) 214 val = argv[i + 1] 215 if val.lower() == 'red': 216 val = gdal.GCI_RedBand 217 elif val.lower() == 'green': 218 val = gdal.GCI_GreenBand 219 elif val.lower() == 'blue': 220 val = gdal.GCI_BlueBand 221 elif val.lower() == 'alpha': 222 val = gdal.GCI_AlphaBand 223 elif val.lower() == 'gray' or val.lower() == 'grey': 224 val = gdal.GCI_GrayIndex 225 elif val.lower() == 'undefined': 226 val = gdal.GCI_Undefined 227 else: 228 sys.stderr.write('Unsupported color interpretation %s.\n' % val + 229 'Only red, green, blue, alpha, gray, undefined are supported.\n') 230 return Usage() 231 colorinterp[band] = val 232 i = i + 1 233 elif argv[i][0] == '-': 234 sys.stderr.write('Unrecognized option : %s\n' % argv[i]) 235 return Usage() 236 elif datasetname is None: 237 datasetname = argv[i] 238 else: 239 sys.stderr.write('Unexpected option : %s\n' % argv[i]) 240 return Usage() 241 242 i = i + 1 243 244 if datasetname is None: 245 return Usage() 246 247 if (srs is None and lry is None and yres is None and not unsetgt and 248 not unsetstats and not stats and not setstats and nodata is None and 249 not units and not molist and not unsetmd and not gcp_list and 250 not unsetnodata and not colorinterp and 251 scale is None and offset is None and not unsetrpc): 252 print('No option specified') 253 print('') 254 return Usage() 255 256 exclusive_option = 0 257 if lry is not None: 258 exclusive_option = exclusive_option + 1 259 if lly is not None: # -a_ulurll 260 exclusive_option = exclusive_option + 1 261 if yres is not None: 262 exclusive_option = exclusive_option + 1 263 if unsetgt: 264 exclusive_option = exclusive_option + 1 265 if exclusive_option > 1: 266 print('-a_ullr, -a_ulurll, -tr and -unsetgt options are exclusive.') 267 print('') 268 return Usage() 269 270 if unsetstats and stats: 271 print('-unsetstats and either -stats or -approx_stats options are exclusive.') 272 print('') 273 return Usage() 274 275 if unsetnodata and nodata: 276 print('-unsetnodata and -nodata options are exclusive.') 277 print('') 278 return Usage() 279 280 if open_options is not None: 281 if ro: 282 ds = gdal.OpenEx(datasetname, gdal.OF_RASTER, open_options=open_options) 283 else: 284 ds = gdal.OpenEx(datasetname, gdal.OF_RASTER | gdal.OF_UPDATE, open_options=open_options) 285 # GDAL 1.X compat 286 elif ro: 287 ds = gdal.Open(datasetname) 288 else: 289 ds = gdal.Open(datasetname, gdal.GA_Update) 290 if ds is None: 291 return -1 292 293 if scale: 294 if len(scale) == 1: 295 scale = scale * ds.RasterCount 296 elif len(scale) != ds.RasterCount: 297 print('If more than one scale value is provided, their number must match the number of bands.') 298 print('') 299 return Usage() 300 301 if offset: 302 if len(offset) == 1: 303 offset = offset * ds.RasterCount 304 elif len(offset) != ds.RasterCount: 305 print('If more than one offset value is provided, their number must match the number of bands.') 306 print('') 307 return Usage() 308 309 wkt = None 310 if srs == '' or srs == 'None': 311 ds.SetProjection('') 312 elif srs is not None: 313 sr = osr.SpatialReference() 314 if sr.SetFromUserInput(srs) != 0: 315 print('Failed to process SRS definition: %s' % srs) 316 return -1 317 wkt = sr.ExportToWkt() 318 if not gcp_list: 319 ds.SetProjection(wkt) 320 321 if lry is not None: 322 gt = [ulx, (lrx - ulx) / ds.RasterXSize, 0, 323 uly, 0, (lry - uly) / ds.RasterYSize] 324 ds.SetGeoTransform(gt) 325 326 elif lly is not None: # -a_ulurll 327 gt = [ulx, (urx - ulx) / ds.RasterXSize, (llx - ulx) / ds.RasterYSize, 328 uly, (ury - uly) / ds.RasterXSize, (lly - uly) / ds.RasterYSize] 329 ds.SetGeoTransform(gt) 330 331 if yres is not None: 332 gt = ds.GetGeoTransform() 333 # Doh ! why is gt a tuple and not an array... 334 gt = [gt[j] for j in range(6)] 335 gt[1] = xres 336 gt[5] = yres 337 ds.SetGeoTransform(gt) 338 339 if unsetgt: 340 # For now only the GTiff drivers understands full-zero as a hint 341 # to unset the geotransform 342 if ds.GetDriver().ShortName == 'GTiff': 343 ds.SetGeoTransform([0, 0, 0, 0, 0, 0]) 344 else: 345 ds.SetGeoTransform([0, 1, 0, 0, 0, 1]) 346 347 if gcp_list: 348 if wkt is None: 349 wkt = ds.GetGCPProjection() 350 if wkt is None: 351 wkt = '' 352 ds.SetGCPs(gcp_list, wkt) 353 354 if nodata is not None: 355 for i in range(ds.RasterCount): 356 ds.GetRasterBand(i + 1).SetNoDataValue(nodata) 357 elif unsetnodata: 358 for i in range(ds.RasterCount): 359 ds.GetRasterBand(i + 1).DeleteNoDataValue() 360 361 if scale: 362 for i in range(ds.RasterCount): 363 ds.GetRasterBand(i + 1).SetScale(scale[i]) 364 365 if offset: 366 for i in range(ds.RasterCount): 367 ds.GetRasterBand(i + 1).SetOffset(offset[i]) 368 369 if units: 370 for i in range(ds.RasterCount): 371 ds.GetRasterBand(i + 1).SetUnitType(units) 372 373 if unsetstats: 374 for i in range(ds.RasterCount): 375 band = ds.GetRasterBand(i + 1) 376 for key in band.GetMetadata().keys(): 377 if key.startswith('STATISTICS_'): 378 band.SetMetadataItem(key, None) 379 380 if stats: 381 for i in range(ds.RasterCount): 382 ds.GetRasterBand(i + 1).ComputeStatistics(approx_stats) 383 384 if setstats: 385 for i in range(ds.RasterCount): 386 if statsmin is None or statsmax is None or statsmean is None or statsdev is None: 387 ds.GetRasterBand(i+1).ComputeStatistics(approx_stats) 388 min,max,mean,stdev = ds.GetRasterBand(i+1).GetStatistics(approx_stats,True) 389 if statsmin is None: 390 statsmin = min 391 if statsmax is None: 392 statsmax = max 393 if statsmean is None: 394 statsmean = mean 395 if statsdev is None: 396 statsdev = stdev 397 ds.GetRasterBand(i+1).SetStatistics(statsmin, statsmax, statsmean, statsdev) 398 399 if molist: 400 if unsetmd: 401 md = {} 402 else: 403 md = ds.GetMetadata() 404 for moitem in molist: 405 equal_pos = moitem.find('=') 406 if equal_pos > 0: 407 md[moitem[0:equal_pos]] = moitem[equal_pos + 1:] 408 ds.SetMetadata(md) 409 elif unsetmd: 410 ds.SetMetadata({}) 411 412 for band in colorinterp: 413 ds.GetRasterBand(band).SetColorInterpretation(colorinterp[band]) 414 415 if unsetrpc: 416 ds.SetMetadata(None, 'RPC') 417 418 ds = band = None 419 420 return 0
421 422
423 -def main(argv):
424 return gdal_edit(argv)
425 426 427 if __name__ == '__main__': 428 sys.exit(main(sys.argv)) 429