예제 #1
0
    def __init__(self, f):
        if f[:4] == '/vsi': raise NotImplementedError
        self.filelist = glob.glob(os.path.dirname(f) + '/*')
        if os.path.splitext(f)[1].lower() != 'imd':
            imd = glob.glob(os.path.splitext(f)[0] + '.[Ii][Mm][Dd]')
            if imd:
                self.__setfileinfo__(imd[0])
            else:
                raise NotImplementedError, 'No matching IMD file'

        self.exts = {
            '.tif': 'GTiff/GeoTIFF',
            '.img': 'HFA/Erdas Imagine Images (.img)',
            '.ntf': 'NITF/National Imagery Transmission Format (.ntf)',
            '.pix': 'PCI Geomatics Database File (.pix)'
        }
        self.til = False
        self.img = False

        btil, self.til = utilities.exists(
            os.path.splitext(f)[0] + '.til', True)
        if not btil:
            for ext in self.exts:
                bext, ext = utilities.exists(
                    os.path.splitext(f)[0] + ext, True)
                if bext:
                    self.img = ext
                    break

            if not self.img:
                raise NotImplementedError, 'Matching DigitalGlobe imagery file not found:\n'
예제 #2
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
예제 #3
0
 def xlsxcallback(xlsxarg,updatearg):
     #xlsx=xlsxarg.value.get()
     xlsx=xlsxarg.value
     if utilities.exists(xlsx):
         updatearg.enabled=True
         #updatearg.value.set(True)
         updatearg.value=True
     else:
         updatearg.enabled=False
         #updatearg.value.set(False)
         updatearg.value=False
예제 #4
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
예제 #5
0
    def __init__(self,f):
        if f[:4]=='/vsi':raise NotImplementedError
        self.filelist=glob.glob(os.path.dirname(f)+'/*')
        if os.path.splitext(f)[1].lower() !='imd':
            imd=glob.glob(os.path.splitext(f)[0]+'.[Ii][Mm][Dd]')
            if imd:
                self.__setfileinfo__(imd[0])
            else:raise NotImplementedError, 'No matching IMD file'

        self.exts={'.tif':'GTiff/GeoTIFF','.img':'HFA/Erdas Imagine Images (.img)','.ntf':'NITF/National Imagery Transmission Format (.ntf)','.pix':'PCI Geomatics Database File (.pix)'}
        self.til=False
        self.img=False

        btil,self.til = utilities.exists(os.path.splitext(f)[0]+'.til',True)
        if not btil:
            for ext in self.exts:
                bext,ext = utilities.exists(os.path.splitext(f)[0]+ext,True)
                if bext:
                    self.img=ext
                    break

            if not self.img:raise NotImplementedError, 'Matching DigitalGlobe imagery file not found:\n'
예제 #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
    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
