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 __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): '''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 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 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 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_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 __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