Пример #1
0
    def __getmetadata__(self):
        '''Read Metadata for a "scene01/*.tif" (possibly) multiband image'''

        f = self.fileinfo['filepath']
        d = os.path.dirname(f)
        bands = sorted([t for t in self.filelist if t[-4:].lower() == '.tif'])
        ds = geometry.OpenDataset(f)

        vrt = geometry.CreateSimpleVRT(bands,
                                       ds.RasterXSize,
                                       ds.RasterYSize,
                                       gdal.GetDataTypeName(
                                           ds.GetRasterBand(1).DataType),
                                       relativeToVRT=0)
        vrtds = geometry.OpenDataset(vrt, gdalconst.GA_Update)
        vrtds.SetGeoTransform(ds.GetGeoTransform())
        vrtds.SetProjection(ds.GetProjection())
        vrtds.SetGCPs(ds.GetGCPs(), ds.GetProjection())
        vrtds.SetMetadata(ds.GetMetadata())

        #Kludge... the drivers are designed to "open" strings, i.e. filenames and vrt xml
        #(maybe look at allowing GdalDataset objects in future)
        vrtds = geometry.CreateVRTCopy(
            vrtds)  #This updates the Description property to include all the
        vrtxml = vrtds.GetDescription()  #SRS/GCP/GT info we just added.
        #GetDescription() is the only way I know of to get at the
        #underlying XML string.

        #Autopopulate metadata
        __default__.Dataset.__getmetadata__(self, vrtxml)
        self.metadata['filetype'] = 'GTiff/GeoTIFF'
Пример #2
0
    def __getmetadata__(self):
        '''Read Metadata for a NetCDF image (1st subdataset)'''
        f=self.fileinfo['filepath']
        if f[:4]=='/vsi':raise NotImplementedError

        nc=geometry.OpenDataset(f)
        ncmd=nc.GetMetadata()

        sds=nc.GetSubDatasets()
        #gdal_version=''.join([c for c in gdal.__version__ if c in '1234567890.'])
        gdal_version=[int(c) for c in gdal_version.split('.')]

        if sds: #Use the SubDataset with the most cols*rows
            xy=[]
            sdo=[]
            for sd_name,sd_desc in sds:
                sd=geometry.OpenDataset(sd_name)
                xy.append(sd.RasterXSize * sd.RasterYSize)
                sdo.append([sd,sd_name,sd_desc])

            sd,sd_name,sd_desc=sdo[xy.index(max(xy))]
            try:__default__.Dataset.__getmetadata__(self, sd_name) #autopopulate basic metadata
            except NotImplementedError:
                if gdal_version < [1,8,0]:
                    raise NotImplementedError('You are using GDAL %s, versions < 1.8 do not read georeferencing information for certain NetCDF files.'%geometry.gdal.__version__)
                else:raise
            sdmd=sd.GetMetadata()
        else:
            try:__default__.Dataset.__getmetadata__(self, f) #autopopulate basic metadata
            except NotImplementedError:
                if gdal_version < [1,8,0]:
                    raise NotImplementedError('You are using GDAL %s, versions < 1.8 do not read georeferencing information for certain NetCDF files.'%geometry.gdal.__version__)
                else:raise

            sdmd={}
            sd_name,sd_desc = ['','']

        source=sdmd.get('NC_GLOBAL#source',ncmd.get('NC_GLOBAL#source',''))
        if source:source='Source:'+source
        history=sdmd.get('NC_GLOBAL#history',ncmd.get('NC_GLOBAL#history',''))
        if history:history='History:n'+history
        self.metadata['lineage'] = '\n\n'.join([source,history]).strip()
        comment=sdmd.get('NC_GLOBAL#comment',ncmd.get('NC_GLOBAL#comment',''))
        references=sdmd.get('NC_GLOBAL#references',ncmd.get('NC_GLOBAL#references',''))
        if references:references='References:n'+references
        self.metadata['abstract'] = '\n\n'.join([comment,references]).strip()
        self.metadata['title'] = ncmd.get('NC_GLOBAL#title',sdmd.get('NC_GLOBAL#title',sd_desc))
        self.metadata['useConstraints'] = ncmd.get('NC_GLOBAL#acknowledgment',sdmd.get('NC_GLOBAL#acknowledgment',''))
        pass
Пример #3
0
 def __init__(self, f=None):
     if not f: f = self.fileinfo['filepath']
     self.filelist = glob.glob(os.path.splitext(f)[0] + '.*')
     self._gdaldataset = geometry.OpenDataset(f)
     self._hdf_md = self._gdaldataset.GetMetadata()
     if not self._hdf_md.get('INSTRUMENTSHORTNAME') == 'ASTER':
         raise NotImplementedError  #This error gets ignored in __init__.Open()
Пример #4
0
    def __opendataset__(self):

        bandlookup = {
            'pan': ['pan'],
            'blu': ['blu'],
            'grn': ['grn'],
            'red': ['red'],
            'nir': ['nir'],
            'bgrn': ['blu', 'grn', 'red', 'nir'],
            'bgr': ['blu', 'grn', 'red'],
            'rgb': ['red', 'grn', 'blu']
        }
        bandfiles = {}
        bandnames = []
        for d in self._datafiles:
            band = d.split('_')[2]
            bands = bandlookup.get(band, band)
            for band in bands:
                bandfiles[band] = os.path.join(
                    os.path.dirname(self.fileinfo['filepath']), d)
                bandnames += [band]

        try:
            f = bandfiles['red']
            rgb = True
        except:
            f = bandfiles['pan']
            rgb = False

        ds = geometry.OpenDataset(f)
        rb = ds.GetRasterBand(1)
        cols = ds.RasterXSize
        rows = ds.RasterYSize
        datatype = gdal.GetDataTypeName(rb.DataType)
        nbits = gdal.GetDataTypeSize(rb.DataType)
        nbands = len(bandnames)
        bandnames = ','.join(bandnames)

        if rgb and bandfiles['red'] != bandfiles['blu']:
            ds = geometry.OpenDataset(
                geometry.CreateSimpleVRT(
                    [bandfiles['red'], bandfiles['grn'], bandfiles['blu']],
                    cols, rows, datatype))

        return ds, nbands, bandnames, f
Пример #5
0
    def __getmetadata__(self, f=None):
        '''Read Metadata for a DIMAP image as GDAL doesn't quite get it all...'''
        if not f: f = self.fileinfo['filepath']
        #dom=etree.parse(f) #Takes tooo long to parse the whole file, so just read as far as we need...
        strxml = ''
        for line in open(f, 'r'):
            if line.upper().strip() == '<DATA_STRIP>': break
            else: strxml += line
        if not '</Dimap_Document>' in strxml: strxml += '</Dimap_Document>'
        dom = etree.fromstring(strxml)
        self.metadata['sceneid'] = dom.xpath(
            'string(/Dimap_Document/Dataset_Id/DATASET_NAME)')
        bands = dom.xpath(
            '/Dimap_Document/Spectral_Band_Info/BAND_DESCRIPTION')
        self.metadata['bands'] = ','.join(
            [band.xpath('string(.)') for band in bands])

        try:
            __default__.Dataset.__getmetadata__(
                self, f)  #autopopulate basic metadata
        except geometry.GDALError, err:  #Work around reading images with lowercase filenames when
            #the DATA_FILE_PATH is uppercase
            # - eg samba filesystems which get converted to lowercase

            dfp = dom.xpath(
                '/Dimap_Document/Data_Access/Data_File/DATA_FILE_PATH')[0]
            fn = utilities.encode(
                dfp.xpath('string(@href)'
                          ))  #XML is unicode, gdal.Open doesn't like unicode
            if not os.path.dirname(fn):
                fn = os.path.join(os.path.dirname(f), fn)
            exists, img = utilities.exists(fn, True)
            if exists and not os.path.exists(fn):
                import tempfile
                tmpfd, tmpfn = tempfile.mkstemp(suffix='.dim',
                                                prefix='metadata')
                dfp.set('href', img)
                tmpfo = os.fdopen(tmpfd, 'w')
                tmpfo.write(etree.tostring(dom))
                tmpfo.flush()
                tmpfo.close()
                cwd = os.path.abspath(os.curdir)
                tmp = os.path.split(tmpfn)
                os.chdir(
                    tmp[0]
                )  #CD to the tmp dir so __default__.Dataset.__getmetadata__ doesn't
                __default__.Dataset.__getmetadata__(self, tmp[1])
                gdalmd = self._gdaldataset.GetMetadata()
                self._gdaldataset = geometry.OpenDataset(img)
                self._gdaldataset.SetMetadata(gdalmd)
                os.unlink(tmpfn)
                os.chdir(cwd)
            else:
                raise
Пример #6
0
    def v1(self, f=None):
        dom = self._dom
        self.metadata['sceneid'] = dom.xpath(
            'string(/Dimap_Document/Dataset_Id/DATASET_NAME)')
        bands = dom.xpath(
            '/Dimap_Document/Spectral_Band_Info/BAND_DESCRIPTION')
        self.metadata['bands'] = ','.join(
            [band.xpath('string(.)') for band in bands])

        try:
            __default__.Dataset.__getmetadata__(
                self, f)  #autopopulate basic metadata
        except geometry.GDALError, err:  #Work around reading images with lowercase filenames when
            #the DATA_FILE_PATH is uppercase
            # - eg samba filesystems which get converted to lowercase

            dfp = dom.xpath(
                '/Dimap_Document/Data_Access/Data_File/DATA_FILE_PATH')[0]
            fn = utilities.encode(
                dfp.xpath('string(@href)'
                          ))  #XML is unicode, gdal.Open doesn't like unicode
            if not os.path.dirname(fn):
                fn = os.path.join(os.path.dirname(f), fn)
            exists, img = utilities.exists(fn, True)
            if exists and not os.path.exists(fn):
                import tempfile
                tmpfd, tmpfn = tempfile.mkstemp(suffix='.dim',
                                                prefix='metadata')
                dfp.set('href', img)
                tmpfo = os.fdopen(tmpfd, 'w')
                tmpfo.write(etree.tostring(dom))
                tmpfo.flush()
                tmpfo.close()
                cwd = os.path.abspath(os.curdir)
                tmp = os.path.split(tmpfn)
                os.chdir(
                    tmp[0]
                )  #CD to the tmp dir so __default__.Dataset.__getmetadata__ doesn't
                __default__.Dataset.__getmetadata__(self, tmp[1])
                gdalmd = self._gdaldataset.GetMetadata()
                self._gdaldataset = geometry.OpenDataset(img)
                self._gdaldataset.SetMetadata(gdalmd)
                os.unlink(tmpfn)
                os.chdir(cwd)
            else:
                raise