예제 #8
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]
예제 #9
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
예제 #10
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]
예제 #11
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
예제 #12
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)
    def __getmetadata__(self):
        '''Read Metadata for an Digital Globe format image as GDAL doesn't quite get it all...

        @todo: Fix QB GDA94 Geographic CS "Unknown datum" problem
        '''
        f=self.fileinfo['filepath']
        imddata=self.__getimddata__(f)
        
        exts={'.tif':'GTiff/GeoTIFF','.img':'HFA/Erdas Imagine Images (.img)','.ntf':'NITF/National Imagery Transmission Format (.ntf)','.pix':'PCI Geomatics Database File (.pix)'}
        btil,til = utilities.exists(os.path.splitext(f)[0]+'.til',True)
        if btil:
            vrt=self.__gettilevrt__(til,imddata)
            __default__.Dataset.__getmetadata__(self, vrt)
            for tmp in self.filelist:
                for ext in exts:
                    if tmp[-4:].lower()==ext:
                        self.metadata['filetype']=exts[ext]
                        break
        else:
            img=False
            for ext in exts:
                bext,ext = utilities.exists(os.path.splitext(f)[0]+ext,True)
                if bext:
                    __default__.Dataset.__getmetadata__(self, ext)
                    img=True
                    break

            if not img:raise IOError, 'Matching DigitalGlobe imagery file not found:\n'

        self.metadata['metadata']=open(f).read()

        if imddata.has_key('IMAGE_1'):imgkey='IMAGE_1'
        else:imgkey='SINGLE_IMAGE_PRODUCT'
        if imddata.has_key('MAP_PROJECTED_PRODUCT'):
            imgdate1=imddata['MAP_PROJECTED_PRODUCT']['earliestAcqTime'][0:19]#Already in ISO 8601 format, just strip off millisecs
            imgdate2=imddata['MAP_PROJECTED_PRODUCT']['latestAcqTime'][0:19]
            if imgdate1==imgdate2:self.metadata['imgdate']='%s'%(imgdate1)
            else:self.metadata['imgdate']='%s/%s'%(imgdate1,imgdate2)
        elif imddata[imgkey].has_key('firstLineTime'):
            self.metadata['imgdate']=imddata[imgkey]['firstLineTime'][0:19] #Already in ISO 8601 format, just strip off millisecs
        if imddata[imgkey]['satId']=='QB02':
            self.metadata['satellite']='Quickbird (QB02)'
        elif imddata[imgkey]['satId']=='WV01':
            self.metadata['satellite']='Worldview-1 (WV01)'
        elif imddata[imgkey]['satId']=='WV02':
            self.metadata['satellite']='Worldview-2 (WV02)'
        else:
            self.metadata['satellite']=imddata[imgkey]['satId']
        if imddata['bandId'] == 'P':self.metadata['sensor']='PANCHROMATIC'
        else:
            if imddata['panSharpenAlgorithm']== 'None':self.metadata['sensor']='MULTISPECTRAL'
            else:self.metadata['sensor']='MULTI/PAN'
        #if imddata['bandId']=='Multi':
        #    if imddata['nbands'] == 3:self.metadata['bands'] = 'B,G,R'
        #    elif imddata['nbands'] == 4:self.metadata['bands'] = 'B,G,R,N'
        #else: #'BGRN','RGB','P'
        #    self.metadata['bands'] = ','.join([l for l in imddata['bandId']])
        self.metadata['bands'] = ','.join([b.split('_')[1] for b in imddata.keys() if b[0:5]=='BAND_'])
        if imddata[imgkey].has_key('meanSunEl'):
            self.metadata['sunelevation'] = imddata[imgkey]['meanSunEl']
            self.metadata['sunazimuth'] = imddata[imgkey]['meanSunAz']
        elif imddata[imgkey].has_key('sunEl'):
            self.metadata['sunelevation'] = imddata[imgkey]['sunEl']
            self.metadata['sunazimuth'] = imddata[imgkey]['sunAz']
        self.metadata['level'] = imddata['productLevel']
        if imddata[imgkey].has_key('cloudCover'):
            self.metadata['cloudcover'] = imddata[imgkey]['cloudCover']
        elif imddata[imgkey].has_key('manualCloudCover'):
            self.metadata['cloudcover'] = max([0, imddata[imgkey]['manualCloudCover']]) #hack for -999 cloud cover
        elif imddata[imgkey].has_key('autoCloudCover'):
            self.metadata['cloudcover'] = max([0, imddata[imgkey]['autoCloudCover']])
        if imddata[imgkey].has_key('offNadirViewAngle'):
            self.metadata['viewangle'] = imddata[imgkey]['offNadirViewAngle']
        elif imddata[imgkey].has_key('meanOffNadirViewAngle'):
            self.metadata['viewangle'] = imddata[imgkey]['meanOffNadirViewAngle']
        if imddata[imgkey].has_key('CatId'):
            self.metadata['sceneid'] = imddata[imgkey]['CatId']
        if imddata[imgkey].has_key('resamplingKernel'):
            self.metadata['resampling'] = imddata[imgkey]['resamplingKernel']
        elif imddata.has_key('MAP_PROJECTED_PRODUCT') and imddata['MAP_PROJECTED_PRODUCT'].has_key('resamplingKernel'):
            self.metadata['resampling'] = imddata['MAP_PROJECTED_PRODUCT']['resamplingKernel']
        if imddata.has_key('MAP_PROJECTED_PRODUCT') and imddata['MAP_PROJECTED_PRODUCT'].has_key('DEMCorrection'):
            self.metadata['demcorrection'] = imddata['MAP_PROJECTED_PRODUCT']['DEMCorrection']
