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): '''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'eo1a.*\.m[1-4]r$', f, re.I): self.ali_l1r(f) elif re.search(r'eo1.*_mtl\.tif$', f): self.ali_l1g_tiff(f) elif re.search(r'eo1.*_hdf\.l1g$', f): self.ali_l1g_hdf(f) elif re.search(r'eo1h.*\.l[1-4]r$', f): self.hyp_l1r(f) elif re.search(r'eo1.*_mtl_.*\.l1t$', f, re.I): self.hyp_l1t(f) self.metadata['cols'] = self.ncols self.metadata['rows'] = self.nrows self.metadata['nbands'] = self.nbands #Geotransform ncols = map(int, str(self.ncols).split(',')) nrows = map(int, str(self.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(self.prjext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = self.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(self.geoext[0]) self.metadata['UR'] = '%s,%s' % tuple(self.geoext[1]) self.metadata['LR'] = '%s,%s' % tuple(self.geoext[2]) self.metadata['LL'] = '%s,%s' % tuple(self.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 = self.geoext
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 __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)