示例#1
0
    def __init__(self, f=None):
        '''Open the dataset'''
        if not f: f = self.fileinfo['filepath']
        self.filelist = [r for r in utilities.rglob(os.path.dirname(f))
                         ]  #everything in this dir and below.

        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)
        if not satellite[0:7] == 'LANDSAT':
            raise NotImplementedError  #This error gets ignored in __init__.Open()
    def __init__(self,f=None):
        '''Open the dataset'''
        if not f:f=self.fileinfo['filepath']

        led=glob.glob(os.path.dirname(f) + '/[Ll][Ee][Aa][Dd]*')[0] #volume file
        meta = open(led,'rb').read()

        #Record 2 - Scene header record
        record=2
        recordlength=3960 #SPOT recordlength=3960 
        satellite=utilities.readbinary(meta,(record-1)*recordlength,613,628)
        if not satellite[0:4] == 'SPOT':
            raise NotImplementedError #This error gets ignored in __init__.Open()
        self.filelist=[r for r in utilities.rglob(os.path.dirname(f))] #everything in this dir and below.
    def __init__(self,f=None):
        '''Open the dataset'''
        if not f:f=self.fileinfo['filepath']
        self.filelist=[r for r in utilities.rglob(os.path.dirname(f))] #everything in this dir and below.

        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)
        if not satellite[0:7] == 'LANDSAT':
            raise NotImplementedError #This error gets ignored in __init__.Open()
示例#4
0
    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
示例#5
0
    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):
        '''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
示例#7
0
    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
示例#8
0
    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