def __getmetadata__(self): '''Read Metadata for a "scene01/*.tif" (possibly) multiband image''' f = self.fileinfo['filepath'] d = os.path.dirname(f) bands = sorted([t for t in self.filelist if t[-4:].lower() == '.tif']) ds = geometry.OpenDataset(f) vrt = geometry.CreateSimpleVRT(bands, ds.RasterXSize, ds.RasterYSize, gdal.GetDataTypeName( ds.GetRasterBand(1).DataType), relativeToVRT=0) vrtds = geometry.OpenDataset(vrt, gdalconst.GA_Update) vrtds.SetGeoTransform(ds.GetGeoTransform()) vrtds.SetProjection(ds.GetProjection()) vrtds.SetGCPs(ds.GetGCPs(), ds.GetProjection()) vrtds.SetMetadata(ds.GetMetadata()) #Kludge... the drivers are designed to "open" strings, i.e. filenames and vrt xml #(maybe look at allowing GdalDataset objects in future) vrtds = geometry.CreateVRTCopy( vrtds) #This updates the Description property to include all the vrtxml = vrtds.GetDescription() #SRS/GCP/GT info we just added. #GetDescription() is the only way I know of to get at the #underlying XML string. #Autopopulate metadata __default__.Dataset.__getmetadata__(self, vrtxml) self.metadata['filetype'] = 'GTiff/GeoTIFF'
def __getmetadata__(self): '''Read Metadata for a NetCDF image (1st subdataset)''' f=self.fileinfo['filepath'] if f[:4]=='/vsi':raise NotImplementedError nc=geometry.OpenDataset(f) ncmd=nc.GetMetadata() sds=nc.GetSubDatasets() #gdal_version=''.join([c for c in gdal.__version__ if c in '1234567890.']) gdal_version=[int(c) for c in gdal_version.split('.')] if sds: #Use the SubDataset with the most cols*rows xy=[] sdo=[] for sd_name,sd_desc in sds: sd=geometry.OpenDataset(sd_name) xy.append(sd.RasterXSize * sd.RasterYSize) sdo.append([sd,sd_name,sd_desc]) sd,sd_name,sd_desc=sdo[xy.index(max(xy))] try:__default__.Dataset.__getmetadata__(self, sd_name) #autopopulate basic metadata except NotImplementedError: if gdal_version < [1,8,0]: raise NotImplementedError('You are using GDAL %s, versions < 1.8 do not read georeferencing information for certain NetCDF files.'%geometry.gdal.__version__) else:raise sdmd=sd.GetMetadata() else: try:__default__.Dataset.__getmetadata__(self, f) #autopopulate basic metadata except NotImplementedError: if gdal_version < [1,8,0]: raise NotImplementedError('You are using GDAL %s, versions < 1.8 do not read georeferencing information for certain NetCDF files.'%geometry.gdal.__version__) else:raise sdmd={} sd_name,sd_desc = ['',''] source=sdmd.get('NC_GLOBAL#source',ncmd.get('NC_GLOBAL#source','')) if source:source='Source:'+source history=sdmd.get('NC_GLOBAL#history',ncmd.get('NC_GLOBAL#history','')) if history:history='History:n'+history self.metadata['lineage'] = '\n\n'.join([source,history]).strip() comment=sdmd.get('NC_GLOBAL#comment',ncmd.get('NC_GLOBAL#comment','')) references=sdmd.get('NC_GLOBAL#references',ncmd.get('NC_GLOBAL#references','')) if references:references='References:n'+references self.metadata['abstract'] = '\n\n'.join([comment,references]).strip() self.metadata['title'] = ncmd.get('NC_GLOBAL#title',sdmd.get('NC_GLOBAL#title',sd_desc)) self.metadata['useConstraints'] = ncmd.get('NC_GLOBAL#acknowledgment',sdmd.get('NC_GLOBAL#acknowledgment','')) pass
def __init__(self, f=None): if not f: f = self.fileinfo['filepath'] self.filelist = glob.glob(os.path.splitext(f)[0] + '.*') self._gdaldataset = geometry.OpenDataset(f) self._hdf_md = self._gdaldataset.GetMetadata() if not self._hdf_md.get('INSTRUMENTSHORTNAME') == 'ASTER': raise NotImplementedError #This error gets ignored in __init__.Open()
def __opendataset__(self): bandlookup = { 'pan': ['pan'], 'blu': ['blu'], 'grn': ['grn'], 'red': ['red'], 'nir': ['nir'], 'bgrn': ['blu', 'grn', 'red', 'nir'], 'bgr': ['blu', 'grn', 'red'], 'rgb': ['red', 'grn', 'blu'] } bandfiles = {} bandnames = [] for d in self._datafiles: band = d.split('_')[2] bands = bandlookup.get(band, band) for band in bands: bandfiles[band] = os.path.join( os.path.dirname(self.fileinfo['filepath']), d) bandnames += [band] try: f = bandfiles['red'] rgb = True except: f = bandfiles['pan'] rgb = False ds = geometry.OpenDataset(f) rb = ds.GetRasterBand(1) cols = ds.RasterXSize rows = ds.RasterYSize datatype = gdal.GetDataTypeName(rb.DataType) nbits = gdal.GetDataTypeSize(rb.DataType) nbands = len(bandnames) bandnames = ','.join(bandnames) if rgb and bandfiles['red'] != bandfiles['blu']: ds = geometry.OpenDataset( geometry.CreateSimpleVRT( [bandfiles['red'], bandfiles['grn'], bandfiles['blu']], cols, rows, datatype)) return ds, nbands, bandnames, f
def __getmetadata__(self, f=None): '''Read Metadata for a DIMAP image as GDAL doesn't quite get it all...''' if not f: f = self.fileinfo['filepath'] #dom=etree.parse(f) #Takes tooo long to parse the whole file, so just read as far as we need... strxml = '' for line in open(f, 'r'): if line.upper().strip() == '<DATA_STRIP>': break else: strxml += line if not '</Dimap_Document>' in strxml: strxml += '</Dimap_Document>' dom = etree.fromstring(strxml) self.metadata['sceneid'] = dom.xpath( 'string(/Dimap_Document/Dataset_Id/DATASET_NAME)') bands = dom.xpath( '/Dimap_Document/Spectral_Band_Info/BAND_DESCRIPTION') self.metadata['bands'] = ','.join( [band.xpath('string(.)') for band in bands]) try: __default__.Dataset.__getmetadata__( self, f) #autopopulate basic metadata except geometry.GDALError, err: #Work around reading images with lowercase filenames when #the DATA_FILE_PATH is uppercase # - eg samba filesystems which get converted to lowercase dfp = dom.xpath( '/Dimap_Document/Data_Access/Data_File/DATA_FILE_PATH')[0] fn = utilities.encode( dfp.xpath('string(@href)' )) #XML is unicode, gdal.Open doesn't like unicode if not os.path.dirname(fn): fn = os.path.join(os.path.dirname(f), fn) exists, img = utilities.exists(fn, True) if exists and not os.path.exists(fn): import tempfile tmpfd, tmpfn = tempfile.mkstemp(suffix='.dim', prefix='metadata') dfp.set('href', img) tmpfo = os.fdopen(tmpfd, 'w') tmpfo.write(etree.tostring(dom)) tmpfo.flush() tmpfo.close() cwd = os.path.abspath(os.curdir) tmp = os.path.split(tmpfn) os.chdir( tmp[0] ) #CD to the tmp dir so __default__.Dataset.__getmetadata__ doesn't __default__.Dataset.__getmetadata__(self, tmp[1]) gdalmd = self._gdaldataset.GetMetadata() self._gdaldataset = geometry.OpenDataset(img) self._gdaldataset.SetMetadata(gdalmd) os.unlink(tmpfn) os.chdir(cwd) else: raise
def v1(self, f=None): dom = self._dom self.metadata['sceneid'] = dom.xpath( 'string(/Dimap_Document/Dataset_Id/DATASET_NAME)') bands = dom.xpath( '/Dimap_Document/Spectral_Band_Info/BAND_DESCRIPTION') self.metadata['bands'] = ','.join( [band.xpath('string(.)') for band in bands]) try: __default__.Dataset.__getmetadata__( self, f) #autopopulate basic metadata except geometry.GDALError, err: #Work around reading images with lowercase filenames when #the DATA_FILE_PATH is uppercase # - eg samba filesystems which get converted to lowercase dfp = dom.xpath( '/Dimap_Document/Data_Access/Data_File/DATA_FILE_PATH')[0] fn = utilities.encode( dfp.xpath('string(@href)' )) #XML is unicode, gdal.Open doesn't like unicode if not os.path.dirname(fn): fn = os.path.join(os.path.dirname(f), fn) exists, img = utilities.exists(fn, True) if exists and not os.path.exists(fn): import tempfile tmpfd, tmpfn = tempfile.mkstemp(suffix='.dim', prefix='metadata') dfp.set('href', img) tmpfo = os.fdopen(tmpfd, 'w') tmpfo.write(etree.tostring(dom)) tmpfo.flush() tmpfo.close() cwd = os.path.abspath(os.curdir) tmp = os.path.split(tmpfn) os.chdir( tmp[0] ) #CD to the tmp dir so __default__.Dataset.__getmetadata__ doesn't __default__.Dataset.__getmetadata__(self, tmp[1]) gdalmd = self._gdaldataset.GetMetadata() self._gdaldataset = geometry.OpenDataset(img) self._gdaldataset.SetMetadata(gdalmd) os.unlink(tmpfn) os.chdir(cwd) else: raise
def __getmetadata__(self): '''Read Metadata for a Landsat Geotiff with Level 1 Metadata format image as GDAL doesn't get it all.''' f = self.fileinfo['filepath'] d = os.path.dirname(f) hdr = parseheader(f) bands = sorted( [i for i in hdr['PRODUCT_METADATA']['BAND_COMBINATION']]) if hdr['PRODUCT_METADATA'][ 'SENSOR_ID'] == 'ETM+': #Landsat 7 has 2 data files for thermal band 6 #Format=123456678 bands[5] = bands[5].replace('6', '61') bands[6] = bands[6].replace('6', '62') bandfiles = [ os.path.join(d, hdr['PRODUCT_METADATA']['BAND%s_FILE_NAME' % b]) for b in bands ] __default__.Dataset.__getmetadata__(self, bandfiles[0]) md = self.metadata md['metadata'] = open(f).read().replace('\x00', '') md['sceneid'] = os.path.basename(d) md['filetype'] = 'GTIFF/Landsat MTL Geotiff' md['bands'] = ','.join(bands) md['nbands'] = len(bands) md['level'] = hdr['PRODUCT_METADATA']['PRODUCT_TYPE'] md['imgdate'] = '%sT%s' % ( hdr['PRODUCT_METADATA']['ACQUISITION_DATE'], hdr['PRODUCT_METADATA']['SCENE_CENTER_SCAN_TIME'][0:8] ) #ISO 8601 format, strip off the milliseconds md['satellite'] = hdr['PRODUCT_METADATA']['SPACECRAFT_ID'] md['sensor'] = hdr['PRODUCT_METADATA']['SENSOR_ID'] md['demcorrection'] = hdr['PRODUCT_METADATA'].get( 'ELEVATION_SOURCE', '') #Level 1G isn't terrain corrected md['resampling'] = hdr['PROJECTION_PARAMETERS']['RESAMPLING_OPTION'] md['sunazimuth'] = hdr['PRODUCT_PARAMETERS']['SUN_AZIMUTH'] md['sunelevation'] = hdr['PRODUCT_PARAMETERS']['SUN_ELEVATION'] vrtxml = geometry.CreateSimpleVRT(bandfiles, md['cols'], md['rows'], md['datatype']) self._gdaldataset = geometry.OpenDataset(vrtxml) self._stretch = ['PERCENT', [3, 2, 1], [2, 98]]
def __getmetadata__(self): '''Read Metadata for a Landsat Geotiff with Level 1 Metadata format image as GDAL doesn't get it all.''' f=self.fileinfo['filepath'] d=os.path.dirname(f) hdr=parseheader(f) if hdr['L1_METADATA_FILE'].get('LANDSAT_SCENE_ID'):self.__getnewmetadata__(f,d,hdr) else:self.__getoldmetadata__(f,d,hdr) md=self.metadata vrtxml=geometry.CreateSimpleVRT(self.bandfiles,md['cols'],md['rows'], md['datatype']) self._gdaldataset = geometry.OpenDataset(vrtxml) for i in range(self._gdaldataset.RasterCount): self._gdaldataset.GetRasterBand(i+1).SetNoDataValue(0) #Fix quicklook stretch for Landsat 8 data if md['satellite']=='LANDSAT_8': self._stretch=['PERCENT',[4,3,2],[1,99]] else: self._stretch=['PERCENT',[3,2,1], [2,98]]
def __getmetadata__(self,f=None): '''Read Metadata for a ECW image as GDAL doesn't quite get it all...''' if not f:f=self.fileinfo['filepath'] #Originally we used the ERS to get metadata as they sometimes hold more info than the ECW #however, this caused segfaults under certain circumstances which were unable to be tracked down. #These circumstances were very repeatable and only occurred when the Crawler iterator returned a #certain ECW dataset, not when it was opened, when metadata was extracted nor even when overviews were generated. #Got me stumped! ers=os.path.splitext(f)[0]+'.ers' if os.path.exists(ers) and os.path.basename(f) in open(ers).read(): try: __default__.Dataset.__getmetadata__(self, ers) #autopopulate basic metadata self.metadata['filetype']='ECW/ERMapper Compressed Wavelets' self.metadata['compressiontype']='ECW' self.metadata['filepath']=f self.metadata['filename']=os.path.basename(f) self._gdaldataset=geometry.OpenDataset(f) #ERS may not get handed off to gdal proxy and segfault except:__default__.Dataset.__getmetadata__(self, f) else: __default__.Dataset.__getmetadata__(self) #autopopulate basic metadata
def hyp_l1t(self, f): md = parseheader(f) self.metadata['level'] = md['PRODUCT_METADATA']['PRODUCT_TYPE'] self.metadata['sceneid'] = self.metadata['filename'].split( '_')[0].upper() self.metadata['filetype'] = 'GTiff/GeoTIFF' self.metadata['satellite'] = 'EO1' self.metadata['sensor'] = md['PRODUCT_METADATA']['SENSOR_ID'] bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif')) band = geometry.OpenDataset(bands[0]) self.ncols = band.RasterXSize self.nrows = band.RasterYSize self.nbands = len(bands) uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON']) self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX']) self.prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE'] self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][ 'RESAMPLING_OPTION'] try: self.metadata['viewangle'] = float( md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunazimuth'] = float( md['PRODUCT_PARAMETERS']['SUN_AZIMUTH']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunelevation'] = float( md['PRODUCT_PARAMETERS']['SUN_ELEVATION']) except: pass #Exception raised if value == 'UNAVAILABLE' #EPSG:32601: WGS 84 / UTM zone 1N #EPSG:32701: WGS 84 / UTM zone 1S srs = osr.SpatialReference() zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER']) if zone > 0: epsg = 32600 + zone #North else: epsg = 32700 - zone #South srs.ImportFromEPSG(epsg) self.metadata['units'] = 'm' self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = str(epsg) ######################################################################################################### ##set self._gdaldataset for use in overview generation ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm) ##as they're near the center of the equivalent ALI bands self._gdaldataset = geometry.OpenDataset( geometry.CreateSimpleVRT([bands[43], bands[30], bands[21]], self.ncols, self.nrows, 'Int16')) self._gdaldataset.GetRasterBand(1).SetNoDataValue(0) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) #self._stretch=('STDDEV',(1,2,3),[2]) self._stretch = ('PERCENT', (1, 2, 3), [2, 98])
def __getmetadata__(self, f=None): '''Read Metadata for ASTER HDF images as GDAL doesn't.''' if not f: f = self.fileinfo['filepath'] hdf_sd = self._gdaldataset.GetSubDatasets() hdf_sd = [sd for sd, sz in hdf_sd if 'ImageData' in sd] hdf_md = self._hdf_md #sd,sz = hdf_sd[0] sd = hdf_sd[0] sd = geometry.OpenDataset(sd) nbands = len(hdf_sd) ncols = [] nrows = [] nbits = [] bands = [] datatypes = [] cellxy = [] for i in range(0, len(hdf_md['PROCESSEDBANDS']), 2): band = hdf_md['PROCESSEDBANDS'][i:i + 2] if i / 2 + 1 <= 4: bands.append('VNIR' + band) cellxy.append('15') elif i / 2 + 1 <= 10: bands.append('SWIR' + band) cellxy.append('30') else: bands.append('TIR' + band) cellxy.append('90') if band.isdigit(): band = str(int(band)) #Get rid of leading zero cols, rows, bytes = map( int, hdf_md['IMAGEDATAINFORMATION%s' % band].split(',')) if bytes == 1: datatypes.append('Byte') elif bytes == 2: datatypes.append('UInt16') ncols.append(str(cols)) nrows.append(str(rows)) nbits.append(str(bytes * 8)) ncols = ','.join(ncols) nrows = ','.join(nrows) nbits = ','.join(nbits) bands = ','.join(bands) datatypes = ','.join(datatypes) cellxy = ','.join(cellxy) uly, ulx = [float(xy) for xy in hdf_md['UPPERLEFT'].split(',')] ury, urx = [float(xy) for xy in hdf_md['UPPERRIGHT'].split(',')] lry, lrx = [float(xy) for xy in hdf_md['LOWERRIGHT'].split(',')] lly, llx = [float(xy) for xy in hdf_md['LOWERLEFT'].split(',')] ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] #SRS reported by GDAL is slightly dodgy, GDA94 is not recognised and doesn't set the North/South properly #Get it anyway so we can work out if it's GDA94 based on the spheroid srs = sd.GetGCPProjection() src_srs = osr.SpatialReference(srs) tgt_srs = osr.SpatialReference() geogcs = osr.SpatialReference() if src_srs.GetAttrValue('SPHEROID') == 'GRS 1980': geogcs.ImportFromEPSG(4283) #Assume 'GDA94' else: geogcs.ImportFromEPSG(4326) #Assume 'WGS84' tgt_srs.CopyGeogCSFrom(geogcs) if hdf_md['PROCESSINGLEVELID'].upper() == '1A': units = 'deg' else: #projparams=map(float, hdf_md['PROJECTIONPARAMETERS1'].split(',')) if hdf_md['MPMETHOD1'] == 'UTM': #Universal Transverse Mercator if uly < 0: bNorth = False #GDAL doesn't set the North/South properly else: bNorth = True nZone = int(hdf_md['UTMZONECODE1']) tgt_srs.SetUTM(nZone, bNorth) units = 'm' #Other projections not (yet?) implemented... #elif hdf_md['MPMETHOD1'] == 'PS':#Polar Stereographic # #dfCenterLon = ? GTCP projection params don't list cenlon/lat for PS # dfCenterLat = ? # dfScale = ? # tgt_srs.SetPS(dfCenterLat,dfCenterLon,dfScale,0.0,0.0) #elif hdf_md['MPMETHOD1'] == 'LAMCC':#Lambert Conformal Conic # dfCenterLon = ? # dfCenterLat = ? # dfStdP1 = ? # dfStdP2 = ? # tgt_srs.SetLCC(dfStdP1,dfStdP2,dfCenterLat,dfCenterLon,0,0) #elif hdf_md['MPMETHOD1'] == 'SOM':#Space Oblique Mercator # dfCenterLon = ? # dfCenterLat = ? # srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0) #elif hdf_md['MPMETHOD1'] == 'EQRECT':#Equi-Rectangular # dfCenterLon = ? # dfCenterLat = ? # tgt_srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0) else: #Assume Geog units = 'deg' srs = tgt_srs.ExportToWkt() self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_md[m]) for m in hdf_md]) self.metadata['satellite'] = 'Terra' self.metadata['sensor'] = 'ASTER' self.metadata['filetype'] = self._gdaldataset.GetDriver( ).ShortName + '/' + self._gdaldataset.GetDriver().LongName + ' (ASTER)' self.metadata['sceneid'] = hdf_md['ASTERSCENEID'] self.metadata['level'] = hdf_md['PROCESSINGLEVELID'] if '-' in hdf_md['CALENDARDATE']: imgdate = hdf_md['CALENDARDATE'] else: imgdate = time.strftime(utilities.dateformat, time.strptime(hdf_md['CALENDARDATE'], '%Y%m%d')) #ISO 8601 imgtime = hdf_md.get('TIMEOFDAY') if imgtime: self.metadata['imgdate'] = time.strftime( utilities.datetimeformat, time.strptime(imgdate + imgtime[0:6], '%Y-%m-%d%H%M%S')) #ISO 8601 else: self.metadata['imgdate'] = imgdate #self.metadata['imgdate'] = hdf_md['CALENDARDATE'] self.metadata['cloudcover'] = float(hdf_md['SCENECLOUDCOVERAGE']) if hdf_md['FLYINGDIRECTION'] == 'DE': self.metadata['orbit'] = 'Descending' else: self.metadata['orbit'] = 'Ascending' self.metadata['rotation'] = float( hdf_md.get('MAPORIENTATIONANGLE', hdf_md.get('SCENEORIENTATIONANGLE'))) if abs(self.metadata['rotation']) < 1.0: self.metadata['orientation'] = 'Map oriented' else: self.metadata['orientation'] = 'Path oriented' self.metadata['sunazimuth'], self.metadata['sunelevation'] = map( float, hdf_md['SOLARDIRECTION'].split(',')) self.metadata['viewangle'] = float(hdf_md['POINTINGANGLE']) self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands self.metadata['datatype'] = datatypes self.metadata['nbits'] = nbits self.metadata['nodata'] = ','.join(['0' for i in range(0, nbands)]) self.metadata['bands'] = bands self.metadata['resampling'] = hdf_md.get( 'RESMETHOD1') #Assume same for all... self.metadata['srs'] = srs self.metadata['epsg'] = spatialreferences.IdentifyAusEPSG(srs) self.metadata['units'] = units self.metadata['cellx'], self.metadata['celly'] = cellxy, cellxy #Geotransform ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] ncols = map(int, str(ncols).split(',')) nrows = map(int, str(nrows).split(',')) cellx, celly = [], [] j = 0 while j < len(ncols): gcps = [] i = 0 lr = [[0, 0], [ncols[j], 0], [ncols[j], nrows[j]], [0, nrows[j]]] while i < len(ext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = ext[i] gcp.Id = str(i) gcps.append(gcp) i += 1 j += 1 geotransform = gdal.GCPsToGeoTransform(gcps) x, y = geometry.CellSize(geotransform) cellx.append(str(x)) celly.append(str(abs(y))) self.metadata['cellx'] = ','.join(cellx) self.metadata['celly'] = ','.join(celly) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_md[m]) for m in hdf_md]) self.metadata['filesize'] = sum( [os.path.getsize(file) for file in self.filelist]) self.metadata['compressionratio'] = 0 self.metadata['compressiontype'] = 'None' self.extent = ext #Build gdaldataset object for overviews vrtcols = ncols[0] vrtrows = nrows[0] #vrtbands=[sd for sd,sn in hdf_sd[0:4]]#The 4 VNIR bands vrtbands = hdf_sd[0:4] #The 4 VNIR bands vrt = geometry.CreateSimpleVRT(vrtbands, vrtcols, vrtrows, datatypes.split(',')[0]) self._gdaldataset = geometry.OpenDataset(vrt) for i in range(1, 5): self._gdaldataset.GetRasterBand(i).SetNoDataValue(0)
def ali_l1g_hdf(self, f): self.metadata['level'] = 'L1G' self.metadata['sensor'] = 'ALI' self.metadata['sceneid'] = self.metadata['filename'].split('_')[0] gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver( ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() self.ncols = [] self.nrows = [] self.nbands = 0 bands = [] for sd, sz in hdf_sd: bands.append(sd) ds = geometry.OpenDataset(sd) self.ncols.append(str(ds.RasterXSize)) self.nrows.append(str(ds.RasterYSize)) self.nbands += 1 #get all multi bands for use in overview generation pancols = max(self.ncols) panindex = ncols.index(pancols) multibands = bands multincols = self.ncols multinrows = self.nrows if pancols > min(self.ncols): #there is a pan band multibands.pop(panindex) multincols.pop(panindex) multinrows.pop(panindex) multibands.sort() self._gdaldataset = geometry.OpenDataset( geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0], 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) self.ncols = ','.join(self.ncols) self.nrows = ','.join(self.nrows) met = f.lower().replace('_hdf.l1g', '_mtl.l1g') md = {} for line in open(met, 'r'): line = line.replace('"', '') line = [l.strip() for l in line.split('=')] if line[0] == 'END': #end of the metadata file break elif line[0] == 'GROUP': #start of a metadata group if line[1] != 'L1_METADATA_FILE': group = line[1] md[group] = {} elif line[0] == 'END_GROUP': #end of a metadata group pass else: #metadata value md[group][line[0]] = line[1] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON']) self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.prjext = self.geoext self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE'] self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][ 'RESAMPLING_OPTION'] try: self.metadata['viewangle'] = float( md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunazimuth'] = float( md['PRODUCT_PARAMETERS']['SUN_AZIMUTH']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunelevation'] = float( md['PRODUCT_PARAMETERS']['SUN_ELEVATION']) except: pass #Exception raised if value == 'UNAVAILABLE' #EPSG:32601: WGS 84 / UTM zone 1N #EPSG:32701: WGS 84 / UTM zone 1S srs = osr.SpatialReference() zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER']) if zone > 0: epsg = 32600 + zone #North else: epsg = 32700 - zone #South srs.ImportFromEPSG(epsg) self.metadata['units'] = 'm' self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = str(epsg)
def ali_l1g_tiff(self, f): self.metadata['level'] = 'L1G' self.metadata['sensor'] = 'ALI' self.metadata['sceneid'] = self.metadata['filename'].split('_')[0] self.metadata['filetype'] = 'GTiff/GeoTIFF' ncols = [] nrows = [] nbands = 0 bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif')) for band in bands: band = geometry.OpenDataset(band) ncols.append(str(band.RasterXSize)) nrows.append(str(band.RasterYSize)) nbands += 1 #rb=sd.GetRasterBand(1) #get all multi bands for use in overview generation pancols = max(ncols) panindex = ncols.index(pancols) multibands = bands multincols = ncols multinrows = nrows if pancols > min(ncols): #there is a pan band multibands.pop(panindex) multincols.pop(panindex) multinrows.pop(panindex) multibands.sort() self._gdaldataset = geometry.OpenDataset( geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0], 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) self.ncols = ','.join(ncols) self.nrows = ','.join(nrows) met = f md = {} for line in open(met, 'r'): line = line.replace('"', '') line = [l.strip() for l in line.split('=')] if line[0] == 'END': #end of the metadata file break elif line[0] == 'GROUP': #start of a metadata group if line[1] != 'L1_METADATA_FILE': group = line[1] md[group] = {} elif line[0] == 'END_GROUP': #end of a metadata group pass else: #metadata value md[group][line[0]] = line[1] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON']) self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX']) self.prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE'] self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][ 'RESAMPLING_OPTION'] try: self.metadata['viewangle'] = float( md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunazimuth'] = float( md['PRODUCT_PARAMETERS']['SUN_AZIMUTH']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunelevation'] = float( md['PRODUCT_PARAMETERS']['SUN_ELEVATION']) except: pass #Exception raised if value == 'UNAVAILABLE' #EPSG:32601: WGS 84 / UTM zone 1N #EPSG:32701: WGS 84 / UTM zone 1S srs = osr.SpatialReference() zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER']) if zone > 0: epsg = 32600 + zone #North else: epsg = 32700 - zone #South srs.ImportFromEPSG(epsg) self.metadata['units'] = 'm' self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = str(epsg)
def ali_l1r(self, f): self.metadata['level'] = 'L1R' self.metadata['sensor'] = 'ALI' gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver( ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = 4326 self.metadata['units'] = 'deg' hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() self.nbands = sd.RasterCount self.ncols = str( sd.RasterXSize * 4 - 30 ) #Account for the four SCA strips and the overlap between SCA strips self.nrows = sd_md[ 'Number of along track pixels'] #sd.RasterYSize is incorrect if len(hdf_sd) == 6: #Includes pan band (3 sds each) sd, sz = hdf_sd[3] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() cols = str( int(sd_md['Number of cross track pixels']) * 4 - 30 ) #Account for the four SCA strips and the overlap between SCA strips rows = sd_md['Number of along track pixels'] #set up to create multispectral only self._gdaldatset for overview generation if self.nbands == 1: multi = 3 multibands = sd_md['Number of bands'] multicols = cols multirows = rows else: multi = 0 multibands = self.nbands multicols = self.ncols multirows = self.nrows multibands = range(1, int(multibands) + 1) #Make a csv list of cols, bands self.ncols = [self.ncols for i in range(0, self.nbands)] self.nrows = [self.nrows for i in range(0, self.nbands)] self.ncols.extend([cols for i in range(0, sd.RasterCount)]) self.nrows.extend([rows for i in range(0, sd.RasterCount)]) #nbands='%s,%s' % (nbands, sd_md['Number of bands']) self.nbands = self.nbands + int(sd_md['Number of bands']) self.ncols = ','.join(self.ncols) self.nrows = ','.join(self.nrows) else: #set up to create multispectral only _gdaldatset for overview generation multi = 0 multibands = range(1, self.nbands + 1) multicols = self.ncols multirows = self.nrows #create multispectral only _gdaldatset for overview generation #Get all the data files and mosaic the strips #strips=[s for s in utilities.rglob(os.path.dirname(f),r'\.m[1-4]r$',True,re.I,False)] strips = glob.glob(os.path.join(os.path.dirname(f), '*.m[1-4]r')) strips.sort() strips.reverse() #west->east = *.m4r-m1 scols = (int(multicols) + 30) / 4 # +30 handles the 10 pixel overlap xoff = 10 yoff = 400 srows = int(multirows) - yoff srcrects = [[0, yoff, scols, srows]] * 4 dstrects = [] srcrect = [0, yoff, scols, srows] #dstrect=[None,0,scols,srows] files = [] sd, sz = hdf_sd[multi] vrt_opts = [] indatasetlist = [] for i in range(0, 4): files.append(sd.replace(f, strips[i])) dstrects.append([i * (scols - xoff), 0, scols, srows]) self._gdaldataset = geometry.OpenDataset( geometry.CreateMosaicedVRT(files, multibands, srcrects, dstrects, multicols, srows, 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) #Extract other metadata met = os.path.splitext(f)[0] + '.met' for line in open(met, 'r').readlines(): if line[0:16] == 'Scene Request ID': line = line.strip().split() self.metadata['sceneid'] = line[3] if line[0:14] == 'ALI Start Time': line = line.strip().split() hdf_md['ImageStartTime'] = line[3] + line[4] if line[0:8] == 'PRODUCT_': line = line.strip() line = map(string.strip, line.split('=')) if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1]) if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1]) self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.prjext = self.geoext
def hyp_l1r(self, f): self.metadata['level'] = 'L1R' self.metadata['sensor'] = 'HYPERION' gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver( ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = 4326 self.metadata['units'] = 'deg' hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() if hdf_sd: #gdal <=1.10.x sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() else: #gdal >=1.11.0 sd = gdalDataset sd_md = hdf_md self.nbands = sd.RasterCount self.ncols = sd.RasterXSize self.nrows = sd.RasterYSize met = os.path.splitext(f)[0] + '.met' for line in open(met, 'r').readlines(): if line[0:16] == 'Scene Request ID': line = line.strip().split() self.metadata['sceneid'] = line[3] if line[0:14] == 'HYP Start Time': line = line.strip().split() imgdate = time.strptime(line[3] + line[4], '%Y%j') self.metadata['imgdate'] = time.strftime('%Y-%m-%d', imgdate) #ISO 8601 if line[0:8] == 'PRODUCT_': line = line.strip() line = map(string.strip, line.split('=')) if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1]) if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1]) self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.prjext = self.geoext ######################################################################################################### ##set self._gdaldataset for use in overview generation ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm) ##as they're near the center of the equivalent ALI bands ##This generates verrrryyy looong overviews cos hyperion data is one long thin strip eg. 256*3000 etc... #self._gdaldataset = geometry.CreateVRTCopy(sd) ##Instead we can clip out some of the centre rows #vrtcols=ncols #vrtrows=int(ncols*1.5) #srcrect=[0, int(nrows/2-vrtrows/2),ncols,vrtrows] #dstrect=[0, 0,ncols,vrtrows] ##Or we can fill out the ncols with nodata vrtcols = int(self.nrows / 1.5) vrtrows = self.nrows srcrect = [0, 0, self.ncols, self.nrows] dstrect = [ int(self.nrows / 2.5 - self.ncols), 0, self.ncols, self.nrows ] vrt = geometry.CreateMosaicedVRT([sd.GetDescription()], [43, 30, 21], [srcrect], [dstrect], vrtcols, vrtrows, self.metadata['datatype']) self._gdaldataset = geometry.OpenDataset(vrt) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(1).SetNoDataValue(0) self._stretch = ('STDDEV', (1, 2, 3), [2])
def __getmetadata__(self): '''Read Metadata for recognised EO1 ALI (L1G & L1R) & Hyperion (L1R) images as GDAL doesn't''' f = self.fileinfo['filepath'] self.metadata['satellite'] = 'E01' self.metadata['nbits'] = 16 self.metadata['datatype'] = 'Int16' self.metadata['nodata'] = 0 if re.search(r'\.m[1-4]r$', f, re.I): self.metadata['level'] = 'L1R' self.metadata['sensor'] = 'ALI' gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % ( gdalDataset.GetDriver().ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = 4326 self.metadata['units'] = 'deg' hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() nbands = sd.RasterCount ncols = str( sd.RasterXSize * 4 - 30 ) #Account for the four SCA strips and the overlap between SCA strips nrows = sd_md[ 'Number of along track pixels'] #sd.RasterYSize is incorrect if len(hdf_sd) == 6: #Includes pan band (3 sds each) sd, sz = hdf_sd[3] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() cols = str( int(sd_md['Number of cross track pixels']) * 4 - 30 ) #Account for the four SCA strips and the overlap between SCA strips rows = sd_md['Number of along track pixels'] #set up to create multispectral only self._gdaldatset for overview generation if nbands == 1: multi = 3 multibands = sd_md['Number of bands'] multicols = cols multirows = rows else: multi = 0 multibands = nbands multicols = ncols multirows = nrows multibands = range(1, int(multibands) + 1) #Make a csv list of cols, bands ncols = [ncols for i in range(0, nbands)] nrows = [nrows for i in range(0, nbands)] ncols.extend([cols for i in range(0, sd.RasterCount)]) nrows.extend([rows for i in range(0, sd.RasterCount)]) #nbands='%s,%s' % (nbands, sd_md['Number of bands']) nbands = nbands + int(sd_md['Number of bands']) ncols = ','.join(ncols) nrows = ','.join(nrows) else: #set up to create multispectral only _gdaldatset for overview generation multi = 0 multibands = range(1, nbands + 1) multicols = ncols multirows = nrows #create multispectral only _gdaldatset for overview generation #Get all the data files and mosaic the strips #strips=[s for s in utilities.rglob(os.path.dirname(f),r'\.m[1-4]r$',True,re.I,False)] strips = glob.glob(os.path.join(os.path.dirname(f), '*.m[1-4]r')) strips.sort() strips.reverse() #west->east = *.m4r-m1 scols = (int(multicols) + 30) / 4 # +30 handles the 10 pixel overlap xoff = 10 yoff = 400 srows = int(multirows) - yoff srcrects = [[0, yoff, scols, srows]] * 4 dstrects = [] srcrect = [0, yoff, scols, srows] #dstrect=[None,0,scols,srows] files = [] sd, sz = hdf_sd[multi] vrt_opts = [] indatasetlist = [] for i in range(0, 4): files.append(sd.replace(f, strips[i])) dstrects.append([i * (scols - xoff), 0, scols, srows]) self._gdaldataset = geometry.OpenDataset( geometry.CreateMosaicedVRT(files, multibands, srcrects, dstrects, multicols, srows, 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) #Extract other metadata met = os.path.splitext(f)[0] + '.met' for line in open(met, 'r').readlines(): if line[0:16] == 'Scene Request ID': line = line.strip().split() self.metadata['sceneid'] = line[3] if line[0:14] == 'ALI Start Time': line = line.strip().split() hdf_md['ImageStartTime'] = line[3] + line[4] if line[0:8] == 'PRODUCT_': line = line.strip() line = map(string.strip, line.split('=')) if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1]) if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1]) geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] prjext = geoext elif re.search(r'eo1.*_mtl\.tif$', f): self.metadata['level'] = 'L1G' self.metadata['sensor'] = 'ALI' self.metadata['sceneid'] = self.metadata['filename'].split('_')[0] self.metadata['filetype'] = 'GTiff/GeoTIFF' ncols = [] nrows = [] nbands = 0 bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif')) for band in bands: band = geometry.OpenDataset(band) ncols.append(str(band.RasterXSize)) nrows.append(str(band.RasterYSize)) nbands += 1 #rb=sd.GetRasterBand(1) #get all multi bands for use in overview generation pancols = max(ncols) panindex = ncols.index(pancols) multibands = bands multincols = ncols multinrows = nrows if pancols > min(ncols): #there is a pan band multibands.pop(panindex) multincols.pop(panindex) multinrows.pop(panindex) multibands.sort() self._gdaldataset = geometry.OpenDataset( geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0], 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) ncols = ','.join(ncols) nrows = ','.join(nrows) met = f md = {} for line in open(met, 'r'): line = line.replace('"', '') line = [l.strip() for l in line.split('=')] if line[0] == 'END': #end of the metadata file break elif line[0] == 'GROUP': #start of a metadata group if line[1] != 'L1_METADATA_FILE': group = line[1] md[group] = {} elif line[0] == 'END_GROUP': #end of a metadata group pass else: #metadata value md[group][line[0]] = line[1] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON']) geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX']) prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] self.metadata['imgdate'] = md['PRODUCT_METADATA'][ 'ACQUISITION_DATE'] self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][ 'RESAMPLING_OPTION'] try: self.metadata['viewangle'] = float( md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunazimuth'] = float( md['PRODUCT_PARAMETERS']['SUN_AZIMUTH']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunelevation'] = float( md['PRODUCT_PARAMETERS']['SUN_ELEVATION']) except: pass #Exception raised if value == 'UNAVAILABLE' #EPSG:32601: WGS 84 / UTM zone 1N #EPSG:32701: WGS 84 / UTM zone 1S srs = osr.SpatialReference() zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER']) if zone > 0: epsg = 32600 + zone #North else: epsg = 32700 - zone #South srs.ImportFromEPSG(epsg) self.metadata['units'] = 'm' self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = str(epsg) elif re.search(r'eo1.*_hdf\.l1g$', f): self.metadata['level'] = 'L1G' self.metadata['sensor'] = 'ALI' self.metadata['sceneid'] = self.metadata['filename'].split('_')[0] gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % ( gdalDataset.GetDriver().ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() ncols = [] nrows = [] nbands = 0 bands = [] for sd, sz in hdf_sd: bands.append(sd) ds = geometry.OpenDataset(sd) ncols.append(str(ds.RasterXSize)) nrows.append(str(ds.RasterYSize)) nbands += 1 #get all multi bands for use in overview generation pancols = max(ncols) panindex = ncols.index(pancols) multibands = bands multincols = ncols multinrows = nrows if pancols > min(ncols): #there is a pan band multibands.pop(panindex) multincols.pop(panindex) multinrows.pop(panindex) multibands.sort() self._gdaldataset = geometry.OpenDataset( geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0], 'Int16')) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(4).SetNoDataValue(0) self._stretch = ('STDDEV', (4, 3, 2), [2]) ncols = ','.join(ncols) nrows = ','.join(nrows) met = f.lower().replace('_hdf.l1g', '_mtl.l1g') md = {} for line in open(met, 'r'): line = line.replace('"', '') line = [l.strip() for l in line.split('=')] if line[0] == 'END': #end of the metadata file break elif line[0] == 'GROUP': #start of a metadata group if line[1] != 'L1_METADATA_FILE': group = line[1] md[group] = {} elif line[0] == 'END_GROUP': #end of a metadata group pass else: #metadata value md[group][line[0]] = line[1] uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT']) ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON']) ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT']) urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON']) lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT']) lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON']) lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT']) llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON']) geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] prjext = geoext self.metadata['imgdate'] = md['PRODUCT_METADATA'][ 'ACQUISITION_DATE'] self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][ 'RESAMPLING_OPTION'] try: self.metadata['viewangle'] = float( md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunazimuth'] = float( md['PRODUCT_PARAMETERS']['SUN_AZIMUTH']) except: pass #Exception raised if value == 'UNAVAILABLE' try: self.metadata['sunelevation'] = float( md['PRODUCT_PARAMETERS']['SUN_ELEVATION']) except: pass #Exception raised if value == 'UNAVAILABLE' #EPSG:32601: WGS 84 / UTM zone 1N #EPSG:32701: WGS 84 / UTM zone 1S srs = osr.SpatialReference() zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER']) if zone > 0: epsg = 32600 + zone #North else: epsg = 32700 - zone #South srs.ImportFromEPSG(epsg) self.metadata['units'] = 'm' self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = str(epsg) else: self.metadata['level'] = 'L1R' self.metadata['sensor'] = 'HYPERION' gdalDataset = geometry.OpenDataset(f) #if not gdalDataset: #Error now raised in geometry.OpenDataset # errmsg=gdal.GetLastErrorMsg() # raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip()) self.metadata['filetype'] = '%s/%s (%s %s)' % ( gdalDataset.GetDriver().ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'], self.metadata['level']) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['epsg'] = 4326 self.metadata['units'] = 'deg' hdf_sd = gdalDataset.GetSubDatasets() hdf_md = gdalDataset.GetMetadata() sd, sz = hdf_sd[0] sd = geometry.OpenDataset(sd) sd_md = sd.GetMetadata() nbands = sd.RasterCount ncols = sd.RasterXSize nrows = sd.RasterYSize met = os.path.splitext(f)[0] + '.met' for line in open(met, 'r').readlines(): if line[0:16] == 'Scene Request ID': line = line.strip().split() self.metadata['sceneid'] = line[3] if line[0:14] == 'HYP Start Time': line = line.strip().split() imgdate = time.strptime(line[3] + line[4], '%Y%j') self.metadata['imgdate'] = time.strftime( '%Y-%m-%d', imgdate) #ISO 8601 if line[0:8] == 'PRODUCT_': line = line.strip() line = map(string.strip, line.split('=')) if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1]) if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1]) if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1]) if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1]) if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1]) geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] prjext = geoext ######################################################################################################### ##set self._gdaldataset for use in overview generation ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm) ##as they're near the center of the equivalent ALI bands ##This generates verrrryyy looong overviews cos hyperion data is one long thin strip eg. 256*3000 etc... #self._gdaldataset = geometry.CreateVRTCopy(sd) ##Instead we can clip out some of the centre rows #vrtcols=ncols #vrtrows=int(ncols*1.5) #srcrect=[0, int(nrows/2-vrtrows/2),ncols,vrtrows] #dstrect=[0, 0,ncols,vrtrows] ##Or we can fill out the ncols with nodata vrtcols = int(nrows / 1.5) vrtrows = nrows srcrect = [0, 0, ncols, nrows] dstrect = [int(nrows / 2.5 - ncols), 0, ncols, nrows] vrt = geometry.CreateMosaicedVRT([sd.GetDescription()], [43, 30, 21], [srcrect], [dstrect], vrtcols, vrtrows, self.metadata['datatype']) self._gdaldataset = geometry.OpenDataset(vrt) self._gdaldataset.GetRasterBand(3).SetNoDataValue(0) self._gdaldataset.GetRasterBand(2).SetNoDataValue(0) self._gdaldataset.GetRasterBand(1).SetNoDataValue(0) self._stretch = ('STDDEV', (1, 2, 3), [2]) ######################################################################################################### self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands #Geotransform ncols = map(int, str(ncols).split(',')) nrows = map(int, str(nrows).split(',')) cellx, celly = [], [] j = 0 while j < len(ncols): gcps = [] i = 0 lr = [[0, 0], [ncols[j], 0], [ncols[j], nrows[j]], [0, nrows[j]]] while i < len(prjext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = prjext[i] gcp.Id = str(i) gcps.append(gcp) i += 1 j += 1 geotransform = gdal.GCPsToGeoTransform(gcps) x, y = geometry.CellSize(geotransform) cellx.append(str(x)) celly.append(str(abs(y))) self.metadata['cellx'] = ','.join(cellx) self.metadata['celly'] = ','.join(celly) self.metadata['UL'] = '%s,%s' % tuple(geoext[0]) self.metadata['UR'] = '%s,%s' % tuple(geoext[1]) self.metadata['LR'] = '%s,%s' % tuple(geoext[2]) self.metadata['LL'] = '%s,%s' % tuple(geoext[3]) self.metadata['rotation'] = geometry.Rotation(geotransform) if abs(self.metadata['rotation']) < 1.0: self.metadata['orientation'] = 'Map oriented' self.metadata['rotation'] = 0.0 else: self.metadata['orientation'] = 'Path oriented' self.metadata['filesize'] = sum( [os.path.getsize(tmp) for tmp in self.filelist]) self.metadata['compressionratio'] = 0 self.metadata['compressiontype'] = 'None' self.extent = geoext
def getoverview(ds,outfile,width,format,bands,stretch_type,*stretch_args): ''' Generate overviews for imagery @type ds: C{GDALDataset} @param ds: a GDALDataset object @type outfile: C{str} @param outfile: a filepath to the output overview image. If supplied, format is determined from the file extension @type width: C{int} @param width: output image width @type format: C{str} @param format: format to generate overview image, one of ['JPG','PNG','GIF','BMP','TIF']. Not required if outfile is supplied. @type bands: C{list} @param bands: list of band numbers (base 1) in processing order - e.g [3,2,1] @type stretch_type: C{str} @param stretch_type: stretch to apply to overview image, one of [L{NONE<_stretch_NONE>},L{PERCENT<_stretch_PERCENT>},L{MINMAX<_stretch_MINMAX>},L{STDDEV<_stretch_STDDEV>},L{COLOURTABLE<_stretch_COLOURTABLE>},L{COLOURTABLELUT<_stretch_COLOURTABLELUT>},L{RANDOM<_stretch_RANDOM>},L{UNIQUE<_stretch_UNIQUE>}]. @type stretch_args: C{list} @param stretch_args: args to pass to the stretch algorithms @rtype: C{str} @return: filepath (if outfile is supplied)/binary image data (if outfile is not supplied) ''' #mapping table for file extension -> GDAL format code imageformats={'JPG':'JPEG', #JPEG JFIF (.jpg) 'PNG':'PNG', #Portable Network Graphics (.png) 'GIF':'GIF', #Graphics Interchange Format (.gif) 'BMP':'BMP', #Microsoft Windows Device Independent Bitmap (.bmp) 'TIF':'GTiff' #Tagged Image File Format/GeoTIFF (.tif) } if outfile: outfile=utilities.encode(outfile) format=os.path.splitext(outfile)[1].replace('.','') #overrides "format" arg if supplied ovdriver=gdal.GetDriverByName(imageformats.get(format.upper(), 'JPEG')) #Get format code, default to 'JPEG' if supplied format doesn't match the predefined ones... cols=ds.RasterXSize rows=ds.RasterYSize vrtcols=width vrtrows=int(math.ceil(width*float(rows)/cols)) vrtdrv=gdal.GetDriverByName('VRT') tempvrts={} #dict with keys=file descriptor and values=[filename,GDALDataset] #Below is a bit of a kludge to handle creating a VRT that is based on an in-memory vrt file drv=ds.GetDriver().ShortName desc=ds.GetDescription() if drv == 'VRT': if not desc or desc[0] == '<':# input path is an in-memory vrt file vrtfd,vrtfn=tempfile.mkstemp('.vrt') ds=vrtdrv.CreateCopy(vrtfn,ds) tempvrts[vrtfd]=[vrtfn,ds] #if stretch_type != 'NONE': # tmpxml=stretch('NONE',vrtcols,vrtrows,ds,bands) # vrtfd,vrtfn=tempfile.mkstemp('.vrt') # ds=vrtdrv.CreateCopy(vrtfn,geometry.OpenDataset(tmpxml)) # tempvrts[vrtfd]=[vrtfn,ds] vrtxml=stretch(stretch_type,vrtcols,vrtrows,ds,bands,*stretch_args) vrtds=geometry.OpenDataset(vrtxml) if outfile: cpds=ovdriver.CreateCopy(outfile, vrtds) if not cpds:raise geometry.GDALError, 'Unable to generate overview image.' else: fd,fn=tempfile.mkstemp(suffix='.'+format.lower(), prefix='getoverviewtempimage') cpds=ovdriver.CreateCopy(fn, vrtds) if not cpds:raise geometry.GDALError, 'Unable to generate overview image.' outfile=os.fdopen(fd).read() os.unlink(fn) for vrt in tempvrts: tempvrts[vrt][1]=None os.close(vrt) del tempvrts[vrt][1] os.unlink(tempvrts[vrt][0]) return outfile
def __getmetadata__(self,f=None): '''Populate metadata''' if not f:f=self.fileinfo['filepath'] self._gdaldataset = geometry.OpenDataset(f) led=glob.glob(os.path.dirname(f) + '/[Ll][Ee][Aa][Dd]*')[0] #volume file meta = open(led,'rb').read() ###################### # Scene header record ###################### record=2 recordlength=3960 #SPOT recordlength=3960 ################## #SCENE PARAMETERS ################## sceneid=utilities.readbinary(meta,(record-1)*recordlength,37,52) cy=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,85,100),'HDDDMMSS') #Latitude of the Scene Centre cx=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,101,116),'HDDDMMSS') #Longitude of the Scene Centre uly=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,149,164),'HDDDMMSS') ulx=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,165,180),'HDDDMMSS') ury=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,213,228),'HDDDMMSS') urx=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,229,244),'HDDDMMSS') lly=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,277,292),'HDDDMMSS') llx=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,293,308),'HDDDMMSS') lry=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,341,356),'HDDDMMSS') lrx=geometry.DMS2DD(utilities.readbinary(meta,(record-1)*recordlength,357,372),'HDDDMMSS') ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] ###################### #IMAGING PARAMETERS ###################### self.metadata['rotation']=float(utilities.readbinary(meta,(record-1)*recordlength,437,452)) if abs(self.metadata['rotation']) < 1: self.metadata['orientation']='Map oriented' self.metadata['rotation']=0.0 else:self.metadata['orientation']='Path oriented' self.metadata['sunazimuth']=float(utilities.readbinary(meta,(record-1)*recordlength,469,484)) self.metadata['sunelevation']=float(utilities.readbinary(meta,(record-1)*recordlength,485,500)) imgdate=utilities.readbinary(meta,(record-1)*recordlength,581,612) #self.metadata['imgdate']=time.strftime(utilities.dateformat,time.strptime(imgdate[0:8],'%Y%m%d')) #ISO 8601 self.metadata['imgdate']=time.strftime(utilities.datetimeformat,time.strptime(imgdate[0:14],'%Y%m%d%H%M%S')) #ISO 8601 satellite=utilities.readbinary(meta,(record-1)*recordlength,613,628) sensor=utilities.readbinary(meta,(record-1)*recordlength,629,644) mode=utilities.readbinary(meta,(record-1)*recordlength,645,660) ###################### #IMAGE PARAMETERS ###################### ncols=int(utilities.readbinary(meta,(record-1)*recordlength,997,1012)) nrows=int(utilities.readbinary(meta,(record-1)*recordlength,1013,1028)) nbands=int(utilities.readbinary(meta,(record-1)*recordlength,1045,1060)) bands=utilities.readbinary(meta,(record-1)*recordlength,1061,1316).replace(' ',',') self.metadata['level']=utilities.readbinary(meta,(record-1)*recordlength,1317,1332) self.metadata['resampling']=utilities.readbinary(meta,(record-1)*recordlength,1365,1380) if self.metadata['level']=='1A': #Not geometrically corrected. Cell size isn't really appropriate gcps=geometry.ExtentToGCPs(ext,ncols,nrows) gt=gdal.GCPsToGeoTransform(gcps) cellx,celly=geometry.CellSize(gt) else: cellx=float(utilities.readbinary(meta,(record-1)*recordlength,1381,1396)) celly=float(utilities.readbinary(meta,(record-1)*recordlength,1397,1412)) ################################################# #Ancillary "Ephemeris / Attitude" record, ################################################# record=3 viewangle=float(utilities.readbinary(meta,(record-1)*recordlength,3065,3076)) ################################################# #Map projection (scene-related) ancillary record ################################################# record=26 projection = utilities.readbinary(meta,(record-1)*recordlength,21,52).replace('\x00','') ellipsoid = utilities.readbinary(meta,(record-1)*recordlength,57,88).replace('\x00','') datum = utilities.readbinary(meta,(record-1)*recordlength,101,132).replace('\x00','') if 'UTM' in projection: # UTM type='UTM' units='m' zone=projection[3:-1] if not zone: zone=str(spatialreferences.lon2utmzone(cx)) if 'GDA' in datum: epsg=int('283'+zone) elif 'AGD' in datum: epsg=int('202'+zone) elif 'WGS' in datum: epsg=int('327'+zone) if projection[-1] =='S' else int('326'+zone) else: #Assume type='GEO' units='deg' if datum=='GDA94':epsg=4283 else:epsg=4326 #Assume WGS84 if 'GDA' in datum: epsg=4283 elif 'AGD' in datum: epsg=202 else: epsg=4326 #Assume WGS84' #cell sizes are reported in metres even for geo projections gcps=[];i=0 lr=[[0,0],[ncols,0],[ncols,nrows],[0,nrows]] while i < len(ext)-1: #don't need the last xy pair gcp=gdal.GCP() gcp.GCPPixel,gcp.GCPLine=lr[i] gcp.GCPX,gcp.GCPY=ext[i] gcp.Id=str(i) gcps.append(gcp) i+=1 geotransform = gdal.GCPsToGeoTransform(gcps) cellx,celly=geometry.CellSize(geotransform) rotation=geometry.Rotation(geotransform) srs = osr.SpatialReference() srs.ImportFromEPSG(epsg) srs=srs.ExportToWkt() self.metadata['satellite']=satellite self.metadata['sensor']=sensor self.metadata['filetype'] ='CEOS/SPOT CCT Format' self.metadata['filesize']=sum([os.path.getsize(file) for file in self.filelist]) self.metadata['sceneid'] = sceneid self.metadata['srs'] = srs self.metadata['epsg'] = epsg self.metadata['units'] = units self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands self.metadata['bands'] = bands self.metadata['nbits'] = 8 self.metadata['datatype'] = 'Byte' self.metadata['nodata'] = 0 self.metadata['mode'] = mode self.metadata['cellx'],self.metadata['celly']=map(float,[cellx,celly]) self.metadata['UL']='%s,%s' % tuple(ext[0]) self.metadata['UR']='%s,%s' % tuple(ext[1]) self.metadata['LR']='%s,%s' % tuple(ext[2]) self.metadata['LL']='%s,%s' % tuple(ext[3]) metadata=self._gdaldataset.GetMetadata() self.metadata['metadata']='\n'.join(['%s: %s' %(m,hdf_self.metadata[m]) for m in metadata]) self.metadata['compressionratio']=0 self.metadata['compressiontype']='None' self.extent=ext
def __getmetadata__(self, f=None): ''' Generate metadata for generic imagery @type f: string @param f: a filepath to the dataset or a VRT XML string @return: None @todo: We force a NoData value. This is not ideal, but it makes for better overview images. ''' if not f: f = self.fileinfo['filepath'] try: cwd = os.path.abspath(os.curdir) if os.path.exists(f) and os.path.dirname(f): p = os.path.split(f)[0] os.chdir(p) if not self._gdaldataset: self._gdaldataset = geometry.OpenDataset( f ) #in case we're subclassed and there's already a dataset open if self._gdaldataset: driver = self._gdaldataset.GetDriver().ShortName if driver[0:3] == 'HDF': raise NotImplementedError, 'HDF files are not yet implemented except by custom formats' self.metadata[ 'filetype'] = driver + '/' + self._gdaldataset.GetDriver( ).LongName self.metadata['cols'] = self._gdaldataset.RasterXSize self.metadata['rows'] = self._gdaldataset.RasterYSize self.metadata['nbands'] = self._gdaldataset.RasterCount self.metadata['srs'] = self._gdaldataset.GetProjection() if not self.metadata['srs'] and self._gdaldataset.GetGCPCount( ) > 0: self.metadata['srs'] = self._gdaldataset.GetGCPProjection() self.metadata['epsg'] = spatialreferences.IdentifyAusEPSG( self.metadata['srs']) self.metadata['units'] = spatialreferences.GetLinearUnitsName( self.metadata['srs']) geotransform = self._gdaldataset.GetGeoTransform() if geotransform == (0, 1, 0, 0, 0, 1): if self._gdaldataset.GetGCPCount() > 0: gcps = self._gdaldataset.GetGCPs() geotransform = gdal.GCPsToGeoTransform(gcps) gcps = geometry.GeoTransformToGCPs( geotransform, self.metadata['cols'], self. metadata['rows']) #Just get the 4 corner GCP's else: raise NotImplementedError, 'Dataset is not georeferenced' else: gcps = geometry.GeoTransformToGCPs(geotransform, self.metadata['cols'], self.metadata['rows']) ext = [[gcp.GCPX, gcp.GCPY] for gcp in gcps] ext.append([gcps[0].GCPX, gcps[0].GCPY ]) #Add the 1st point to close the polygon) #Reproject corners to lon,lat geom = geometry.GeomFromExtent(ext) src_srs = osr.SpatialReference() src_srs.ImportFromWkt(self.metadata['srs']) tgt_srs = osr.SpatialReference() tgt_srs.ImportFromEPSG(4326) geom = geometry.ReprojectGeom(geom, src_srs, tgt_srs) points = geom.GetGeometryRef(0) #geom.GetBoundary() ext = [[points.GetX(i), points.GetY(i)] for i in range(0, points.GetPointCount())] self.metadata['cellx'], self.metadata[ 'celly'] = geometry.CellSize(geotransform) self.metadata['rotation'] = geometry.Rotation(geotransform) if abs(self.metadata['rotation']) < 1.0: self.metadata['orientation'] = 'Map oriented' self.metadata['rotation'] = 0.0 else: self.metadata['orientation'] = 'Path oriented' self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['LL'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['UR'] = '%s,%s' % tuple(ext[3]) rb = self._gdaldataset.GetRasterBand(1) if rb: self.metadata['datatype'] = gdal.GetDataTypeName( rb.DataType) self.metadata['nbits'] = gdal.GetDataTypeSize(rb.DataType) nodata = rb.GetNoDataValue() if nodata is not None: self.metadata['nodata'] = str(nodata) else: ct = rb.GetColorTable() #Fix for Issue 31 if ct is None: if self.metadata['datatype'][0:4] in [ 'Byte', 'UInt' ]: nodata = 0 #Unsigned, assume 0 else: nodata = -2**( self.metadata['nbits'] - 1 ) #Signed, assume min value in data range self.metadata['nodata'] = str(nodata) #Fix for Issue 17 for i in range(1, self._gdaldataset.RasterCount + 1): self._gdaldataset.GetRasterBand( i).SetNoDataValue(nodata) else: raise IOError, 'No valid rasterbands found.' metadata = self._gdaldataset.GetMetadata() self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, metadata[m]) for m in metadata]) self.metadata['filesize'] = sum( [os.path.getsize(tmp) for tmp in self.filelist]) if self.metadata['filesize'] > 0: self.metadata['compressionratio'] = int( (self.metadata['nbands'] * self.metadata['cols'] * self.metadata['rows'] * (self.metadata['nbits'] / 8.0)) / self.metadata['filesize']) if self.metadata['compressionratio'] > 0: try: if driver[0:3] == 'JP2': self.metadata['compressiontype'] = "JPEG2000" elif driver[0:3] == 'ECW': self.metadata['compressiontype'] = "ECW" else: mdis = self._gdaldataset.GetMetadata( 'IMAGE_STRUCTURE') #self.metadata['compressiontype']=mdis['IMAGE_STRUCTURE'] self.metadata['compressiontype'] = mdis[ 'COMPRESSION'] except: self.metadata['compressiontype'] = 'Unknown' else: self.metadata['compressiontype'] = 'None' self.extent = ext else: errmsg = gdal.GetLastErrorMsg() raise IOError, 'Unable to open %s\n%s' % (f, errmsg.strip()) finally: #Cleanup gdal.ErrorReset() os.chdir(cwd)
def __getmetadata__(self, f=None): '''Populate the metadata''' if not f: f = self.fileinfo['filepath'] self._gdaldataset = geometry.OpenDataset(f) led = glob.glob(os.path.dirname(f) + '/[Ll][Ee][Aa][Dd]*')[0] #volume file meta = open(led, 'rb').read() ''' metadata has 4 records, each is 4320 (LS) or 6120 (SPOT) bytes long: File descriptor record; Scene header record; Map projection (scene-related) ancillary record; Radiometric transformation ancillary record. ''' #Record 2 - Scene header record record = 2 recordlength = 4320 #LS 5 satellite = utilities.readbinary(meta, (record - 1) * recordlength, 309, 324) #Scene ID, path/row & image date/time start, stop = 37, 52 sceneid = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) start, stop = 165, 180 pathrow = utilities.readbinary(meta, (record - 1) * recordlength, start, stop)[1:] start, stop = 117, 148 imgdate = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) self.metadata['imgdate'] = time.strftime( utilities.datetimeformat, time.strptime(imgdate[0:14], '%Y%m%d%H%M%S')) #ISO 8601 #Ascending/descending flag start, stop = 357, 372 if utilities.readbinary(meta, (record - 1) * recordlength, start, stop) == 'D': self.metadata['orbit'] = 'Descending' else: self.metadata['orbit'] = 'Ascending' #Processing level start, stop = 1573, 1588 self.metadata['level'] = utilities.readbinary( meta, (record - 1) * recordlength, start, stop) #Bands start, stop = 1653, 1659 bands = [] actbands = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) for i in range(0, 7): #Loop thru the 7 LS 5 bands if actbands[i] == '1': bands.append(str(i + 1)) self._gdaldataset.GetRasterBand(i + 1).SetNoDataValue(0) #Record 3 - Map projection (scene-related) ancillary record record = 3 #Bands, rows & columns and rotation nbands = int(self._gdaldataset.RasterCount) start, stop = 333, 348 ncols = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 349, 364 nrows = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 445, 460 self.metadata['rotation'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) if abs(self.metadata['rotation']) < 1: self.metadata['orientation'] = 'Map oriented' self.metadata['rotation'] = 0.0 else: self.metadata['orientation'] = 'Path oriented' #Sun elevation and azimuth start, stop = 605, 620 self.metadata['sunelevation'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 621, 636 self.metadata['sunazimuth'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) #geometry.CellSizes start, stop = 365, 396 (cellx, celly) = map( float, utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split()) start, stop = 397, 412 projection = utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split() datum = projection[0] zone = projection[1] # lat/lons start, stop = 765, 892 coords = utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split() uly, ulx, ury, urx, lry, lrx, lly, llx = map(float, coords) ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] if int(zone) != 0: # UTM type = 'UTM' units = 'm' #start,stop = 637,764 #coords = utilities.readbinary(meta,(record-1)*recordlength,start,stop).split() #uly,ulx,ury,urx,lry,lrx,lly,llx = map(float, coords) #ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] if datum == 'GDA94': epsg = int('283' + zone) elif datum == 'AGD66': epsg = int('202' + zone) elif datum == 'WGS84': epsg = int('327' + zone) else: #Assume type = 'GEO' units = 'deg' if datum == 'GDA94': epsg = 4283 else: epsg = 4326 #Assume WGS84 gcps = [] i = 0 lr = [[0, 0], [ncols, 0], [ncols, nrows], [0, nrows]] while i < len(ext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = ext[i] gcp.Id = str(i) gcps.append(gcp) i += 1 geotransform = gdal.GCPsToGeoTransform(gcps) cellx, celly = geometry.CellSize(geotransform) rotation = geometry.Rotation(geotransform) srs = osr.SpatialReference() srs.ImportFromEPSG(epsg) srs = srs.ExportToWkt() self.metadata['satellite'] = satellite if satellite == 'LANDSAT-5': self.metadata['sensor'] = 'TM' self.metadata['filetype'] = 'CEOS/Landsat CCRS Format' else: self.metadata['sensor'] = 'HRV' self.metadata['filetype'] = 'CEOS/SPOT CCRS Format' self.metadata['filesize'] = sum( [os.path.getsize(file) for file in self.filelist]) self.metadata['srs'] = srs self.metadata['epsg'] = epsg self.metadata['units'] = units self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands self.metadata['bands'] = ','.join(bands) self.metadata['nbits'] = 8 self.metadata['datatype'] = 'Byte' self.metadata['nodata'] = 0 self.metadata['cellx'], self.metadata['celly'] = map( float, [cellx, celly]) self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) metadata = self._gdaldataset.GetMetadata() self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_self.metadata[m]) for m in metadata]) self.metadata['compressionratio'] = 0 self.metadata['compressiontype'] = 'None' self.extent = ext
def __getmetadata__(self,f=None): '''Read Metadata for an ACRES ALOS AVNIR-2/PRISM/PALSAR format image as GDAL doesn't''' #Local copies for brevity vol=self._vol led=self._led if 'led-alpsr' in led.lower():driver='SAR_CEOS' else:driver='CEOS' extra_md={} #for holding any extra metadata which gets stuffed into self.metadata['metadata'] later on self.metadata['satellite']='ALOS' nodata = 0 #ACRES ortho product is in GTIFF format tif=False if driver=='SAR_CEOS': #PALSAR - assumes Level 1.5, Level 1.0 not implemented #Format Description #Level 1.0 - http://www.ga.gov.au/servlet/BigObjFileManager?bigobjid=GA10287 #Level 1.1/1.5 - http://www.eorc.jaxa.jp/ALOS/doc/fdata/PALSAR_x_Format_EK.pdf self.metadata['sensor']='PALSAR' self.metadata['filetype'] ='CEOS/ALOS PALSAR CEOS Format' ''' volume file has 3-6 records, 360 bytes length: Record Length ========================= 1 File descriptor 360 2 File pointer 360 (3-6 records = N+2 where N is number of polarization) 3 Text 360 ''' meta = open(vol,'rb').read() #File descriptor record offset = 0 #Number of file pointers npointers=int(utilities.readbinary(meta,offset,161,164)) #Text record offset = 360*(npointers+1) #Product type specifier start,stop = 17,56 prodspec = utilities.readbinary(meta,offset,start,stop)[8:] #Strip of the "'PRODUCT:" string if prodspec[1:4] != '1.5':raise Exception, 'ALOS PALSAR Level %s not yet implemented' % level if prodspec[0]=='H':self.metadata['mode']='Fine (high resolution) mode' elif prodspec[0]=='W':self.metadata['mode']='ScanSAR (wide observation) mode' elif prodspec[0]=='D':self.metadata['mode']='Direct Downlink mode' elif prodspec[0]=='P':self.metadata['mode']='Polarimetry mode' elif prodspec[0]=='C':self.metadata['mode']='Calibration mode' level=prodspec[1:5] orient=prodspec[4] if orient=='G':self.metadata['orientation']='Map oriented' else: self.metadata['orientation']='Path oriented' orbit=prodspec[6] ''' leader file has >9 records of variable length: Record Length ============================================ 1 File descriptor 720 2 Data set summary 4096 3 Map projection data 1620 4 Platform position data 4680 5 Attitude data 8192 6 Radiometric data 9860 7 Data quality summary 1620 8 Calibration data 13212 9 Facility related Variable ''' meta = open(led,'rb').read() #File descriptor offset = 0 #Data set summary offset = 720 #Scene ID start,stop = 21,52 sceneid = utilities.readbinary(meta,offset,start,stop) #Image date start,stop = 69,100 #imgdate=utilities.readbinary(meta,offset,start,stop)[0:14]#Strip off time #self.metadata['imgdate'] = time.strftime(utilities.dateformat,time.strptime(imgdate,'%Y%m%d')) #ISO 8601 imgdate=utilities.readbinary(meta,offset,start,stop)[0:14] #Keep time, strip off milliseconds self.metadata['imgdate'] = time.strftime(utilities.datetimeformat,time.strptime(imgdate,'%Y%m%d%H%M%S')) #SAR Channels start,stop = 389,392 nbands = int(utilities.readbinary(meta,offset,start,stop)) #Radar wavelength start,stop = 501,516 wavelen = utilities.readbinary(meta,offset,start,stop) extra_md['wavelength']=wavelen #Nominal offnadir angle start,stop = 1839,1854 self.metadata['viewangle'] = utilities.readbinary(meta,offset,start,stop) #Map projection data offset += 4096 #Cols & rows start,stop = 61,76 ncols = int(utilities.readbinary(meta,offset,start,stop)) start,stop = 77,92 nrows = int(utilities.readbinary(meta,offset,start,stop)) #cell sizes (metres) start,stop = 93,124 ypix,xpix = map(float,utilities.readbinary(meta,offset,start,stop).split()) #Orientation at output scene centre start,stop = 125,140 rot = math.radians(float(utilities.readbinary(meta,offset,start,stop))) #GeogCS src_srs=osr.SpatialReference() #src_srs.SetGeogCS('GRS 1980','GRS 1980','GRS 1980',6378137.00000,298.2572220972) src_srs.SetWellKnownGeogCS( "WGS84" ) #Proj CS start,stop = 413,444 projdesc = utilities.readbinary(meta,offset,start,stop) epsg=0#default if projdesc == 'UTM-PROJECTION': nZone = int(utilities.readbinary(meta,offset,477,480)) dfFalseNorthing = float(utilities.readbinary(meta,offset,497,512)) if dfFalseNorthing > 0.0: bNorth=False epsg=32700+nZone else: bNorth=True epsg=32600+nZone src_srs.ImportFromEPSG(epsg) #src_srs.SetUTM(nZone,bNorth) #generates WKT that osr.SpatialReference.AutoIdentifyEPSG() doesn't return an EPSG for elif projdesc == 'UPS-PROJECTION': dfCenterLon = float(utilities.readbinary(meta,offset,625,640)) dfCenterLat = float(utilities.readbinary(meta,offset,641,656)) dfScale = float(utilities.readbinary(meta,offset,657,672)) src_srs.SetPS(dfCenterLat,dfCenterLon,dfScale,0.0,0.0) elif projdesc == 'MER-PROJECTION': dfCenterLon = float(utilities.readbinary(meta,offset,737,752)) dfCenterLat = float(utilities.readbinary(meta,offset,753,768)) src_srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0) elif projdesc == 'LCC-PROJECTION': dfCenterLon = float(utilities.readbinary(meta,offset,737,752)) dfCenterLat = float(utilities.readbinary(meta,offset,753,768)) dfStdP1 = float(utilities.readbinary(meta,offset,769,784)) dfStdP2 = float(utilities.readbinary(meta,offset,785,800)) src_srs.SetLCC(dfStdP1,dfStdP2,dfCenterLat,dfCenterLon,0,0) srs=src_srs.ExportToWkt() if not epsg:epsg = spatialreferences.IdentifyAusEPSG(srs) units = spatialreferences.GetLinearUnitsName(srs) #UL-LR coords ##ext=[float(coord)*1000 for coord in utilities.readbinary(meta,offset,945,1072).split()] #Get lat/lon instead of eastings/northings ext=[float(coord) for coord in utilities.readbinary(meta,offset,1073,1200).split()] uly,ulx,ury,urx,lry,lrx,lly,llx=ext ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] #last xy pair closes the poly self.metadata['nbits'] = 16 self.metadata['datatype']='UInt16' #Generate a GDAL Dataset object self._gdaldataset=geometry.OpenDataset(self._imgs[0]) else: #ALOS AVNIR2/PRISM ##Format - http://www.ga.gov.au/servlet/BigObjFileManager?bigobjid=GA10285 ''' leader file has 5 records, each is 4680 bytes long: 1. File descriptor record; 2. Scene header record; 3. Map projection (scene-related) ancillary record; 4. Radiometric transformation ancillary record; 5. Platform position ancillary record. ''' #ACRES ortho product is in GTIFF format if '.tif' in self._imgs[0].lower(): tif=True level='ORTHOCORRECTED' __default__.Dataset.__getmetadata__(self, self._imgs[0]) meta = open(led,'rb').read() recordlength = 4680 #Record 2 - Scene header record record=2 #Processing level if not tif: start,stop = 21,36 procinfo = utilities.readbinary(meta,(record-1)*recordlength,start,stop) level=procinfo[1:4] #if level != '1B2':raise Exception, 'Level %s PRISM is not supported' % level self.metadata['level']==procinfo[1:4] opt=procinfo[4:6].strip().strip('_') if opt!='':level+='-'+opt #SceneID if level[0:3] == '1B2':start,stop = 197,212 else:start,stop = 37,52 sceneid = utilities.readbinary(meta,(record-1)*recordlength,start,stop) #Lat/Lon of scene center ##if level[0:3] == '1B2':start,stop = 245,276 ##else:start,stop = 85,116 ##cenrow, cencol=map(float,utilities.readbinary(meta,(record-1)*recordlength,start,stop).split()) #Line & Pixel number for scene center ##if level[0:3] == '1B2':start,stop = 245,276 ##else:start,stop = 85,116 ##cenrow, cencol=map(float,utilities.readbinary(meta,(record-1)*recordlength,start,stop).split()) #Orientation Angle NNN.N = degrees start,stop = 277,292 rot = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) #Ascending/descendit orbit start,stop = 357,372 orbit = utilities.readbinary(meta,(record-1)*recordlength,start,stop) #view, sun elevation and azimuth angles start,stop = 373,388 self.metadata['viewangle'] = utilities.readbinary(meta,(record-1)*recordlength,start,stop) start,stop = 453,466 sunangles = utilities.readbinary(meta,(record-1)*recordlength,start,stop) self.metadata['sunelevation'] = sunangles[6:9].strip() self.metadata['sunazimuth'] = sunangles[11:].strip() #Image aquisition date start,stop = 401,408 imgdate = utilities.readbinary(meta,(record-1)*recordlength,start,stop) imgdate = time.strptime(imgdate,'%d%b%y') #DDMmmYY self.metadata['imgdate'] = time.strftime(utilities.dateformat,imgdate) #ISO 8601 #Sensor type and bands start,stop = 443,452 sensor,bands=utilities.readbinary(meta,(record-1)*recordlength,start,stop).split() if sensor=='PSM': self.metadata['sensor']='PRISM' if sceneid[5] == 'N': extra_md['SENSOR DIRECTION']='Nadir 35km' elif sceneid[5] == 'W':extra_md['SENSOR DIRECTION']='Nadir 70km' elif sceneid[5] == 'F':extra_md['SENSOR DIRECTION']='Forward 35km' elif sceneid[5] == 'B':extra_md['SENSOR DIRECTION']='Backward 35km' else:self.metadata['sensor']='AVNIR-2' self.metadata['filetype'] ='CEOS/ALOS %s CEOS Format' % self.metadata['sensor'] self.metadata['bands']=','.join([band for band in bands]) #Processing info if not tif: start,stop = 467,478 procinfo = utilities.readbinary(meta,(record-1)*recordlength,start,stop) orient=procinfo[-1] if orient=='G':self.metadata['orientation']='Map oriented' else:self.metadata['orientation']='Path oriented' #No. bands start,stop = 1413,1428 nbands = int(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) #No. cols start,stop = 1429,1444 ncols = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) #No. rows start,stop = 1445,1460 nrows = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) #Resampling start,stop = 1541,1556 res = utilities.readbinary(meta,(record-1)*recordlength,start,stop) if res=='NNNNN':self.metadata['resampling']='' #Raw (L1A,L1B1) elif res=='YNNNN':self.metadata['resampling']='NN' #Nearest neighbour elif res=='NYNNN':self.metadata['resampling']='BL' #Bi-linear elif res=='NNYNN':self.metadata['resampling']='CC' #Cubic convolution #Lat/Lon extent start,stop = 1733,1860 coords = utilities.readbinary(meta,(record-1)*recordlength,start,stop).split() uly,ulx,ury,urx,lly,llx,lry,lrx = map(float, coords) ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] if not tif: #Record 3 record=3 #Hemisphere start,stop = 93,96 hemi = utilities.readbinary(meta,(record-1)*recordlength,start,stop) #UTM Zone - revisit if we get polarstereographic projection products start,stop = 97,108 utm = utilities.readbinary(meta,(record-1)*recordlength,start,stop) if hemi=='1': #South epsg=int('327%s' % utm) #Assume WGS84 else: #North epsg=int('326%s' % utm) src_srs = osr.SpatialReference() src_srs.ImportFromEPSG(epsg) units = 'm' #Scene center position - revisit if we get polarstereographic projection products ##start,stop = 141,156 ##ceny = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) * 1000 #(Northing - km) ##start,stop = 157,172 ##cenx = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) * 1000 #(Easting - km) #Orientation Angle NNN.N = radians start,stop = 205,220 rot = float(utilities.readbinary(meta,(record-1)*recordlength,start,stop)) #Pixel size (x) start,stop=541,572 xpix,ypix=map(float,utilities.readbinary(meta,(record-1)*recordlength,start,stop).split()) #Get extent of scene ##xmin=(cenx+xpix/2)-(cencol*xpix) ##ymin=(ceny+ypix/2)-(cenrow*ypix) ##xmax=xmin+(ncols*xpix) ##ymax=ymin+(nrows*ypix) ##if procinfo[-1]=='R': #Calculate rotated extent coordinates ## ##angc=math.cos(rot) ## ##angs=math.sin(rot) ## angc=math.cos(math.radians(rot)) ## angs=math.sin(math.radians(rot)) ## ulx = (xmin-cenx)*angc + (ymax-ceny)*angs+cenx ## uly = -(xmin-cenx)*angs + (ymax-ceny)*angc+ceny ## llx = (xmin-cenx)*angc + (ymin-ceny)*angs+cenx ## lly = -(xmin-cenx)*angs + (ymin-ceny)*angc+ceny ## urx = (xmax-cenx)*angc + (ymax-ceny)*angs+cenx ## ury = -(xmax-cenx)*angs + (ymax-ceny)*angc+ceny ## lrx = (xmax-cenx)*angc + (ymin-ceny)*angs+cenx ## lry = -(xmax-cenx)*angs + (ymin-ceny)*angc+ceny ##else: #Just use xmin etc... ## ulx,uly = xmin,ymax ## llx,lly = xmin,ymin ## urx,ury = xmax,ymax ## lrx,lry = xmax,ymin ##ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] #Geotransform ##gcps=[];i=0 ##lr=[[0,0],[ncols,0],[ncols,nrows],[0,nrows]] ##while i < len(ext)-1: #don't need the last xy pair ## gcp=gdal.GCP() ## gcp.GCPPixel,gcp.GCPLine=lr[i] ## gcp.GCPX,gcp.GCPY=ext[i] ## gcp.Id=str(i) ## gcps.append(gcp) ## i+=1 ##geotransform = gdal.GCPsToGeoTransform(gcps) self.metadata['nbits'] = 8 self.metadata['datatype'] = 'Byte' #Generate a VRT GDAL Dataset object self._imgs.sort() img=self._imgs[0] meta = open(img,'rb').read(1024) start,stop = 187,192 record=1 recordlength=0 offset=utilities.readbinary(meta,(record-1)*recordlength,start,stop) #don't use ALOS provided no. cols, as it doesn't include 'dummy' pixels #vrt=geometry.CreateRawRasterVRT(self._imgs,self.metadata['cols'],self.metadata['rows'],self.metadata['datatype'],offset,byteorder='MSB') vrt=geometry.CreateRawRasterVRT(self._imgs,offset,nrows,self.metadata['datatype'],offset,byteorder='MSB') self._gdaldataset=geometry.OpenDataset(vrt) #Reproject corners to lon,lat ##geom = geometry.GeomFromExtent(ext) ##tgt_srs=osr.SpatialReference() ##tgt_srs.ImportFromEPSG(4326) ##geom=geometry.ReprojectGeom(geom,src_srs,tgt_srs) ##points=geom.GetBoundary() ##ext=[[points.GetX(i),points.GetY(i)] for i in range(0,points.GetPointCount())] #Fix for Issue 17 for i in range(1,self._gdaldataset.RasterCount+1): self._gdaldataset.GetRasterBand(i).SetNoDataValue(nodata) self.metadata['level'] = level self.metadata['sceneid'] = sceneid if orbit=='A':self.metadata['orbit']='Ascending' else: self.metadata['orbit']='Descending' self.metadata['metadata']='\n'.join(['%s: %s' %(m,extra_md[m]) for m in extra_md]) if not tif: self.metadata['filesize']=sum([os.path.getsize(tmp) for tmp in self.filelist]) self.metadata['srs'] = src_srs.ExportToWkt() self.metadata['epsg'] = epsg self.metadata['units'] = units self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands if abs(math.degrees(rot)) < 1.0:self.metadata['rotation'] = 0.0 else: self.metadata['rotation'] = math.degrees(rot) self.metadata['UL']='%s,%s' % tuple(ext[0]) self.metadata['UR']='%s,%s' % tuple(ext[1]) self.metadata['LR']='%s,%s' % tuple(ext[2]) self.metadata['LL']='%s,%s' % tuple(ext[3]) self.metadata['cellx'],self.metadata['celly']=xpix,ypix self.metadata['nodata'] = nodata self.metadata['compressionratio']=0 self.metadata['compressiontype']='None' self.extent=ext
def v2(self, f=None): if not f: f = self.fileinfo['filepath'] dom = self._dom self.metadata['sceneid'] = dom.xpath( 'string(/Dimap_Document/Dataset_Identification/DATASET_NAME)') try: self._gdaldataset = geometry.OpenDataset(f) __default__.Dataset.__getmetadata__( self) #autopopulate basic metadata except: ncols = dom.xpath('number(//*/NCOLS)') nrows = dom.xpath('number(//*/NROWS)') nbands = dom.xpath('number(//*/NBANDS)') nbits = dom.xpath('number(//*/NBITS)') if nbits == 16: datatype = 'UInt16' else: datatype = 'Byte' if nbands == 1: bands = [1] else: bands = [ int(b[1:]) for b in [ dom.xpath('string(//*/RED_CHANNEL)'), dom.xpath('string(//*/GREEN_CHANNEL)'), dom.xpath('string(//*/BLUE_CHANNEL)') ] ] self.metadata['bands'] = ','.join(map(str, bands)) if dom.xpath('string(//*/DATA_FILE_TILES)') == 'true': import math ntiles = dom.xpath('number(//*/NTILES)') if dom.xpath('boolean(//*/NTILES_COUNT/@ntiles_x)'): ntiles_x = dom.xpath('number(//*/NTILES_COUNT/@ntiles_x)') ntiles_y = dom.xpath('number(//*/NTILES_COUNT/@ntiles_y)') elif dom.xpath('boolean(//*/NTILES_COUNT/@ntiles_C)'): ntiles_x = dom.xpath('number(//*/NTILES_COUNT/@ntiles_C)') ntiles_y = dom.xpath('number(//*/NTILES_COUNT/@ntiles_R)') tile_cols = math.ceil(ncols / ntiles_x) last_tile_cols = tile_cols - (ntiles_x * tile_cols - ncols) tile_rows = math.ceil(nrows / ntiles_y) last_tile_rows = tile_rows - (ntiles_y * tile_rows - nrows) srcrects, dstrects = [], [] files = [] for df in dom.xpath('//*/Data_File'): col = df.xpath('number(@tile_C)') row = df.xpath('number(@tile_R)') datafile = os.path.join( os.path.dirname(f), df.xpath('string(DATA_FILE_PATH/@href)')) exists, datafile = utilities.exists( datafile, True ) #Work around reading images with lowercase filenames when the DATA_FILE_PATH is uppercase # - eg samba filesystems which get converted to lowercase if (row, col) == (1, 1): r1c1 = datafile srcrect = [0, 0, tile_cols, tile_rows] dstrect = [(ntiles_x - 1) * tile_cols, (ntiles_y - 1) * tile_rows, tile_cols, tile_rows] if col == ntiles_x: #last col srcrect[2] = last_tile_cols dstrect[2] = last_tile_cols if row == ntiles_y: #last row srcrect[3] = last_tile_rows dstrect[3] = last_tile_rows files.append(datafile) srcrects.append(srcrect) dstrects.append(dstrect) self._gdaldataset = geometry.OpenDataset( geometry.CreateMosaicedVRT(files, bands, srcrects, dstrects, ncols, nrows, datatype)) ds = geometry.OpenDataset(r1c1) self._gdaldataset.SetGeoTransform(ds.GetGeoTransform()) self._gdaldataset.SetProjection(ds.GetProjection()) else: datafile = os.path.join( os.path.dirname(f), dom.xpath('string(//*/DATA_FILE_PATH/@href)')) exists, datafile = utilities.exists(datafile, True) self._gdaldataset = geometry.OpenDataset(datafile) __default__.Dataset.__getmetadata__(self) dates = {} for src in dom.xpath('//Source_Identification'): datetime = '%sT%s' % (src.xpath('string(//*/IMAGING_DATE)'), src.xpath('string(//*/IMAGING_TIME)')[:8]) dts = time.mktime(time.strptime( datetime, utilities.datetimeformat)) #ISO 8601 dates[dts] = datetime if len(dates) == 1: self.metadata['imgdate'] = datetime else: self.metadata['imgdate'] = '%s/%s' % (dates[min( dates.keys())], dates[max(dates.keys())]) self.metadata['satellite'] = '%s %s' % (src.xpath( 'string(//*/MISSION)'), src.xpath('string(//*/MISSION_INDEX)')) try: self.metadata['sensor'] = '%s %s' % ( src.xpath('string(//*/INSTRUMENT)'), src.xpath('string(//*/INSTRUMENT_INDEX)')) except: self.metadata['sensor'] = '%s' % src.xpath( 'string(//*/INSTRUMENT)') try: sunangles = dom.xpath( '//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Solar_Incidences' )[0] self.metadata['sunelevation'] = sunangles.xpath( 'number(SUN_ELEVATION)') self.metadata['sunazimuth'] = sunangles.xpath( 'number(SUN_AZIMUTH)') except: pass try: self.metadata['viewangle'] = dom.xpath( 'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/VIEWING_ANGLE)' ) self.metadata['satelevation'] = dom.xpath( 'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/INCIDENCE_ANGLE)' ) self.metadata['satazimuth'] = dom.xpath( 'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/AZIMUTH_ANGLE)' ) except: pass try: self.metadata['level'] = dom.xpath( 'string(//*/Processing_Information/Product_Settings/PROCESSING_LEVEL)' ) except: pass try: self.metadata['resampling'] = dom.xpath( 'string(//*/Processing_Information/Product_Settings/Sampling_Settings/RESAMPLING_KERNEL)' ) except: pass self.metadata['metadata'] = etree.tostring(dom, pretty_print=True)
def __getmetadata__(self): '''Read Metadata for an ACRES Landsat FastL7A format image as GDAL doesn't get it all. Format description: http://www.ga.gov.au/image_cache/GA10348.pdf Note: hrf = ~30m VNIR/SWIR (bands 1-5 & 7) htm = ~60m thermal (band 6) hpn = ~15m pan (band 8) ''' f = self.fileinfo['filepath'] d = os.path.dirname(f) hdr = open(f).read() err = 'Unable to open %s' % f md = self.metadata md['filesize'] = sum([os.path.getsize(file) for file in self.filelist]) md['filetype'] = 'FAST/EOSAT FAST Format' rl = 1536 #recordlength ###################################### ##Record 1 - administrative ###################################### rec = 1 req_id = utilities.readascii(hdr, (rec - 1) * rl, 9, 28) loc = utilities.readascii(hdr, (rec - 1) * rl, 35, 51) acquisition_date = utilities.readascii(hdr, (rec - 1) * rl, 71, 78) md['imgdate'] = '%s-%s-%s' % ( acquisition_date[:4], acquisition_date[4:6], acquisition_date[6:]) md['satellite'] = utilities.readascii(hdr, (rec - 1) * rl, 92, 101) md['sensor'] = utilities.readascii(hdr, (rec - 1) * rl, 111, 120) md['mode'] = utilities.readascii(hdr, (rec - 1) * rl, 135, 140) md['viewangle'] = float( utilities.readascii(hdr, (rec - 1) * rl, 154, 159)) product_type = utilities.readascii(hdr, (rec - 1) * rl, 655, 672) product_size = utilities.readascii(hdr, (rec - 1) * rl, 688, 697) level = utilities.readascii(hdr, (rec - 1) * rl, 741, 751) md['resampling'] = utilities.readascii(hdr, (rec - 1) * rl, 765, 766) md['cols'] = int(utilities.readascii(hdr, (rec - 1) * rl, 843, 847)) md['rows'] = int(utilities.readascii(hdr, (rec - 1) * rl, 865, 869)) md['cellx'] = float(utilities.readascii(hdr, (rec - 1) * rl, 954, 959)) md['celly'] = md['cellx'] md['nbits'] = 8 #int(utilities.readascii(hdr,(rec-1)*rl,984,985)) always 8 bit md['datatype'] = 'Byte' md['nodata'] = '0' bands_present = utilities.readascii(hdr, (rec - 1) * rl, 1056, 1087) bandindices = [[1131, 1159], [1170, 1198], [1211, 1239], [1250, 1278], [1291, 1319], [1330, 1358]] bandfiles = {} for i in bandindices: band = utilities.readascii(hdr, (rec - 1) * rl, i[0], i[1]) if band: exists, path = utilities.exists(os.path.join(d, band), True) if exists: bandfiles[band] = path else: #Assume ACRES format (band*.dat) instead Fast format (l7*.fst)... bandid = band[23:25] if bandid == '61': bandid = '6l' elif bandid == '62': bandid = '6h' else: bandid = bandid[0] exists, path = utilities.exists( os.path.join(d, 'band%s.dat' % bandid), True) if not exists: raise RuntimeError, 'Unable to open band data files.' bandfiles[band] = path else: break md['nbands'] = len(bandfiles) md['sceneid'] = os.path.basename( bandfiles.keys()[0] )[3: 21] #Use path/row & aquisition date as sceneid - L7f[ppprrr_rrrYYYYMMDD]_AAA.FST if self._filetype == 'HRF': md['bands'] = '1 (BLUE),2 (GREEN),3 (RED),4 (NIR),5 (SWIR),7 (SWIR)' elif self._filetype == 'HTM': md['bands'] = '6L (THERMAL),6H (THERMAL)' elif self._filetype == 'HPN': md['bands'] = '8 (PAN)' ###################################### ##Record 2 - radiometric ###################################### #Move along, nothing to see here... ###################################### ##Record 3 - geometric ###################################### rec = 3 map_projection = utilities.readascii(hdr, (rec - 1) * rl, 32, 35) prjcode = spatialreferences.GCTP_PROJECTIONS.get(map_projection, 0) ellipsoid = utilities.readascii(hdr, (rec - 1) * rl, 48, 65) ellcode = spatialreferences.GCTP_ELLIPSOIDS.get(ellipsoid, 0) datum = utilities.readascii(hdr, (rec - 1) * rl, 74, 79) zone = utilities.readascii(hdr, (rec - 1) * rl, 521, 526) #Workaround for UTM zones as GDAL does not pick up southern hemisphere #as some FST headers don't include a negative zone number to indicate southern hemisphere #as per the FAST format definition zone = int(zone) if zone else 0 usgs_indices = ( (110, 133), #Semi-major axis (135, 158), #Semi-minor axis (161, 184), (186, 209), (211, 234), (241, 264), (266, 289), (291, 314), (321, 344), (346, 369), (371, 394), (401, 424), (426, 449), (451, 474), (481, 504)) usgs_params = [] for i in usgs_indices: p = utilities.readascii(hdr, (rec - 1) * rl, i[0], i[1]) if p: usgs_params.append(float(p)) else: usgs_params.append(0.0) ulx = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 566, 578), 'DDDMMSSSSSSSH') uly = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 580, 591), 'DDMMSSSSSSSH') urx = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 646, 658), 'DDDMMSSSSSSSH') ury = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 660, 671), 'DDMMSSSSSSSH') lrx = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 726, 738), 'DDDMMSSSSSSSH') lry = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 740, 751), 'DDMMSSSSSSSH') llx = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 806, 818), 'DDDMMSSSSSSSH') lly = geometry.DMS2DD( utilities.readascii(hdr, (rec - 1) * rl, 820, 831), 'DDMMSSSSSSSH') ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] md['UL'] = '%s,%s' % tuple(ext[0]) md['UR'] = '%s,%s' % tuple(ext[1]) md['LR'] = '%s,%s' % tuple(ext[2]) md['LL'] = '%s,%s' % tuple(ext[3]) if zone > 0 and uly < 0: zone *= -1 srs = osr.SpatialReference() srs.ImportFromUSGS(prjcode, zone, usgs_params, ellcode) if datum == 'GDA': #Workaround for GDA94 datum as GDAL does not recognise it #as per the FAST format definition if map_projection == 'UTM': epsg = 28300 + abs(zone) srs.ImportFromEPSG(epsg) md['srs'] = srs.ExportToWkt() md['epsg'] = epsg md['units'] = 'm' else: srs.SetGeogCS('GDA94', 'Geocentric_Datum_of_Australia_1994', 'GRS 1980', usgs_params[0], 298.257) md['srs'] = srs.ExportToWkt() md['epsg'] = spatialreferences.IdentifyAusEPSG(md['srs']) md['units'] = spatialreferences.GetLinearUnitsName(md['srs']) else: md['srs'] = srs.ExportToWkt() md['epsg'] = spatialreferences.IdentifyAusEPSG(md['srs']) md['units'] = spatialreferences.GetLinearUnitsName(md['srs']) md['rotation'] = float( utilities.readascii(hdr, (rec - 1) * rl, 995, 1000)) if abs(md['rotation']) < 1: md['orientation'] = 'Map oriented' md['rotation'] = 0.0 else: md['orientation'] = 'Path oriented' md['sunelevation'] = utilities.readascii(hdr, (rec - 1) * rl, 1062, 1065) md['sunazimuth'] = utilities.readascii(hdr, (rec - 1) * rl, 1086, 1090) try: ##Open dataset self._gdaldataset = geometry.OpenDataset(f) metadata = self._gdaldataset.GetMetadata() md['metadata'] = '\n'.join( ['%s: %s' % (m, metadata[m]) for m in metadata]) #Fix for Issue 17 for i in range(1, self._gdaldataset.RasterCount + 1): self._gdaldataset.GetRasterBand(i).SetNoDataValue( float(md['nodata'])) except: #build a VRT dataset - if we want to use this for anything other than overview generation, should probably fill out the geotransform, srs, metadata etc... bands = bandfiles.values() bands.sort() #vrtxml=geometry.CreateRawRasterVRT(bands,md['cols'],md['rows'], md['datatype']) #Fix for Issue 17 vrtxml = geometry.CreateRawRasterVRT(bands, md['cols'], md['rows'], md['datatype'], nodata=md['nodata']) self._gdaldataset = geometry.OpenDataset(vrtxml) md['metadata'] = hdr if self._filetype == 'HRF': self._gdaldataset.GetRasterBand(4).SetRasterColorInterpretation( gdal.GCI_BlueBand) self._gdaldataset.GetRasterBand(3).SetRasterColorInterpretation( gdal.GCI_GreenBand) self._gdaldataset.GetRasterBand(2).SetRasterColorInterpretation( gdal.GCI_RedBand) if level == 'SYSTEMATIC': md['level'] = '1G ' elif level == 'SYSTERRAIN': md['level'] = '1Gt' elif level == 'PRECISION': md['level'] = '1P' elif level == 'TERRAIN': md['level'] = '1T' md['compressionratio'] = 0 md['compressiontype'] = 'None' self.extent = ext for m in md: self.metadata[m] = md[m]
def __gettilevrt__(self, f, imddata): til = iter(open(f).readlines()) tileinfo = {} datasets = {} line = til.next() while line: #Extract all keys and values from the header file into a dictionary line = line.strip().strip(';').replace('"', '') if line == 'END': break if 'BEGIN_GROUP' in line: line = til.next() while line: line = line.strip().strip(';').replace('"', '') if 'END_GROUP' in line: break else: dat = map(string.strip, line.split('=', 1)) if not dat[0] in datasets: datasets[dat[0]] = [] datasets[dat[0]].append(dat[1]) line = til.next() else: var = map(string.strip, line.split('=', 1)) tileinfo[var[0]] = var[1] line = til.next() curdir = os.path.dirname(f) bimg, img = utilities.exists( os.path.join(curdir, datasets['filename'][0]), True) ds = geometry.OpenDataset(img) rb = ds.GetRasterBand(1) DataType = gdal.GetDataTypeName(rb.DataType) GeoTransform = ds.GetGeoTransform() Projection = ds.GetProjection() if GeoTransform == (0.0, 1.0, 0.0, 0.0, 0.0, 1.0): GeoTransform = gdal.GCPsToGeoTransform(ds.GetGCPs()) if Projection == '': Projection = ds.GetGCPProjection() GeoTransform = ','.join(map(str, GeoTransform)) numTiles = int(tileinfo['numTiles']) BlockXSize, BlockYSize = rb.GetBlockSize() vrtXML = [] vrtXML.append('<VRTDataset rasterXSize="%s" rasterYSize="%s">' % (imddata['numColumns'], imddata['numRows'])) vrtXML.append('<SRS>%s</SRS>' % Projection) vrtXML.append('<GeoTransform>%s</GeoTransform>' % GeoTransform) for b, band in enumerate(imddata['bands']): b += 1 vrtXML.append(' <VRTRasterBand dataType="%s" band="%s">' % (DataType, b)) #vrtXML.append(' <ColorInterp>Gray</ColorInterp>') for tile in range(0, numTiles): tileSizeX = int(datasets['URColOffset'][tile]) - int( datasets['ULColOffset'][tile]) + 1 tileSizeY = int(datasets['LLRowOffset'][tile]) - int( datasets['ULRowOffset'][tile]) + 1 ULColOffset = datasets['ULColOffset'][tile] ULRowOffset = datasets['ULRowOffset'][tile] bimg, img = utilities.exists( os.path.join(curdir, datasets['filename'][tile]), True) vrtXML.append(' <SimpleSource>') vrtXML.append( ' <SourceFilename relativeToVRT="0">%s</SourceFilename>' % img) vrtXML.append(' <SourceBand>%s</SourceBand>' % (b)) vrtXML.append( ' <SourceProperties RasterXSize="%s" RasterYSize="%s" DataType="%s"/>' % (tileSizeX, tileSizeY, DataType) ) # BlockXSize="%s" BlockYSize="%s"/>'(tileSizeX,tileSizeY,DataType,BlockXSize,BlockYSize)) vrtXML.append( ' <SrcRect xOff="0" yOff="0" xSize="%s" ySize="%s"/>' % (tileSizeX, tileSizeY)) vrtXML.append( ' <DstRect xOff="%s" yOff="%s" xSize="%s" ySize="%s"/>' % (ULColOffset, ULRowOffset, tileSizeX, tileSizeY)) vrtXML.append(' </SimpleSource>') vrtXML.append(' </VRTRasterBand>') vrtXML.append('</VRTDataset>') vrtXML = '\n'.join(vrtXML) return vrtXML