Пример #7
0
    def __getmetadata__(self):
        '''Read Metadata for a Landsat Geotiff with Level 1 Metadata format image as GDAL doesn't get it all.'''

        f = self.fileinfo['filepath']
        d = os.path.dirname(f)
        hdr = parseheader(f)

        bands = sorted(
            [i for i in hdr['PRODUCT_METADATA']['BAND_COMBINATION']])
        if hdr['PRODUCT_METADATA'][
                'SENSOR_ID'] == 'ETM+':  #Landsat 7 has 2 data files for thermal band 6
            #Format=123456678
            bands[5] = bands[5].replace('6', '61')
            bands[6] = bands[6].replace('6', '62')

        bandfiles = [
            os.path.join(d, hdr['PRODUCT_METADATA']['BAND%s_FILE_NAME' % b])
            for b in bands
        ]

        __default__.Dataset.__getmetadata__(self, bandfiles[0])

        md = self.metadata
        md['metadata'] = open(f).read().replace('\x00', '')
        md['sceneid'] = os.path.basename(d)
        md['filetype'] = 'GTIFF/Landsat MTL Geotiff'

        md['bands'] = ','.join(bands)
        md['nbands'] = len(bands)
        md['level'] = hdr['PRODUCT_METADATA']['PRODUCT_TYPE']
        md['imgdate'] = '%sT%s' % (
            hdr['PRODUCT_METADATA']['ACQUISITION_DATE'],
            hdr['PRODUCT_METADATA']['SCENE_CENTER_SCAN_TIME'][0:8]
        )  #ISO 8601 format, strip off the milliseconds
        md['satellite'] = hdr['PRODUCT_METADATA']['SPACECRAFT_ID']
        md['sensor'] = hdr['PRODUCT_METADATA']['SENSOR_ID']
        md['demcorrection'] = hdr['PRODUCT_METADATA'].get(
            'ELEVATION_SOURCE', '')  #Level 1G isn't terrain corrected
        md['resampling'] = hdr['PROJECTION_PARAMETERS']['RESAMPLING_OPTION']
        md['sunazimuth'] = hdr['PRODUCT_PARAMETERS']['SUN_AZIMUTH']
        md['sunelevation'] = hdr['PRODUCT_PARAMETERS']['SUN_ELEVATION']
        vrtxml = geometry.CreateSimpleVRT(bandfiles, md['cols'], md['rows'],
                                          md['datatype'])
        self._gdaldataset = geometry.OpenDataset(vrtxml)
        self._stretch = ['PERCENT', [3, 2, 1], [2, 98]]
Пример #8
0
    def __getmetadata__(self):
        '''Read Metadata for a Landsat Geotiff with Level 1 Metadata format image as GDAL doesn't get it all.'''
        f=self.fileinfo['filepath']
        d=os.path.dirname(f)
        hdr=parseheader(f)

        if hdr['L1_METADATA_FILE'].get('LANDSAT_SCENE_ID'):self.__getnewmetadata__(f,d,hdr)
        else:self.__getoldmetadata__(f,d,hdr)

        md=self.metadata
        vrtxml=geometry.CreateSimpleVRT(self.bandfiles,md['cols'],md['rows'], md['datatype'])
        self._gdaldataset = geometry.OpenDataset(vrtxml)
        for i in range(self._gdaldataset.RasterCount):
            self._gdaldataset.GetRasterBand(i+1).SetNoDataValue(0)

        #Fix quicklook stretch for Landsat 8 data
        if md['satellite']=='LANDSAT_8':
            self._stretch=['PERCENT',[4,3,2],[1,99]]
        else:
            self._stretch=['PERCENT',[3,2,1], [2,98]]
Пример #9
0
 def __getmetadata__(self,f=None):
     '''Read Metadata for a ECW image as GDAL doesn't quite get it all...'''
     if not f:f=self.fileinfo['filepath']
     #Originally we used the ERS to get metadata as they sometimes hold more info than the ECW
     #however, this caused segfaults under certain circumstances which were unable to be tracked down.
     #These circumstances were very repeatable and only occurred when the Crawler iterator returned a
     #certain ECW dataset, not when it was opened, when metadata was extracted nor even when overviews were generated.
     #Got me stumped!
     ers=os.path.splitext(f)[0]+'.ers'
     if os.path.exists(ers) and os.path.basename(f) in open(ers).read():
         try:
             __default__.Dataset.__getmetadata__(self, ers) #autopopulate basic metadata
             self.metadata['filetype']='ECW/ERMapper Compressed Wavelets'
             self.metadata['compressiontype']='ECW'
             self.metadata['filepath']=f
             self.metadata['filename']=os.path.basename(f)
             self._gdaldataset=geometry.OpenDataset(f) #ERS may not get handed off to gdal proxy and segfault
         except:__default__.Dataset.__getmetadata__(self, f)
     else:
         __default__.Dataset.__getmetadata__(self) #autopopulate basic metadata
