def main(): # -----------Setting up and unsing option parser----------------------- parser = OptionParser(usage=usage, version=version) parser.add_option("-d", "--doc", action="store_true", dest="doc", help="Prints more detailed documentation and exit") parser.add_option("-v", action="store_const", const=logging.DEBUG, dest="loglevel", default=get_loglevel(), help="Produce verbose output") parser.add_option("-o", "--output", action="store", dest="outfileName", default=None, help="Output file") parser.add_option("-i", "--i", action="store", dest="infile", help="Raster to be regionalized") parser.add_option("-r", "--regdef", action="store", dest="regdef", help="Raster defining the regions found " + "in statistics table") parser.add_option("-s", "--stat", action="store", dest="stat", help="Tab-separated statistics table, " + "with 1st column representing geocode and value " + "representing region sum") parser.add_option("-c", "--colname", action="store", dest="colname", help="Header of column in stat table to fetch " + "region sums from") (options, args) = parser.parse_args() # ------------Setting up logging capabilities ----------- rootLogger = logger.RootLogger(int(options.loglevel)) global log log = rootLogger.getLogger(sys.argv[0]) # ------------Process and validate options--------------- if options.doc: print __doc__ sys.exit() if len(args) > 0: parser.error("Incorrect number of arguments") regdef = Raster() if options.regdef is not None: regdef.read(options.regdef) else: log.error("No region definition raster specified") sys.exit(1) key = Raster() if options.infile is not None: key.read(options.infile) else: log.info("No initial distribution raster given, using " + "homogenious distribution") key.assign(regdef) key.data = np.where(regdef.data != regdef.nodata, 1, regdef.nodata) if options.stat is None: log.error("No statistics table specified") sys.exit(1) if (regdef.xll != key.xll or regdef.yll != key.yll): log.error("The raster domain size is differs between key raster " + "and region raster") stat = DataTable() stat.read(options.stat, defaultType=float) print stat.desc stat.convertCol(stat.desc[0]["id"], int) print stat.desc # Set first column as unique id for rows stat.setKeys([stat.desc[0]["id"]]) # Remove nodata in rasters key.nodataToZero() regdef.nodataToZero() log.info("Consistency och completeness check for codes " + "in regdef and statistics") # Create list of codes in raster regdefCodes = regdef.unique() regdefCodes = map(int, regdefCodes) if 0.0 in regdefCodes: regdefCodes.remove(0.0) statRegCodes = [row[0] for row in stat.data] if options.colname is not None: try: col = stat.colIndex[options.colname] except KeyError: log.error("No column named " + "%s found in statistics table" % options.colname) sys.exit(1) else: col = 1 colId = stat.desc[col]["id"] errFound = False for code in statRegCodes: # Assuring that the regional codes are present in regdef if code not in regdefCodes: log.error("Input Error: code:" + str(int(code)) + "in reg totals is not represented in regional raster") errFound = True # Assuring that the regional raster IDs are present # in the regional statistics for code in regdefCodes: if code not in statRegCodes: log.error("Input Error: ID:" + str(code) + " in region raster is not represented in " + "regional totals!") errFound = True if errFound: sys.exit(1) # For all regions, calculate the regional sum, # set the key values to key/regSum res = np.zeros(key.data.shape) log.info("Regionalizing key raster") for code in regdefCodes: emis = stat.lookup(colId, code) log.debug("Statistics for reg %i: %f" % (code, emis)) mask = np.array(regdef.data == code) regKey = mask * key.data regSum = np.sum(np.sum(regKey)) if regSum > 0: res = res + emis * regKey / regSum else: log.warning("Distribution key is zero for geocode" + " %i, using homogenuous distribution for this region" % code) res = res + emis * mask / np.sum(np.sum(mask)) key.data = res # resultRast=(totFractionRast*key)*regionalTotals.regSum(substance) key.write(options.outfileName) log.info("Result with sum: %f written" % res.sum())
def read(filename,bandIndex=None,dataType=numpy.float): """ Read raster using GDAL drivers @param filename: raster filename @param bandIndex: index of band to read, None gives all bands @param dataType: convert raster to type, default=numpy.float """ #ArgGIS grid: AIG #GeoTIFF: GTiff #GIF #BMP # register all of the drivers gdal.AllRegister() ds = gdal.Open(filename, GA_ReadOnly) if ds is None: print 'Could not open ' + filename sys.exit(1) ncols= ds.RasterXSize nrows = ds.RasterYSize nbands = ds.RasterCount #Info used for georeferencing geoTransform = ds.GetGeoTransform() xul=geoTransform[0] #top left x cellsizeX=geoTransform[1] #w-e pixel resolution rot1=geoTransform[2] #rotation, 0 if image is "north up" yul=geoTransform[3] #top left y rot2=geoTransform[4] #rotation, 0 if image is "north up" cellsizeY=geoTransform[5] #n-s pixel resolution xll=xul yll=yul-nrows*cellsizeY if rot1!=0 or rot2!=0: print 'Rotated rasters are not supported by pyAirviro.geo.raster' sys.exit(1) if abs(cellsizeX)!=abs(cellsizeY): print 'Non-homogenous cellsizes are not supported by pyAirviro.geo.raster' sys.exit(1) #Creates a list with band indices to be read rasters=[] if bandIndex is None: bandRange=range(1,nbands+1) else: if isinstance(bandIndex,list): bandRange=bandIndex else: bandRange=[bandIndex] for bi in bandRange: band = ds.GetRasterBand(bi) nodata=band.GetNoDataValue() rast=Raster(Xll=xll,Yll=yll,Ncols=ncols,Nrows=nrows,Cellsize=abs(cellsizeX),Nodata=nodata) xBlockSize,yBlockSize=band.GetBlockSize() data =None for i in range(0, nrows, yBlockSize): if i + yBlockSize < nrows: numRows = yBlockSize else: numRows=nrows-i #last block is not complete in y direction colBlock=None for j in range(0, ncols, xBlockSize): if j + xBlockSize < ncols: numCols = xBlockSize else: numCols=ncols-j #last block is not complete in x direction dataBlock = band.ReadAsArray(j, i, numCols, numRows) #Read whole array dataBlock = dataBlock.astype(dataType) # Process block here if large file ,before # reading the next block if colBlock is None: colBlock=dataBlock else: colBlock=numpy.concatenate((colBlock,dataBlock),1) if data is None: data=colBlock else: data=numpy.concatenate((data,colBlock),0) rast.data=data rasters.append(rast) return rasters