예제 #14
0
    def __getmetadata__(self):
        '''Read Metadata for an Digital Globe format image as GDAL doesn't quite get it all...

        @todo: Fix QB GDA94 Geographic CS "Unknown datum" problem
        '''
        f = self.fileinfo['filepath']
        imddata = self.__getimddata__(f)

        exts = {
            '.tif': 'GTiff/GeoTIFF',
            '.img': 'HFA/Erdas Imagine Images (.img)',
            '.ntf': 'NITF/National Imagery Transmission Format (.ntf)',
            '.pix': 'PCI Geomatics Database File (.pix)'
        }
        btil, til = utilities.exists(os.path.splitext(f)[0] + '.til', True)
        if btil:
            vrt = self.__gettilevrt__(til, imddata)
            __default__.Dataset.__getmetadata__(self, vrt)
            for tmp in self.filelist:
                for ext in exts:
                    if tmp[-4:].lower() == ext:
                        self.metadata['filetype'] = exts[ext]
                        break
        else:
            img = False
            for ext in exts:
                bext, ext = utilities.exists(
                    os.path.splitext(f)[0] + ext, True)
                if bext:
                    __default__.Dataset.__getmetadata__(self, ext)
                    img = True
                    break

            if not img:
                raise IOError, 'Matching DigitalGlobe imagery file not found:\n'

        self.metadata['metadata'] = open(f).read()

        if imddata.has_key('IMAGE_1'): imgkey = 'IMAGE_1'
        else: imgkey = 'SINGLE_IMAGE_PRODUCT'
        if imddata.has_key('MAP_PROJECTED_PRODUCT'):
            imgdate1 = imddata['MAP_PROJECTED_PRODUCT']['earliestAcqTime'][
                0:19]  #Already in ISO 8601 format, just strip off millisecs
            imgdate2 = imddata['MAP_PROJECTED_PRODUCT']['latestAcqTime'][0:19]
            if imgdate1 == imgdate2:
                self.metadata['imgdate'] = '%s' % (imgdate1)
            else:
                self.metadata['imgdate'] = '%s/%s' % (imgdate1, imgdate2)
        elif imddata[imgkey].has_key('firstLineTime'):
            self.metadata['imgdate'] = imddata[imgkey]['firstLineTime'][
                0:19]  #Already in ISO 8601 format, just strip off millisecs
        if imddata[imgkey]['satId'] == 'QB02':
            self.metadata['satellite'] = 'Quickbird (QB02)'
        elif imddata[imgkey]['satId'] == 'WV01':
            self.metadata['satellite'] = 'Worldview-1 (WV01)'
        elif imddata[imgkey]['satId'] == 'WV02':
            self.metadata['satellite'] = 'Worldview-2 (WV02)'
        else:
            self.metadata['satellite'] = imddata[imgkey]['satId']
        if imddata['bandId'] == 'P': self.metadata['sensor'] = 'PANCHROMATIC'
        else:
            if imddata['panSharpenAlgorithm'] == 'None':
                self.metadata['sensor'] = 'MULTISPECTRAL'
            else:
                self.metadata['sensor'] = 'MULTI/PAN'
        #if imddata['bandId']=='Multi':
        #    if imddata['nbands'] == 3:self.metadata['bands'] = 'B,G,R'
        #    elif imddata['nbands'] == 4:self.metadata['bands'] = 'B,G,R,N'
        #else: #'BGRN','RGB','P'
        #    self.metadata['bands'] = ','.join([l for l in imddata['bandId']])
        self.metadata['bands'] = ','.join(
            [b.split('_')[1] for b in imddata.keys() if b[0:5] == 'BAND_'])
        if imddata[imgkey].has_key('meanSunEl'):
            self.metadata['sunelevation'] = imddata[imgkey]['meanSunEl']
            self.metadata['sunazimuth'] = imddata[imgkey]['meanSunAz']
        elif imddata[imgkey].has_key('sunEl'):
            self.metadata['sunelevation'] = imddata[imgkey]['sunEl']
            self.metadata['sunazimuth'] = imddata[imgkey]['sunAz']
        self.metadata['level'] = imddata['productLevel']
        if imddata[imgkey].has_key('cloudCover'):
            self.metadata['cloudcover'] = imddata[imgkey]['cloudCover']
        elif imddata[imgkey].has_key('manualCloudCover'):
            self.metadata['cloudcover'] = max([
                0, imddata[imgkey]['manualCloudCover']
            ])  #hack for -999 cloud cover
        elif imddata[imgkey].has_key('autoCloudCover'):
            self.metadata['cloudcover'] = max(
                [0, imddata[imgkey]['autoCloudCover']])
        if imddata[imgkey].has_key('offNadirViewAngle'):
            self.metadata['viewangle'] = imddata[imgkey]['offNadirViewAngle']
        elif imddata[imgkey].has_key('meanOffNadirViewAngle'):
            self.metadata['viewangle'] = imddata[imgkey][
                'meanOffNadirViewAngle']
        if imddata[imgkey].has_key('CatId'):
            self.metadata['sceneid'] = imddata[imgkey]['CatId']
        if imddata[imgkey].has_key('resamplingKernel'):
            self.metadata['resampling'] = imddata[imgkey]['resamplingKernel']
        elif imddata.has_key('MAP_PROJECTED_PRODUCT') and imddata[
                'MAP_PROJECTED_PRODUCT'].has_key('resamplingKernel'):
            self.metadata['resampling'] = imddata['MAP_PROJECTED_PRODUCT'][
                'resamplingKernel']
        if imddata.has_key('MAP_PROJECTED_PRODUCT') and imddata[
                'MAP_PROJECTED_PRODUCT'].has_key('DEMCorrection'):
            self.metadata['demcorrection'] = imddata['MAP_PROJECTED_PRODUCT'][
                'DEMCorrection']
예제 #15
0
    def v2(self,f=None):
        dom = self._dom
        self.metadata['sceneid'] = dom.xpath('string(/Dimap_Document/Dataset_Identification/DATASET_NAME)')
        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)')
            ntiles_x=dom.xpath('number(//*/NTILES_COUNT/@ntiles_x)')
            ntiles_y=dom.xpath('number(//*/NTILES_COUNT/@ntiles_y)')
            tile_cols=math.ceil(ncols/ntiles_x)
            last_tile_cols=tile_cols-(ntiles_x*tile_cols-ncols)
            tile_rows=math.ceil(ncols/ntiles_x)
            last_tile_rows=tile_rows-(ntiles_y*tile_row-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

                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))

        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)