Пример #10
0
    def hyp_l1t(self, f):
        md = parseheader(f)

        self.metadata['level'] = md['PRODUCT_METADATA']['PRODUCT_TYPE']
        self.metadata['sceneid'] = self.metadata['filename'].split(
            '_')[0].upper()
        self.metadata['filetype'] = 'GTiff/GeoTIFF'
        self.metadata['satellite'] = 'EO1'
        self.metadata['sensor'] = md['PRODUCT_METADATA']['SENSOR_ID']

        bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif'))
        band = geometry.OpenDataset(bands[0])
        self.ncols = band.RasterXSize
        self.nrows = band.RasterYSize
        self.nbands = len(bands)

        uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT'])
        ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON'])
        ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT'])
        urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON'])
        lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT'])
        lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON'])
        lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT'])
        llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON'])
        self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]

        uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY'])
        ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX'])
        ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY'])
        urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX'])
        lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY'])
        lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX'])
        lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY'])
        llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX'])
        self.prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]

        self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE']
        self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][
            'RESAMPLING_OPTION']
        try:
            self.metadata['viewangle'] = float(
                md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunazimuth'] = float(
                md['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunelevation'] = float(
                md['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'

        #EPSG:32601: WGS 84 / UTM zone 1N
        #EPSG:32701: WGS 84 / UTM zone 1S
        srs = osr.SpatialReference()
        zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER'])
        if zone > 0: epsg = 32600 + zone  #North
        else: epsg = 32700 - zone  #South
        srs.ImportFromEPSG(epsg)
        self.metadata['units'] = 'm'
        self.metadata['srs'] = srs.ExportToWkt()
        self.metadata['epsg'] = str(epsg)

        #########################################################################################################
        ##set self._gdaldataset for use in overview generation
        ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm)
        ##as they're near the center of the equivalent ALI bands
        self._gdaldataset = geometry.OpenDataset(
            geometry.CreateSimpleVRT([bands[43], bands[30], bands[21]],
                                     self.ncols, self.nrows, 'Int16'))
        self._gdaldataset.GetRasterBand(1).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
        #self._stretch=('STDDEV',(1,2,3),[2])
        self._stretch = ('PERCENT', (1, 2, 3), [2, 98])
Пример #11
0
    def __getmetadata__(self, f=None):
        '''Read Metadata for ASTER HDF images as GDAL doesn't.'''
        if not f: f = self.fileinfo['filepath']

        hdf_sd = self._gdaldataset.GetSubDatasets()
        hdf_sd = [sd for sd, sz in hdf_sd if 'ImageData' in sd]
        hdf_md = self._hdf_md

        #sd,sz = hdf_sd[0]
        sd = hdf_sd[0]
        sd = geometry.OpenDataset(sd)

        nbands = len(hdf_sd)
        ncols = []
        nrows = []
        nbits = []
        bands = []
        datatypes = []
        cellxy = []
        for i in range(0, len(hdf_md['PROCESSEDBANDS']), 2):
            band = hdf_md['PROCESSEDBANDS'][i:i + 2]
            if i / 2 + 1 <= 4:
                bands.append('VNIR' + band)
                cellxy.append('15')
            elif i / 2 + 1 <= 10:
                bands.append('SWIR' + band)
                cellxy.append('30')
            else:
                bands.append('TIR' + band)
                cellxy.append('90')
            if band.isdigit(): band = str(int(band))  #Get rid of leading zero
            cols, rows, bytes = map(
                int, hdf_md['IMAGEDATAINFORMATION%s' % band].split(','))
            if bytes == 1: datatypes.append('Byte')
            elif bytes == 2: datatypes.append('UInt16')
            ncols.append(str(cols))
            nrows.append(str(rows))
            nbits.append(str(bytes * 8))
        ncols = ','.join(ncols)
        nrows = ','.join(nrows)
        nbits = ','.join(nbits)
        bands = ','.join(bands)
        datatypes = ','.join(datatypes)
        cellxy = ','.join(cellxy)

        uly, ulx = [float(xy) for xy in hdf_md['UPPERLEFT'].split(',')]
        ury, urx = [float(xy) for xy in hdf_md['UPPERRIGHT'].split(',')]
        lry, lrx = [float(xy) for xy in hdf_md['LOWERRIGHT'].split(',')]
        lly, llx = [float(xy) for xy in hdf_md['LOWERLEFT'].split(',')]
        ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]]

        #SRS reported by GDAL is slightly dodgy, GDA94 is not recognised and doesn't set the North/South properly
        #Get it anyway so we can work out if it's GDA94 based on the spheroid
        srs = sd.GetGCPProjection()
        src_srs = osr.SpatialReference(srs)
        tgt_srs = osr.SpatialReference()
        geogcs = osr.SpatialReference()
        if src_srs.GetAttrValue('SPHEROID') == 'GRS 1980':
            geogcs.ImportFromEPSG(4283)  #Assume 'GDA94'
        else:
            geogcs.ImportFromEPSG(4326)  #Assume 'WGS84'
        tgt_srs.CopyGeogCSFrom(geogcs)

        if hdf_md['PROCESSINGLEVELID'].upper() == '1A':
            units = 'deg'
        else:
            #projparams=map(float, hdf_md['PROJECTIONPARAMETERS1'].split(','))
            if hdf_md['MPMETHOD1'] == 'UTM':  #Universal Transverse Mercator
                if uly < 0:
                    bNorth = False  #GDAL doesn't set the North/South properly
                else:
                    bNorth = True
                nZone = int(hdf_md['UTMZONECODE1'])
                tgt_srs.SetUTM(nZone, bNorth)
                units = 'm'
            #Other projections not (yet?) implemented...
            #elif hdf_md['MPMETHOD1'] == 'PS':#Polar Stereographic
            #    #dfCenterLon = ? GTCP projection params don't list cenlon/lat for PS
            #    dfCenterLat = ?
            #    dfScale = ?
            #    tgt_srs.SetPS(dfCenterLat,dfCenterLon,dfScale,0.0,0.0)
            #elif hdf_md['MPMETHOD1'] == 'LAMCC':#Lambert Conformal Conic
            #    dfCenterLon = ?
            #    dfCenterLat = ?
            #    dfStdP1 = ?
            #    dfStdP2 = ?
            #    tgt_srs.SetLCC(dfStdP1,dfStdP2,dfCenterLat,dfCenterLon,0,0)
            #elif hdf_md['MPMETHOD1'] == 'SOM':#Space Oblique Mercator
            #    dfCenterLon = ?
            #    dfCenterLat = ?
            #    srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0)
            #elif hdf_md['MPMETHOD1'] == 'EQRECT':#Equi-Rectangular
            #    dfCenterLon = ?
            #    dfCenterLat = ?
            #    tgt_srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0)
            else:  #Assume Geog
                units = 'deg'

        srs = tgt_srs.ExportToWkt()

        self.metadata['UL'] = '%s,%s' % tuple(ext[0])
        self.metadata['UR'] = '%s,%s' % tuple(ext[1])
        self.metadata['LR'] = '%s,%s' % tuple(ext[2])
        self.metadata['LL'] = '%s,%s' % tuple(ext[3])

        self.metadata['metadata'] = '\n'.join(
            ['%s: %s' % (m, hdf_md[m]) for m in hdf_md])

        self.metadata['satellite'] = 'Terra'
        self.metadata['sensor'] = 'ASTER'
        self.metadata['filetype'] = self._gdaldataset.GetDriver(
        ).ShortName + '/' + self._gdaldataset.GetDriver().LongName + ' (ASTER)'
        self.metadata['sceneid'] = hdf_md['ASTERSCENEID']
        self.metadata['level'] = hdf_md['PROCESSINGLEVELID']
        if '-' in hdf_md['CALENDARDATE']: imgdate = hdf_md['CALENDARDATE']
        else:
            imgdate = time.strftime(utilities.dateformat,
                                    time.strptime(hdf_md['CALENDARDATE'],
                                                  '%Y%m%d'))  #ISO 8601
        imgtime = hdf_md.get('TIMEOFDAY')
        if imgtime:
            self.metadata['imgdate'] = time.strftime(
                utilities.datetimeformat,
                time.strptime(imgdate + imgtime[0:6],
                              '%Y-%m-%d%H%M%S'))  #ISO 8601
        else:
            self.metadata['imgdate'] = imgdate
        #self.metadata['imgdate'] = hdf_md['CALENDARDATE']
        self.metadata['cloudcover'] = float(hdf_md['SCENECLOUDCOVERAGE'])
        if hdf_md['FLYINGDIRECTION'] == 'DE':
            self.metadata['orbit'] = 'Descending'
        else:
            self.metadata['orbit'] = 'Ascending'
        self.metadata['rotation'] = float(
            hdf_md.get('MAPORIENTATIONANGLE',
                       hdf_md.get('SCENEORIENTATIONANGLE')))
        if abs(self.metadata['rotation']) < 1.0:
            self.metadata['orientation'] = 'Map oriented'
        else:
            self.metadata['orientation'] = 'Path oriented'
        self.metadata['sunazimuth'], self.metadata['sunelevation'] = map(
            float, hdf_md['SOLARDIRECTION'].split(','))
        self.metadata['viewangle'] = float(hdf_md['POINTINGANGLE'])
        self.metadata['cols'] = ncols
        self.metadata['rows'] = nrows
        self.metadata['nbands'] = nbands
        self.metadata['datatype'] = datatypes
        self.metadata['nbits'] = nbits
        self.metadata['nodata'] = ','.join(['0' for i in range(0, nbands)])
        self.metadata['bands'] = bands
        self.metadata['resampling'] = hdf_md.get(
            'RESMETHOD1')  #Assume same for all...
        self.metadata['srs'] = srs
        self.metadata['epsg'] = spatialreferences.IdentifyAusEPSG(srs)
        self.metadata['units'] = units
        self.metadata['cellx'], self.metadata['celly'] = cellxy, cellxy

        #Geotransform
        ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]]
        ncols = map(int, str(ncols).split(','))
        nrows = map(int, str(nrows).split(','))
        cellx, celly = [], []
        j = 0
        while j < len(ncols):
            gcps = []
            i = 0
            lr = [[0, 0], [ncols[j], 0], [ncols[j], nrows[j]], [0, nrows[j]]]
            while i < len(ext) - 1:  #don't need the last xy pair
                gcp = gdal.GCP()
                gcp.GCPPixel, gcp.GCPLine = lr[i]
                gcp.GCPX, gcp.GCPY = ext[i]
                gcp.Id = str(i)
                gcps.append(gcp)
                i += 1
            j += 1
            geotransform = gdal.GCPsToGeoTransform(gcps)
            x, y = geometry.CellSize(geotransform)
            cellx.append(str(x))
            celly.append(str(abs(y)))

        self.metadata['cellx'] = ','.join(cellx)
        self.metadata['celly'] = ','.join(celly)

        srs = osr.SpatialReference()
        srs.ImportFromEPSG(4326)
        self.metadata['srs'] = srs.ExportToWkt()

        self.metadata['UL'] = '%s,%s' % tuple(ext[0])
        self.metadata['UR'] = '%s,%s' % tuple(ext[1])
        self.metadata['LR'] = '%s,%s' % tuple(ext[2])
        self.metadata['LL'] = '%s,%s' % tuple(ext[3])

        self.metadata['metadata'] = '\n'.join(
            ['%s: %s' % (m, hdf_md[m]) for m in hdf_md])

        self.metadata['filesize'] = sum(
            [os.path.getsize(file) for file in self.filelist])
        self.metadata['compressionratio'] = 0
        self.metadata['compressiontype'] = 'None'
        self.extent = ext

        #Build gdaldataset object for overviews
        vrtcols = ncols[0]
        vrtrows = nrows[0]
        #vrtbands=[sd for sd,sn in hdf_sd[0:4]]#The 4 VNIR bands
        vrtbands = hdf_sd[0:4]  #The 4 VNIR bands
        vrt = geometry.CreateSimpleVRT(vrtbands, vrtcols, vrtrows,
                                       datatypes.split(',')[0])
        self._gdaldataset = geometry.OpenDataset(vrt)
        for i in range(1, 5):
            self._gdaldataset.GetRasterBand(i).SetNoDataValue(0)
Пример #12
0
    def ali_l1g_hdf(self, f):
        self.metadata['level'] = 'L1G'
        self.metadata['sensor'] = 'ALI'
        self.metadata['sceneid'] = self.metadata['filename'].split('_')[0]

        gdalDataset = geometry.OpenDataset(f)
        #if not gdalDataset: #Error now raised in geometry.OpenDataset
        #    errmsg=gdal.GetLastErrorMsg()
        #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

        self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver(
        ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                                                       self.metadata['level'])

        hdf_sd = gdalDataset.GetSubDatasets()
        hdf_md = gdalDataset.GetMetadata()
        sd, sz = hdf_sd[0]
        sd = geometry.OpenDataset(sd)
        sd_md = sd.GetMetadata()
        self.ncols = []
        self.nrows = []
        self.nbands = 0
        bands = []
        for sd, sz in hdf_sd:
            bands.append(sd)
            ds = geometry.OpenDataset(sd)
            self.ncols.append(str(ds.RasterXSize))
            self.nrows.append(str(ds.RasterYSize))
            self.nbands += 1

        #get all multi bands for use in overview generation
        pancols = max(self.ncols)
        panindex = ncols.index(pancols)
        multibands = bands
        multincols = self.ncols
        multinrows = self.nrows
        if pancols > min(self.ncols):  #there is a pan band
            multibands.pop(panindex)
            multincols.pop(panindex)
            multinrows.pop(panindex)
        multibands.sort()
        self._gdaldataset = geometry.OpenDataset(
            geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0],
                                     'Int16'))
        self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
        self._stretch = ('STDDEV', (4, 3, 2), [2])

        self.ncols = ','.join(self.ncols)
        self.nrows = ','.join(self.nrows)

        met = f.lower().replace('_hdf.l1g', '_mtl.l1g')
        md = {}
        for line in open(met, 'r'):
            line = line.replace('"', '')
            line = [l.strip() for l in line.split('=')]
            if line[0] == 'END':  #end of the metadata file
                break
            elif line[0] == 'GROUP':  #start of a metadata group
                if line[1] != 'L1_METADATA_FILE':
                    group = line[1]
                    md[group] = {}
            elif line[0] == 'END_GROUP':  #end of a metadata group
                pass
            else:  #metadata value
                md[group][line[0]] = line[1]

        uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT'])
        ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON'])
        ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT'])
        urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON'])
        lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT'])
        lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON'])
        lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT'])
        llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON'])
        self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]
        self.prjext = self.geoext

        self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE']
        self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][
            'RESAMPLING_OPTION']
        try:
            self.metadata['viewangle'] = float(
                md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunazimuth'] = float(
                md['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunelevation'] = float(
                md['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'

        #EPSG:32601: WGS 84 / UTM zone 1N
        #EPSG:32701: WGS 84 / UTM zone 1S
        srs = osr.SpatialReference()
        zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER'])
        if zone > 0: epsg = 32600 + zone  #North
        else: epsg = 32700 - zone  #South
        srs.ImportFromEPSG(epsg)
        self.metadata['units'] = 'm'
        self.metadata['srs'] = srs.ExportToWkt()
        self.metadata['epsg'] = str(epsg)
Пример #13
0
    def ali_l1g_tiff(self, f):
        self.metadata['level'] = 'L1G'
        self.metadata['sensor'] = 'ALI'
        self.metadata['sceneid'] = self.metadata['filename'].split('_')[0]
        self.metadata['filetype'] = 'GTiff/GeoTIFF'

        ncols = []
        nrows = []
        nbands = 0
        bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif'))
        for band in bands:
            band = geometry.OpenDataset(band)
            ncols.append(str(band.RasterXSize))
            nrows.append(str(band.RasterYSize))
            nbands += 1
            #rb=sd.GetRasterBand(1)

        #get all multi bands for use in overview generation
        pancols = max(ncols)
        panindex = ncols.index(pancols)
        multibands = bands
        multincols = ncols
        multinrows = nrows
        if pancols > min(ncols):  #there is a pan band
            multibands.pop(panindex)
            multincols.pop(panindex)
            multinrows.pop(panindex)
        multibands.sort()
        self._gdaldataset = geometry.OpenDataset(
            geometry.CreateSimpleVRT(multibands, multincols[0], multinrows[0],
                                     'Int16'))
        self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
        self._stretch = ('STDDEV', (4, 3, 2), [2])

        self.ncols = ','.join(ncols)
        self.nrows = ','.join(nrows)
        met = f
        md = {}
        for line in open(met, 'r'):
            line = line.replace('"', '')
            line = [l.strip() for l in line.split('=')]
            if line[0] == 'END':  #end of the metadata file
                break
            elif line[0] == 'GROUP':  #start of a metadata group
                if line[1] != 'L1_METADATA_FILE':
                    group = line[1]
                    md[group] = {}
            elif line[0] == 'END_GROUP':  #end of a metadata group
                pass
            else:  #metadata value
                md[group][line[0]] = line[1]

        uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT'])
        ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON'])
        ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT'])
        urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON'])
        lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT'])
        lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON'])
        lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT'])
        llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON'])
        self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]

        uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY'])
        ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX'])
        ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY'])
        urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX'])
        lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY'])
        lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX'])
        lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY'])
        llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX'])
        self.prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]

        self.metadata['imgdate'] = md['PRODUCT_METADATA']['ACQUISITION_DATE']
        self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][
            'RESAMPLING_OPTION']
        try:
            self.metadata['viewangle'] = float(
                md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunazimuth'] = float(
                md['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'
        try:
            self.metadata['sunelevation'] = float(
                md['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
        except:
            pass  #Exception raised if value == 'UNAVAILABLE'

        #EPSG:32601: WGS 84 / UTM zone 1N
        #EPSG:32701: WGS 84 / UTM zone 1S
        srs = osr.SpatialReference()
        zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER'])
        if zone > 0: epsg = 32600 + zone  #North
        else: epsg = 32700 - zone  #South
        srs.ImportFromEPSG(epsg)
        self.metadata['units'] = 'm'
        self.metadata['srs'] = srs.ExportToWkt()
        self.metadata['epsg'] = str(epsg)
Пример #14
0
    def ali_l1r(self, f):
        self.metadata['level'] = 'L1R'
        self.metadata['sensor'] = 'ALI'

        gdalDataset = geometry.OpenDataset(f)
        #if not gdalDataset: #Error now raised in geometry.OpenDataset
        #    errmsg=gdal.GetLastErrorMsg()
        #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

        self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver(
        ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                                                       self.metadata['level'])

        srs = osr.SpatialReference()
        srs.ImportFromEPSG(4326)
        self.metadata['srs'] = srs.ExportToWkt()
        self.metadata['epsg'] = 4326
        self.metadata['units'] = 'deg'

        hdf_sd = gdalDataset.GetSubDatasets()
        hdf_md = gdalDataset.GetMetadata()
        sd, sz = hdf_sd[0]
        sd = geometry.OpenDataset(sd)
        sd_md = sd.GetMetadata()
        self.nbands = sd.RasterCount
        self.ncols = str(
            sd.RasterXSize * 4 - 30
        )  #Account for the four SCA strips and the overlap between SCA strips
        self.nrows = sd_md[
            'Number of along track pixels']  #sd.RasterYSize is incorrect
        if len(hdf_sd) == 6:  #Includes pan band (3 sds each)
            sd, sz = hdf_sd[3]
            sd = geometry.OpenDataset(sd)
            sd_md = sd.GetMetadata()
            cols = str(
                int(sd_md['Number of cross track pixels']) * 4 - 30
            )  #Account for the four SCA strips and the overlap between SCA strips
            rows = sd_md['Number of along track pixels']

            #set up to create multispectral only self._gdaldatset for overview generation
            if self.nbands == 1:
                multi = 3
                multibands = sd_md['Number of bands']
                multicols = cols
                multirows = rows
            else:
                multi = 0
                multibands = self.nbands
                multicols = self.ncols
                multirows = self.nrows
            multibands = range(1, int(multibands) + 1)

            #Make a csv list of cols, bands
            self.ncols = [self.ncols for i in range(0, self.nbands)]
            self.nrows = [self.nrows for i in range(0, self.nbands)]
            self.ncols.extend([cols for i in range(0, sd.RasterCount)])
            self.nrows.extend([rows for i in range(0, sd.RasterCount)])
            #nbands='%s,%s' % (nbands, sd_md['Number of bands'])
            self.nbands = self.nbands + int(sd_md['Number of bands'])
            self.ncols = ','.join(self.ncols)
            self.nrows = ','.join(self.nrows)

        else:
            #set up to create multispectral only _gdaldatset for overview generation
            multi = 0
            multibands = range(1, self.nbands + 1)
            multicols = self.ncols
            multirows = self.nrows

        #create multispectral only _gdaldatset for overview generation
        #Get all the data files and mosaic the strips
        #strips=[s for s in utilities.rglob(os.path.dirname(f),r'\.m[1-4]r$',True,re.I,False)]
        strips = glob.glob(os.path.join(os.path.dirname(f), '*.m[1-4]r'))
        strips.sort()
        strips.reverse()  #west->east = *.m4r-m1
        scols = (int(multicols) + 30) / 4  # +30 handles the 10 pixel overlap
        xoff = 10
        yoff = 400
        srows = int(multirows) - yoff
        srcrects = [[0, yoff, scols, srows]] * 4
        dstrects = []
        srcrect = [0, yoff, scols, srows]
        #dstrect=[None,0,scols,srows]
        files = []
        sd, sz = hdf_sd[multi]
        vrt_opts = []
        indatasetlist = []
        for i in range(0, 4):
            files.append(sd.replace(f, strips[i]))
            dstrects.append([i * (scols - xoff), 0, scols, srows])
        self._gdaldataset = geometry.OpenDataset(
            geometry.CreateMosaicedVRT(files, multibands, srcrects, dstrects,
                                       multicols, srows, 'Int16'))
        self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
        self._stretch = ('STDDEV', (4, 3, 2), [2])

        #Extract other metadata
        met = os.path.splitext(f)[0] + '.met'
        for line in open(met, 'r').readlines():
            if line[0:16] == 'Scene Request ID':
                line = line.strip().split()
                self.metadata['sceneid'] = line[3]
            if line[0:14] == 'ALI Start Time':
                line = line.strip().split()
                hdf_md['ImageStartTime'] = line[3] + line[4]
            if line[0:8] == 'PRODUCT_':
                line = line.strip()
                line = map(string.strip, line.split('='))
                if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1])
                if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1])
                if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1])
                if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1])
                if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1])
                if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1])
                if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1])
                if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1])
        self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]
        self.prjext = self.geoext
Пример #15
0
    def hyp_l1r(self, f):
        self.metadata['level'] = 'L1R'
        self.metadata['sensor'] = 'HYPERION'

        gdalDataset = geometry.OpenDataset(f)
        #if not gdalDataset: #Error now raised in geometry.OpenDataset
        #    errmsg=gdal.GetLastErrorMsg()
        #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

        self.metadata['filetype'] = '%s/%s (%s %s)' % (gdalDataset.GetDriver(
        ).ShortName, gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                                                       self.metadata['level'])
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(4326)
        self.metadata['srs'] = srs.ExportToWkt()
        self.metadata['epsg'] = 4326
        self.metadata['units'] = 'deg'

        hdf_sd = gdalDataset.GetSubDatasets()
        hdf_md = gdalDataset.GetMetadata()
        if hdf_sd:  #gdal <=1.10.x
            sd, sz = hdf_sd[0]
            sd = geometry.OpenDataset(sd)
            sd_md = sd.GetMetadata()
        else:  #gdal >=1.11.0
            sd = gdalDataset
            sd_md = hdf_md
        self.nbands = sd.RasterCount
        self.ncols = sd.RasterXSize
        self.nrows = sd.RasterYSize
        met = os.path.splitext(f)[0] + '.met'
        for line in open(met, 'r').readlines():
            if line[0:16] == 'Scene Request ID':
                line = line.strip().split()
                self.metadata['sceneid'] = line[3]
            if line[0:14] == 'HYP Start Time':
                line = line.strip().split()
                imgdate = time.strptime(line[3] + line[4], '%Y%j')
                self.metadata['imgdate'] = time.strftime('%Y-%m-%d',
                                                         imgdate)  #ISO 8601
            if line[0:8] == 'PRODUCT_':
                line = line.strip()
                line = map(string.strip, line.split('='))
                if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1])
                if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1])
                if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1])
                if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1])
                if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1])
                if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1])
                if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1])
                if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1])
        self.geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                       [ulx, uly]]
        self.prjext = self.geoext

        #########################################################################################################
        ##set self._gdaldataset for use in overview generation
        ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm)
        ##as they're near the center of the equivalent ALI bands

        ##This generates verrrryyy looong overviews cos hyperion data is one long thin strip eg. 256*3000 etc...
        #self._gdaldataset = geometry.CreateVRTCopy(sd)
        ##Instead we can clip out some of the centre rows
        #vrtcols=ncols
        #vrtrows=int(ncols*1.5)
        #srcrect=[0, int(nrows/2-vrtrows/2),ncols,vrtrows]
        #dstrect=[0, 0,ncols,vrtrows]
        ##Or we can fill out the ncols with nodata
        vrtcols = int(self.nrows / 1.5)
        vrtrows = self.nrows
        srcrect = [0, 0, self.ncols, self.nrows]
        dstrect = [
            int(self.nrows / 2.5 - self.ncols), 0, self.ncols, self.nrows
        ]
        vrt = geometry.CreateMosaicedVRT([sd.GetDescription()], [43, 30, 21],
                                         [srcrect], [dstrect], vrtcols,
                                         vrtrows, self.metadata['datatype'])
        self._gdaldataset = geometry.OpenDataset(vrt)
        self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
        self._gdaldataset.GetRasterBand(1).SetNoDataValue(0)
        self._stretch = ('STDDEV', (1, 2, 3), [2])
    def __getmetadata__(self):
        '''Read Metadata for recognised EO1 ALI (L1G & L1R) & Hyperion (L1R) images as GDAL doesn't'''

        f = self.fileinfo['filepath']
        self.metadata['satellite'] = 'E01'
        self.metadata['nbits'] = 16
        self.metadata['datatype'] = 'Int16'
        self.metadata['nodata'] = 0
        if re.search(r'\.m[1-4]r$', f, re.I):
            self.metadata['level'] = 'L1R'
            self.metadata['sensor'] = 'ALI'

            gdalDataset = geometry.OpenDataset(f)
            #if not gdalDataset: #Error now raised in geometry.OpenDataset
            #    errmsg=gdal.GetLastErrorMsg()
            #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

            self.metadata['filetype'] = '%s/%s (%s %s)' % (
                gdalDataset.GetDriver().ShortName,
                gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                self.metadata['level'])

            srs = osr.SpatialReference()
            srs.ImportFromEPSG(4326)
            self.metadata['srs'] = srs.ExportToWkt()
            self.metadata['epsg'] = 4326
            self.metadata['units'] = 'deg'

            hdf_sd = gdalDataset.GetSubDatasets()
            hdf_md = gdalDataset.GetMetadata()
            sd, sz = hdf_sd[0]
            sd = geometry.OpenDataset(sd)
            sd_md = sd.GetMetadata()
            nbands = sd.RasterCount
            ncols = str(
                sd.RasterXSize * 4 - 30
            )  #Account for the four SCA strips and the overlap between SCA strips
            nrows = sd_md[
                'Number of along track pixels']  #sd.RasterYSize is incorrect
            if len(hdf_sd) == 6:  #Includes pan band (3 sds each)
                sd, sz = hdf_sd[3]
                sd = geometry.OpenDataset(sd)
                sd_md = sd.GetMetadata()
                cols = str(
                    int(sd_md['Number of cross track pixels']) * 4 - 30
                )  #Account for the four SCA strips and the overlap between SCA strips
                rows = sd_md['Number of along track pixels']

                #set up to create multispectral only self._gdaldatset for overview generation
                if nbands == 1:
                    multi = 3
                    multibands = sd_md['Number of bands']
                    multicols = cols
                    multirows = rows
                else:
                    multi = 0
                    multibands = nbands
                    multicols = ncols
                    multirows = nrows
                multibands = range(1, int(multibands) + 1)

                #Make a csv list of cols, bands
                ncols = [ncols for i in range(0, nbands)]
                nrows = [nrows for i in range(0, nbands)]
                ncols.extend([cols for i in range(0, sd.RasterCount)])
                nrows.extend([rows for i in range(0, sd.RasterCount)])
                #nbands='%s,%s' % (nbands, sd_md['Number of bands'])
                nbands = nbands + int(sd_md['Number of bands'])
                ncols = ','.join(ncols)
                nrows = ','.join(nrows)

            else:
                #set up to create multispectral only _gdaldatset for overview generation
                multi = 0
                multibands = range(1, nbands + 1)
                multicols = ncols
                multirows = nrows

            #create multispectral only _gdaldatset for overview generation
            #Get all the data files and mosaic the strips
            #strips=[s for s in utilities.rglob(os.path.dirname(f),r'\.m[1-4]r$',True,re.I,False)]
            strips = glob.glob(os.path.join(os.path.dirname(f), '*.m[1-4]r'))
            strips.sort()
            strips.reverse()  #west->east = *.m4r-m1
            scols = (int(multicols) +
                     30) / 4  # +30 handles the 10 pixel overlap
            xoff = 10
            yoff = 400
            srows = int(multirows) - yoff
            srcrects = [[0, yoff, scols, srows]] * 4
            dstrects = []
            srcrect = [0, yoff, scols, srows]
            #dstrect=[None,0,scols,srows]
            files = []
            sd, sz = hdf_sd[multi]
            vrt_opts = []
            indatasetlist = []
            for i in range(0, 4):
                files.append(sd.replace(f, strips[i]))
                dstrects.append([i * (scols - xoff), 0, scols, srows])
            self._gdaldataset = geometry.OpenDataset(
                geometry.CreateMosaicedVRT(files, multibands, srcrects,
                                           dstrects, multicols, srows,
                                           'Int16'))
            self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
            self._stretch = ('STDDEV', (4, 3, 2), [2])

            #Extract other metadata
            met = os.path.splitext(f)[0] + '.met'
            for line in open(met, 'r').readlines():
                if line[0:16] == 'Scene Request ID':
                    line = line.strip().split()
                    self.metadata['sceneid'] = line[3]
                if line[0:14] == 'ALI Start Time':
                    line = line.strip().split()
                    hdf_md['ImageStartTime'] = line[3] + line[4]
                if line[0:8] == 'PRODUCT_':
                    line = line.strip()
                    line = map(string.strip, line.split('='))
                    if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1])
                    if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1])
                    if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1])
                    if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1])
                    if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1])
                    if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1])
                    if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1])
                    if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1])
            geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                      [ulx, uly]]
            prjext = geoext
        elif re.search(r'eo1.*_mtl\.tif$', f):
            self.metadata['level'] = 'L1G'
            self.metadata['sensor'] = 'ALI'
            self.metadata['sceneid'] = self.metadata['filename'].split('_')[0]
            self.metadata['filetype'] = 'GTiff/GeoTIFF'

            ncols = []
            nrows = []
            nbands = 0
            bands = glob.glob(os.path.join(os.path.dirname(f), 'eo1*_b*.tif'))
            for band in bands:
                band = geometry.OpenDataset(band)
                ncols.append(str(band.RasterXSize))
                nrows.append(str(band.RasterYSize))
                nbands += 1
                #rb=sd.GetRasterBand(1)

            #get all multi bands for use in overview generation
            pancols = max(ncols)
            panindex = ncols.index(pancols)
            multibands = bands
            multincols = ncols
            multinrows = nrows
            if pancols > min(ncols):  #there is a pan band
                multibands.pop(panindex)
                multincols.pop(panindex)
                multinrows.pop(panindex)
            multibands.sort()
            self._gdaldataset = geometry.OpenDataset(
                geometry.CreateSimpleVRT(multibands, multincols[0],
                                         multinrows[0], 'Int16'))
            self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
            self._stretch = ('STDDEV', (4, 3, 2), [2])

            ncols = ','.join(ncols)
            nrows = ','.join(nrows)
            met = f
            md = {}
            for line in open(met, 'r'):
                line = line.replace('"', '')
                line = [l.strip() for l in line.split('=')]
                if line[0] == 'END':  #end of the metadata file
                    break
                elif line[0] == 'GROUP':  #start of a metadata group
                    if line[1] != 'L1_METADATA_FILE':
                        group = line[1]
                        md[group] = {}
                elif line[0] == 'END_GROUP':  #end of a metadata group
                    pass
                else:  #metadata value
                    md[group][line[0]] = line[1]

            uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT'])
            ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON'])
            ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT'])
            urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON'])
            lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT'])
            lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON'])
            lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT'])
            llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON'])
            geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                      [ulx, uly]]

            uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPY'])
            ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_MAPX'])
            ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPY'])
            urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_MAPX'])
            lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPY'])
            lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_MAPX'])
            lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPY'])
            llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_MAPX'])
            prjext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                      [ulx, uly]]

            self.metadata['imgdate'] = md['PRODUCT_METADATA'][
                'ACQUISITION_DATE']
            self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][
                'RESAMPLING_OPTION']
            try:
                self.metadata['viewangle'] = float(
                    md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'
            try:
                self.metadata['sunazimuth'] = float(
                    md['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'
            try:
                self.metadata['sunelevation'] = float(
                    md['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'

            #EPSG:32601: WGS 84 / UTM zone 1N
            #EPSG:32701: WGS 84 / UTM zone 1S
            srs = osr.SpatialReference()
            zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER'])
            if zone > 0: epsg = 32600 + zone  #North
            else: epsg = 32700 - zone  #South
            srs.ImportFromEPSG(epsg)
            self.metadata['units'] = 'm'
            self.metadata['srs'] = srs.ExportToWkt()
            self.metadata['epsg'] = str(epsg)

        elif re.search(r'eo1.*_hdf\.l1g$', f):
            self.metadata['level'] = 'L1G'
            self.metadata['sensor'] = 'ALI'
            self.metadata['sceneid'] = self.metadata['filename'].split('_')[0]

            gdalDataset = geometry.OpenDataset(f)
            #if not gdalDataset: #Error now raised in geometry.OpenDataset
            #    errmsg=gdal.GetLastErrorMsg()
            #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

            self.metadata['filetype'] = '%s/%s (%s %s)' % (
                gdalDataset.GetDriver().ShortName,
                gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                self.metadata['level'])

            hdf_sd = gdalDataset.GetSubDatasets()
            hdf_md = gdalDataset.GetMetadata()
            sd, sz = hdf_sd[0]
            sd = geometry.OpenDataset(sd)
            sd_md = sd.GetMetadata()
            ncols = []
            nrows = []
            nbands = 0
            bands = []
            for sd, sz in hdf_sd:
                bands.append(sd)
                ds = geometry.OpenDataset(sd)
                ncols.append(str(ds.RasterXSize))
                nrows.append(str(ds.RasterYSize))
                nbands += 1

            #get all multi bands for use in overview generation
            pancols = max(ncols)
            panindex = ncols.index(pancols)
            multibands = bands
            multincols = ncols
            multinrows = nrows
            if pancols > min(ncols):  #there is a pan band
                multibands.pop(panindex)
                multincols.pop(panindex)
                multinrows.pop(panindex)
            multibands.sort()
            self._gdaldataset = geometry.OpenDataset(
                geometry.CreateSimpleVRT(multibands, multincols[0],
                                         multinrows[0], 'Int16'))
            self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(4).SetNoDataValue(0)
            self._stretch = ('STDDEV', (4, 3, 2), [2])

            ncols = ','.join(ncols)
            nrows = ','.join(nrows)

            met = f.lower().replace('_hdf.l1g', '_mtl.l1g')
            md = {}
            for line in open(met, 'r'):
                line = line.replace('"', '')
                line = [l.strip() for l in line.split('=')]
                if line[0] == 'END':  #end of the metadata file
                    break
                elif line[0] == 'GROUP':  #start of a metadata group
                    if line[1] != 'L1_METADATA_FILE':
                        group = line[1]
                        md[group] = {}
                elif line[0] == 'END_GROUP':  #end of a metadata group
                    pass
                else:  #metadata value
                    md[group][line[0]] = line[1]

            uly = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LAT'])
            ulx = float(md['PRODUCT_METADATA']['PRODUCT_UL_CORNER_LON'])
            ury = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LAT'])
            urx = float(md['PRODUCT_METADATA']['PRODUCT_UR_CORNER_LON'])
            lry = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LAT'])
            lrx = float(md['PRODUCT_METADATA']['PRODUCT_LR_CORNER_LON'])
            lly = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LAT'])
            llx = float(md['PRODUCT_METADATA']['PRODUCT_LL_CORNER_LON'])
            geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                      [ulx, uly]]
            prjext = geoext

            self.metadata['imgdate'] = md['PRODUCT_METADATA'][
                'ACQUISITION_DATE']
            self.metadata['resampling'] = md['PROJECTION_PARAMETERS'][
                'RESAMPLING_OPTION']
            try:
                self.metadata['viewangle'] = float(
                    md['PRODUCT_PARAMETERS']['SENSOR_LOOK_ANGLE'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'
            try:
                self.metadata['sunazimuth'] = float(
                    md['PRODUCT_PARAMETERS']['SUN_AZIMUTH'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'
            try:
                self.metadata['sunelevation'] = float(
                    md['PRODUCT_PARAMETERS']['SUN_ELEVATION'])
            except:
                pass  #Exception raised if value == 'UNAVAILABLE'

            #EPSG:32601: WGS 84 / UTM zone 1N
            #EPSG:32701: WGS 84 / UTM zone 1S
            srs = osr.SpatialReference()
            zone = int(md['UTM_PARAMETERS']['ZONE_NUMBER'])
            if zone > 0: epsg = 32600 + zone  #North
            else: epsg = 32700 - zone  #South
            srs.ImportFromEPSG(epsg)
            self.metadata['units'] = 'm'
            self.metadata['srs'] = srs.ExportToWkt()
            self.metadata['epsg'] = str(epsg)

        else:
            self.metadata['level'] = 'L1R'
            self.metadata['sensor'] = 'HYPERION'

            gdalDataset = geometry.OpenDataset(f)
            #if not gdalDataset: #Error now raised in geometry.OpenDataset
            #    errmsg=gdal.GetLastErrorMsg()
            #    raise IOError, 'Unable to open %s\n%s' % (f,errmsg.strip())

            self.metadata['filetype'] = '%s/%s (%s %s)' % (
                gdalDataset.GetDriver().ShortName,
                gdalDataset.GetDriver().LongName, self.metadata['sensor'],
                self.metadata['level'])
            srs = osr.SpatialReference()
            srs.ImportFromEPSG(4326)
            self.metadata['srs'] = srs.ExportToWkt()
            self.metadata['epsg'] = 4326
            self.metadata['units'] = 'deg'

            hdf_sd = gdalDataset.GetSubDatasets()
            hdf_md = gdalDataset.GetMetadata()
            sd, sz = hdf_sd[0]
            sd = geometry.OpenDataset(sd)
            sd_md = sd.GetMetadata()
            nbands = sd.RasterCount
            ncols = sd.RasterXSize
            nrows = sd.RasterYSize
            met = os.path.splitext(f)[0] + '.met'
            for line in open(met, 'r').readlines():
                if line[0:16] == 'Scene Request ID':
                    line = line.strip().split()
                    self.metadata['sceneid'] = line[3]
                if line[0:14] == 'HYP Start Time':
                    line = line.strip().split()
                    imgdate = time.strptime(line[3] + line[4], '%Y%j')
                    self.metadata['imgdate'] = time.strftime(
                        '%Y-%m-%d', imgdate)  #ISO 8601
                if line[0:8] == 'PRODUCT_':
                    line = line.strip()
                    line = map(string.strip, line.split('='))
                    if line[0] == 'PRODUCT_UL_CORNER_LAT': uly = float(line[1])
                    if line[0] == 'PRODUCT_UL_CORNER_LON': ulx = float(line[1])
                    if line[0] == 'PRODUCT_UR_CORNER_LAT': ury = float(line[1])
                    if line[0] == 'PRODUCT_UR_CORNER_LON': urx = float(line[1])
                    if line[0] == 'PRODUCT_LR_CORNER_LAT': lry = float(line[1])
                    if line[0] == 'PRODUCT_LR_CORNER_LON': lrx = float(line[1])
                    if line[0] == 'PRODUCT_LL_CORNER_LAT': lly = float(line[1])
                    if line[0] == 'PRODUCT_LL_CORNER_LON': llx = float(line[1])
            geoext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly],
                      [ulx, uly]]
            prjext = geoext

            #########################################################################################################
            ##set self._gdaldataset for use in overview generation
            ##we'll use bands 21, 30 & 43 for RGB (http://edcsns17.cr.usgs.gov/eo1/Hyperion_Spectral_Coverage.htm)
            ##as they're near the center of the equivalent ALI bands

            ##This generates verrrryyy looong overviews cos hyperion data is one long thin strip eg. 256*3000 etc...
            #self._gdaldataset = geometry.CreateVRTCopy(sd)
            ##Instead we can clip out some of the centre rows
            #vrtcols=ncols
            #vrtrows=int(ncols*1.5)
            #srcrect=[0, int(nrows/2-vrtrows/2),ncols,vrtrows]
            #dstrect=[0, 0,ncols,vrtrows]
            ##Or we can fill out the ncols with nodata
            vrtcols = int(nrows / 1.5)
            vrtrows = nrows
            srcrect = [0, 0, ncols, nrows]
            dstrect = [int(nrows / 2.5 - ncols), 0, ncols, nrows]
            vrt = geometry.CreateMosaicedVRT([sd.GetDescription()],
                                             [43, 30, 21], [srcrect],
                                             [dstrect], vrtcols, vrtrows,
                                             self.metadata['datatype'])
            self._gdaldataset = geometry.OpenDataset(vrt)
            self._gdaldataset.GetRasterBand(3).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(2).SetNoDataValue(0)
            self._gdaldataset.GetRasterBand(1).SetNoDataValue(0)
            self._stretch = ('STDDEV', (1, 2, 3), [2])
            #########################################################################################################
        self.metadata['cols'] = ncols
        self.metadata['rows'] = nrows
        self.metadata['nbands'] = nbands

        #Geotransform
        ncols = map(int, str(ncols).split(','))
        nrows = map(int, str(nrows).split(','))
        cellx, celly = [], []
        j = 0
        while j < len(ncols):
            gcps = []
            i = 0
            lr = [[0, 0], [ncols[j], 0], [ncols[j], nrows[j]], [0, nrows[j]]]
            while i < len(prjext) - 1:  #don't need the last xy pair
                gcp = gdal.GCP()
                gcp.GCPPixel, gcp.GCPLine = lr[i]
                gcp.GCPX, gcp.GCPY = prjext[i]
                gcp.Id = str(i)
                gcps.append(gcp)
                i += 1
            j += 1
            geotransform = gdal.GCPsToGeoTransform(gcps)
            x, y = geometry.CellSize(geotransform)
            cellx.append(str(x))
            celly.append(str(abs(y)))

        self.metadata['cellx'] = ','.join(cellx)
        self.metadata['celly'] = ','.join(celly)

        self.metadata['UL'] = '%s,%s' % tuple(geoext[0])
        self.metadata['UR'] = '%s,%s' % tuple(geoext[1])
        self.metadata['LR'] = '%s,%s' % tuple(geoext[2])
        self.metadata['LL'] = '%s,%s' % tuple(geoext[3])

        self.metadata['rotation'] = geometry.Rotation(geotransform)
        if abs(self.metadata['rotation']) < 1.0:
            self.metadata['orientation'] = 'Map oriented'
            self.metadata['rotation'] = 0.0
        else:
            self.metadata['orientation'] = 'Path oriented'

        self.metadata['filesize'] = sum(
            [os.path.getsize(tmp) for tmp in self.filelist])
        self.metadata['compressionratio'] = 0
        self.metadata['compressiontype'] = 'None'
        self.extent = geoext
Пример #17
0
def getoverview(ds,outfile,width,format,bands,stretch_type,*stretch_args):
    '''
    Generate overviews for imagery

    @type  ds:      C{GDALDataset}
    @param ds:      a GDALDataset object
    @type  outfile: C{str}
    @param outfile: a filepath to the output overview image. If supplied, format is determined from the file extension
    @type  width:   C{int}
    @param width:   output image width
    @type  format:  C{str}
    @param format:  format to generate overview image, one of ['JPG','PNG','GIF','BMP','TIF']. Not required if outfile is supplied.
    @type  bands:   C{list}
    @param bands:   list of band numbers (base 1) in processing order - e.g [3,2,1]
    @type  stretch_type:  C{str}
    @param stretch_type:  stretch to apply to overview image,
                          one of [L{NONE<_stretch_NONE>},L{PERCENT<_stretch_PERCENT>},L{MINMAX<_stretch_MINMAX>},L{STDDEV<_stretch_STDDEV>},L{COLOURTABLE<_stretch_COLOURTABLE>},L{COLOURTABLELUT<_stretch_COLOURTABLELUT>},L{RANDOM<_stretch_RANDOM>},L{UNIQUE<_stretch_UNIQUE>}].
    @type stretch_args:   C{list}
    @param stretch_args:  args to pass to the stretch algorithms
    @rtype:         C{str}
    @return:        filepath (if outfile is supplied)/binary image data (if outfile is not supplied)
    '''

    #mapping table for file extension -> GDAL format code
    imageformats={'JPG':'JPEG', #JPEG JFIF (.jpg)
                  'PNG':'PNG',  #Portable Network Graphics (.png)
                  'GIF':'GIF',  #Graphics Interchange Format (.gif)
                  'BMP':'BMP',  #Microsoft Windows Device Independent Bitmap (.bmp)
                  'TIF':'GTiff' #Tagged Image File Format/GeoTIFF (.tif)
                 }
    if outfile:
        outfile=utilities.encode(outfile)
        format=os.path.splitext(outfile)[1].replace('.','')                  #overrides "format" arg if supplied
    ovdriver=gdal.GetDriverByName(imageformats.get(format.upper(), 'JPEG'))  #Get format code, default to 'JPEG' if supplied format doesn't match the predefined ones...

    cols=ds.RasterXSize
    rows=ds.RasterYSize
    vrtcols=width
    vrtrows=int(math.ceil(width*float(rows)/cols))

    vrtdrv=gdal.GetDriverByName('VRT')
    tempvrts={} #dict with keys=file descriptor and values=[filename,GDALDataset]

    #Below is a bit of a kludge to handle creating a VRT that is based on an in-memory vrt file
    drv=ds.GetDriver().ShortName
    desc=ds.GetDescription()
    if drv == 'VRT':
        if not desc or desc[0] == '<':# input path is an in-memory vrt file
            vrtfd,vrtfn=tempfile.mkstemp('.vrt')
            ds=vrtdrv.CreateCopy(vrtfn,ds)
            tempvrts[vrtfd]=[vrtfn,ds]

    #if stretch_type != 'NONE':
    #    tmpxml=stretch('NONE',vrtcols,vrtrows,ds,bands)
    #    vrtfd,vrtfn=tempfile.mkstemp('.vrt')
    #    ds=vrtdrv.CreateCopy(vrtfn,geometry.OpenDataset(tmpxml))
    #    tempvrts[vrtfd]=[vrtfn,ds]

    vrtxml=stretch(stretch_type,vrtcols,vrtrows,ds,bands,*stretch_args)
    vrtds=geometry.OpenDataset(vrtxml)
    if outfile:
        cpds=ovdriver.CreateCopy(outfile, vrtds)
        if not cpds:raise geometry.GDALError, 'Unable to generate overview image.'
    else:
        fd,fn=tempfile.mkstemp(suffix='.'+format.lower(), prefix='getoverviewtempimage')
        cpds=ovdriver.CreateCopy(fn, vrtds)
        if not cpds:raise geometry.GDALError, 'Unable to generate overview image.'

        outfile=os.fdopen(fd).read()
        os.unlink(fn)
    for vrt in tempvrts:
        tempvrts[vrt][1]=None
        os.close(vrt)
        del tempvrts[vrt][1]
        os.unlink(tempvrts[vrt][0])
    return outfile
Пример #18
0
    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
Пример #19
0
    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)
Пример #20
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
Пример #21
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
Пример #22
0
    def v2(self, f=None):
        if not f: f = self.fileinfo['filepath']
        dom = self._dom
        self.metadata['sceneid'] = dom.xpath(
            'string(/Dimap_Document/Dataset_Identification/DATASET_NAME)')
        try:
            self._gdaldataset = geometry.OpenDataset(f)
            __default__.Dataset.__getmetadata__(
                self)  #autopopulate basic metadata
        except:
            ncols = dom.xpath('number(//*/NCOLS)')
            nrows = dom.xpath('number(//*/NROWS)')
            nbands = dom.xpath('number(//*/NBANDS)')
            nbits = dom.xpath('number(//*/NBITS)')
            if nbits == 16: datatype = 'UInt16'
            else: datatype = 'Byte'
            if nbands == 1:
                bands = [1]
            else:
                bands = [
                    int(b[1:]) for b in [
                        dom.xpath('string(//*/RED_CHANNEL)'),
                        dom.xpath('string(//*/GREEN_CHANNEL)'),
                        dom.xpath('string(//*/BLUE_CHANNEL)')
                    ]
                ]
            self.metadata['bands'] = ','.join(map(str, bands))

            if dom.xpath('string(//*/DATA_FILE_TILES)') == 'true':
                import math
                ntiles = dom.xpath('number(//*/NTILES)')
                if dom.xpath('boolean(//*/NTILES_COUNT/@ntiles_x)'):
                    ntiles_x = dom.xpath('number(//*/NTILES_COUNT/@ntiles_x)')
                    ntiles_y = dom.xpath('number(//*/NTILES_COUNT/@ntiles_y)')
                elif dom.xpath('boolean(//*/NTILES_COUNT/@ntiles_C)'):
                    ntiles_x = dom.xpath('number(//*/NTILES_COUNT/@ntiles_C)')
                    ntiles_y = dom.xpath('number(//*/NTILES_COUNT/@ntiles_R)')

                tile_cols = math.ceil(ncols / ntiles_x)
                last_tile_cols = tile_cols - (ntiles_x * tile_cols - ncols)
                tile_rows = math.ceil(nrows / ntiles_y)
                last_tile_rows = tile_rows - (ntiles_y * tile_rows - nrows)
                srcrects, dstrects = [], []
                files = []
                for df in dom.xpath('//*/Data_File'):
                    col = df.xpath('number(@tile_C)')
                    row = df.xpath('number(@tile_R)')
                    datafile = os.path.join(
                        os.path.dirname(f),
                        df.xpath('string(DATA_FILE_PATH/@href)'))
                    exists, datafile = utilities.exists(
                        datafile, True
                    )  #Work around reading images with lowercase filenames when the DATA_FILE_PATH is uppercase
                    # - eg samba filesystems which get converted to lowercase
                    if (row, col) == (1, 1): r1c1 = datafile
                    srcrect = [0, 0, tile_cols, tile_rows]
                    dstrect = [(ntiles_x - 1) * tile_cols,
                               (ntiles_y - 1) * tile_rows, tile_cols,
                               tile_rows]
                    if col == ntiles_x:  #last col
                        srcrect[2] = last_tile_cols
                        dstrect[2] = last_tile_cols
                    if row == ntiles_y:  #last row
                        srcrect[3] = last_tile_rows
                        dstrect[3] = last_tile_rows

                    files.append(datafile)
                    srcrects.append(srcrect)
                    dstrects.append(dstrect)

                self._gdaldataset = geometry.OpenDataset(
                    geometry.CreateMosaicedVRT(files, bands, srcrects,
                                               dstrects, ncols, nrows,
                                               datatype))
                ds = geometry.OpenDataset(r1c1)
                self._gdaldataset.SetGeoTransform(ds.GetGeoTransform())
                self._gdaldataset.SetProjection(ds.GetProjection())

            else:
                datafile = os.path.join(
                    os.path.dirname(f),
                    dom.xpath('string(//*/DATA_FILE_PATH/@href)'))
                exists, datafile = utilities.exists(datafile, True)
                self._gdaldataset = geometry.OpenDataset(datafile)

            __default__.Dataset.__getmetadata__(self)

        dates = {}
        for src in dom.xpath('//Source_Identification'):
            datetime = '%sT%s' % (src.xpath('string(//*/IMAGING_DATE)'),
                                  src.xpath('string(//*/IMAGING_TIME)')[:8])
            dts = time.mktime(time.strptime(
                datetime, utilities.datetimeformat))  #ISO 8601
            dates[dts] = datetime
        if len(dates) == 1:
            self.metadata['imgdate'] = datetime
        else:
            self.metadata['imgdate'] = '%s/%s' % (dates[min(
                dates.keys())], dates[max(dates.keys())])

        self.metadata['satellite'] = '%s %s' % (src.xpath(
            'string(//*/MISSION)'), src.xpath('string(//*/MISSION_INDEX)'))
        try:
            self.metadata['sensor'] = '%s %s' % (
                src.xpath('string(//*/INSTRUMENT)'),
                src.xpath('string(//*/INSTRUMENT_INDEX)'))
        except:
            self.metadata['sensor'] = '%s' % src.xpath(
                'string(//*/INSTRUMENT)')
        try:
            sunangles = dom.xpath(
                '//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Solar_Incidences'
            )[0]
            self.metadata['sunelevation'] = sunangles.xpath(
                'number(SUN_ELEVATION)')
            self.metadata['sunazimuth'] = sunangles.xpath(
                'number(SUN_AZIMUTH)')
        except:
            pass
        try:
            self.metadata['viewangle'] = dom.xpath(
                'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/VIEWING_ANGLE)'
            )
            self.metadata['satelevation'] = dom.xpath(
                'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/INCIDENCE_ANGLE)'
            )
            self.metadata['satazimuth'] = dom.xpath(
                'number(//*/Located_Geometric_Values[LOCATION_TYPE="Center"]/Acquisition_Angles/AZIMUTH_ANGLE)'
            )
        except:
            pass

        try:
            self.metadata['level'] = dom.xpath(
                'string(//*/Processing_Information/Product_Settings/PROCESSING_LEVEL)'
            )
        except:
            pass
        try:
            self.metadata['resampling'] = dom.xpath(
                'string(//*/Processing_Information/Product_Settings/Sampling_Settings/RESAMPLING_KERNEL)'
            )
        except:
            pass

        self.metadata['metadata'] = etree.tostring(dom, pretty_print=True)
Пример #23
0
    def __getmetadata__(self):
        '''Read Metadata for an ACRES Landsat FastL7A format image as GDAL doesn't get it all.
        Format description: http://www.ga.gov.au/image_cache/GA10348.pdf

        Note:
        hrf = ~30m VNIR/SWIR       (bands 1-5 & 7)
        htm = ~60m thermal         (band 6)
        hpn = ~15m pan             (band 8)
        '''

        f = self.fileinfo['filepath']
        d = os.path.dirname(f)
        hdr = open(f).read()
        err = 'Unable to open %s' % f

        md = self.metadata
        md['filesize'] = sum([os.path.getsize(file) for file in self.filelist])
        md['filetype'] = 'FAST/EOSAT FAST Format'

        rl = 1536  #recordlength

        ######################################
        ##Record 1 - administrative
        ######################################
        rec = 1

        req_id = utilities.readascii(hdr, (rec - 1) * rl, 9, 28)
        loc = utilities.readascii(hdr, (rec - 1) * rl, 35, 51)
        acquisition_date = utilities.readascii(hdr, (rec - 1) * rl, 71, 78)
        md['imgdate'] = '%s-%s-%s' % (
            acquisition_date[:4], acquisition_date[4:6], acquisition_date[6:])
        md['satellite'] = utilities.readascii(hdr, (rec - 1) * rl, 92, 101)
        md['sensor'] = utilities.readascii(hdr, (rec - 1) * rl, 111, 120)
        md['mode'] = utilities.readascii(hdr, (rec - 1) * rl, 135, 140)
        md['viewangle'] = float(
            utilities.readascii(hdr, (rec - 1) * rl, 154, 159))
        product_type = utilities.readascii(hdr, (rec - 1) * rl, 655, 672)
        product_size = utilities.readascii(hdr, (rec - 1) * rl, 688, 697)
        level = utilities.readascii(hdr, (rec - 1) * rl, 741, 751)
        md['resampling'] = utilities.readascii(hdr, (rec - 1) * rl, 765, 766)
        md['cols'] = int(utilities.readascii(hdr, (rec - 1) * rl, 843, 847))
        md['rows'] = int(utilities.readascii(hdr, (rec - 1) * rl, 865, 869))
        md['cellx'] = float(utilities.readascii(hdr, (rec - 1) * rl, 954, 959))
        md['celly'] = md['cellx']
        md['nbits'] = 8  #int(utilities.readascii(hdr,(rec-1)*rl,984,985)) always 8 bit
        md['datatype'] = 'Byte'
        md['nodata'] = '0'
        bands_present = utilities.readascii(hdr, (rec - 1) * rl, 1056, 1087)

        bandindices = [[1131, 1159], [1170, 1198], [1211, 1239], [1250, 1278],
                       [1291, 1319], [1330, 1358]]
        bandfiles = {}
        for i in bandindices:
            band = utilities.readascii(hdr, (rec - 1) * rl, i[0], i[1])
            if band:
                exists, path = utilities.exists(os.path.join(d, band), True)
                if exists: bandfiles[band] = path
                else:  #Assume ACRES format (band*.dat) instead Fast format (l7*.fst)...
                    bandid = band[23:25]
                    if bandid == '61': bandid = '6l'
                    elif bandid == '62': bandid = '6h'
                    else: bandid = bandid[0]
                    exists, path = utilities.exists(
                        os.path.join(d, 'band%s.dat' % bandid), True)
                    if not exists:
                        raise RuntimeError, 'Unable to open band data files.'
                    bandfiles[band] = path
            else:
                break
        md['nbands'] = len(bandfiles)

        md['sceneid'] = os.path.basename(
            bandfiles.keys()[0]
        )[3:
          21]  #Use path/row & aquisition date as sceneid - L7f[ppprrr_rrrYYYYMMDD]_AAA.FST
        if self._filetype == 'HRF':
            md['bands'] = '1 (BLUE),2 (GREEN),3 (RED),4 (NIR),5 (SWIR),7 (SWIR)'
        elif self._filetype == 'HTM':
            md['bands'] = '6L (THERMAL),6H (THERMAL)'
        elif self._filetype == 'HPN':
            md['bands'] = '8 (PAN)'

        ######################################
        ##Record 2 - radiometric
        ######################################
        #Move along, nothing to see here...

        ######################################
        ##Record 3 - geometric
        ######################################
        rec = 3
        map_projection = utilities.readascii(hdr, (rec - 1) * rl, 32, 35)
        prjcode = spatialreferences.GCTP_PROJECTIONS.get(map_projection, 0)
        ellipsoid = utilities.readascii(hdr, (rec - 1) * rl, 48, 65)
        ellcode = spatialreferences.GCTP_ELLIPSOIDS.get(ellipsoid, 0)
        datum = utilities.readascii(hdr, (rec - 1) * rl, 74, 79)
        zone = utilities.readascii(hdr, (rec - 1) * rl, 521, 526)

        #Workaround for UTM zones as GDAL does not pick up southern hemisphere
        #as some FST headers don't include a negative zone number to indicate southern hemisphere
        #as per the FAST format definition
        zone = int(zone) if zone else 0

        usgs_indices = (
            (110, 133),  #Semi-major axis
            (135, 158),  #Semi-minor axis
            (161, 184),
            (186, 209),
            (211, 234),
            (241, 264),
            (266, 289),
            (291, 314),
            (321, 344),
            (346, 369),
            (371, 394),
            (401, 424),
            (426, 449),
            (451, 474),
            (481, 504))
        usgs_params = []
        for i in usgs_indices:
            p = utilities.readascii(hdr, (rec - 1) * rl, i[0], i[1])
            if p: usgs_params.append(float(p))
            else: usgs_params.append(0.0)

        ulx = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 566, 578),
            'DDDMMSSSSSSSH')
        uly = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 580, 591), 'DDMMSSSSSSSH')
        urx = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 646, 658),
            'DDDMMSSSSSSSH')
        ury = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 660, 671), 'DDMMSSSSSSSH')
        lrx = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 726, 738),
            'DDDMMSSSSSSSH')
        lry = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 740, 751), 'DDMMSSSSSSSH')
        llx = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 806, 818),
            'DDDMMSSSSSSSH')
        lly = geometry.DMS2DD(
            utilities.readascii(hdr, (rec - 1) * rl, 820, 831), 'DDMMSSSSSSSH')
        ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]]

        md['UL'] = '%s,%s' % tuple(ext[0])
        md['UR'] = '%s,%s' % tuple(ext[1])
        md['LR'] = '%s,%s' % tuple(ext[2])
        md['LL'] = '%s,%s' % tuple(ext[3])

        if zone > 0 and uly < 0: zone *= -1
        srs = osr.SpatialReference()
        srs.ImportFromUSGS(prjcode, zone, usgs_params, ellcode)
        if datum == 'GDA':  #Workaround for GDA94 datum as GDAL does not recognise it
            #as per the FAST format definition
            if map_projection == 'UTM':
                epsg = 28300 + abs(zone)
                srs.ImportFromEPSG(epsg)
                md['srs'] = srs.ExportToWkt()
                md['epsg'] = epsg
                md['units'] = 'm'
            else:
                srs.SetGeogCS('GDA94', 'Geocentric_Datum_of_Australia_1994',
                              'GRS 1980', usgs_params[0], 298.257)
                md['srs'] = srs.ExportToWkt()
                md['epsg'] = spatialreferences.IdentifyAusEPSG(md['srs'])
                md['units'] = spatialreferences.GetLinearUnitsName(md['srs'])
        else:
            md['srs'] = srs.ExportToWkt()
            md['epsg'] = spatialreferences.IdentifyAusEPSG(md['srs'])
            md['units'] = spatialreferences.GetLinearUnitsName(md['srs'])

        md['rotation'] = float(
            utilities.readascii(hdr, (rec - 1) * rl, 995, 1000))
        if abs(md['rotation']) < 1:
            md['orientation'] = 'Map oriented'
            md['rotation'] = 0.0
        else:
            md['orientation'] = 'Path oriented'
        md['sunelevation'] = utilities.readascii(hdr, (rec - 1) * rl, 1062,
                                                 1065)
        md['sunazimuth'] = utilities.readascii(hdr, (rec - 1) * rl, 1086, 1090)

        try:  ##Open dataset
            self._gdaldataset = geometry.OpenDataset(f)
            metadata = self._gdaldataset.GetMetadata()
            md['metadata'] = '\n'.join(
                ['%s: %s' % (m, metadata[m]) for m in metadata])
            #Fix for Issue 17
            for i in range(1, self._gdaldataset.RasterCount + 1):
                self._gdaldataset.GetRasterBand(i).SetNoDataValue(
                    float(md['nodata']))

        except:  #build a VRT dataset - if we want to use this for anything other than overview generation, should probably fill out the geotransform, srs, metadata etc...
            bands = bandfiles.values()
            bands.sort()
            #vrtxml=geometry.CreateRawRasterVRT(bands,md['cols'],md['rows'], md['datatype']) #Fix for Issue 17
            vrtxml = geometry.CreateRawRasterVRT(bands,
                                                 md['cols'],
                                                 md['rows'],
                                                 md['datatype'],
                                                 nodata=md['nodata'])
            self._gdaldataset = geometry.OpenDataset(vrtxml)
            md['metadata'] = hdr

        if self._filetype == 'HRF':
            self._gdaldataset.GetRasterBand(4).SetRasterColorInterpretation(
                gdal.GCI_BlueBand)
            self._gdaldataset.GetRasterBand(3).SetRasterColorInterpretation(
                gdal.GCI_GreenBand)
            self._gdaldataset.GetRasterBand(2).SetRasterColorInterpretation(
                gdal.GCI_RedBand)

        if level == 'SYSTEMATIC': md['level'] = '1G '
        elif level == 'SYSTERRAIN': md['level'] = '1Gt'
        elif level == 'PRECISION': md['level'] = '1P'
        elif level == 'TERRAIN': md['level'] = '1T'

        md['compressionratio'] = 0
        md['compressiontype'] = 'None'

        self.extent = ext

        for m in md:
            self.metadata[m] = md[m]
Пример #24
0
    def __gettilevrt__(self, f, imddata):
        til = iter(open(f).readlines())
        tileinfo = {}
        datasets = {}
        line = til.next()
        while line:  #Extract all keys and values from the header file into a dictionary
            line = line.strip().strip(';').replace('"', '')
            if line == 'END': break
            if 'BEGIN_GROUP' in line:
                line = til.next()
                while line:
                    line = line.strip().strip(';').replace('"', '')
                    if 'END_GROUP' in line: break
                    else:
                        dat = map(string.strip, line.split('=', 1))
                        if not dat[0] in datasets: datasets[dat[0]] = []
                        datasets[dat[0]].append(dat[1])
                    line = til.next()
            else:
                var = map(string.strip, line.split('=', 1))
                tileinfo[var[0]] = var[1]
            line = til.next()
        curdir = os.path.dirname(f)
        bimg, img = utilities.exists(
            os.path.join(curdir, datasets['filename'][0]), True)
        ds = geometry.OpenDataset(img)
        rb = ds.GetRasterBand(1)
        DataType = gdal.GetDataTypeName(rb.DataType)
        GeoTransform = ds.GetGeoTransform()
        Projection = ds.GetProjection()
        if GeoTransform == (0.0, 1.0, 0.0, 0.0, 0.0, 1.0):
            GeoTransform = gdal.GCPsToGeoTransform(ds.GetGCPs())
        if Projection == '':
            Projection = ds.GetGCPProjection()
        GeoTransform = ','.join(map(str, GeoTransform))
        numTiles = int(tileinfo['numTiles'])
        BlockXSize, BlockYSize = rb.GetBlockSize()

        vrtXML = []
        vrtXML.append('<VRTDataset rasterXSize="%s" rasterYSize="%s">' %
                      (imddata['numColumns'], imddata['numRows']))
        vrtXML.append('<SRS>%s</SRS>' % Projection)
        vrtXML.append('<GeoTransform>%s</GeoTransform>' % GeoTransform)

        for b, band in enumerate(imddata['bands']):
            b += 1
            vrtXML.append(' <VRTRasterBand dataType="%s" band="%s">' %
                          (DataType, b))
            #vrtXML.append('  <ColorInterp>Gray</ColorInterp>')
            for tile in range(0, numTiles):
                tileSizeX = int(datasets['URColOffset'][tile]) - int(
                    datasets['ULColOffset'][tile]) + 1
                tileSizeY = int(datasets['LLRowOffset'][tile]) - int(
                    datasets['ULRowOffset'][tile]) + 1
                ULColOffset = datasets['ULColOffset'][tile]
                ULRowOffset = datasets['ULRowOffset'][tile]
                bimg, img = utilities.exists(
                    os.path.join(curdir, datasets['filename'][tile]), True)
                vrtXML.append('  <SimpleSource>')
                vrtXML.append(
                    '   <SourceFilename  relativeToVRT="0">%s</SourceFilename>'
                    % img)
                vrtXML.append('   <SourceBand>%s</SourceBand>' % (b))
                vrtXML.append(
                    '   <SourceProperties RasterXSize="%s" RasterYSize="%s" DataType="%s"/>'
                    % (tileSizeX, tileSizeY, DataType)
                )  # BlockXSize="%s" BlockYSize="%s"/>'(tileSizeX,tileSizeY,DataType,BlockXSize,BlockYSize))
                vrtXML.append(
                    '   <SrcRect xOff="0" yOff="0" xSize="%s" ySize="%s"/>' %
                    (tileSizeX, tileSizeY))
                vrtXML.append(
                    '   <DstRect xOff="%s" yOff="%s" xSize="%s" ySize="%s"/>' %
                    (ULColOffset, ULRowOffset, tileSizeX, tileSizeY))
                vrtXML.append('  </SimpleSource>')
            vrtXML.append(' </VRTRasterBand>')
        vrtXML.append('</VRTDataset>')
        vrtXML = '\n'.join(vrtXML)
        return vrtXML