263 lines
9.1 KiB
Python
263 lines
9.1 KiB
Python
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
#
|
||
|
# United States Government Sponsorship acknowledged. This software is subject to
|
||
|
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
|
||
|
# (No [Export] License Required except when exporting to an embargoed country,
|
||
|
# end user, or in support of a prohibited end use). By downloading this software,
|
||
|
# the user agrees to comply with all applicable U.S. export laws and regulations.
|
||
|
# The user has the responsibility to obtain export licenses, or other export
|
||
|
# authority as may be required before exporting this software to any 'EAR99'
|
||
|
# embargoed foreign country or citizen of those countries.
|
||
|
#
|
||
|
# Author: Giangi Sacco
|
||
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
|
||
|
|
||
|
from __future__ import print_function
|
||
|
from iscesys.ImageApi import DataAccessor as DA
|
||
|
import os
|
||
|
## If you finalize more than once, do you get an error?
|
||
|
ERROR_CHECK_FINALIZE = False
|
||
|
|
||
|
class DataAccessor(object):
|
||
|
_accessorType = ''
|
||
|
|
||
|
@staticmethod
|
||
|
def getTypeSizeS(type_):
|
||
|
return DA.getTypeSize(type_)
|
||
|
def __init__(self):
|
||
|
self._accessor = None
|
||
|
self._factory = None
|
||
|
self.scheme = ''
|
||
|
self.caster = ''
|
||
|
self.width = None
|
||
|
self.bands = None
|
||
|
self.length = None
|
||
|
self.accessMode = ''
|
||
|
self.filename = ''
|
||
|
self.dataType = ''
|
||
|
self._size = None
|
||
|
#instead of creating a new function for each type of Accessor to be created
|
||
|
#in the c bindings, pass a dictionary which contains the key 'type' to know the accessor that
|
||
|
#needs to be instanciated
|
||
|
self._extraInfo = {}
|
||
|
self._extra_reader = 'vrt'
|
||
|
return None
|
||
|
|
||
|
## Experimental
|
||
|
def __int__(self):
|
||
|
return self.getAccessor()
|
||
|
|
||
|
def initAccessor(self, filename, filemode, width,
|
||
|
type=None, bands=None, scheme=None, caster=None):
|
||
|
self.filename = filename
|
||
|
self.accessMode = filemode
|
||
|
self.width = int(width)
|
||
|
if type:
|
||
|
self.dataType = type
|
||
|
if bands:
|
||
|
self.bands = int(bands)
|
||
|
if scheme:
|
||
|
self.scheme = scheme
|
||
|
if caster:
|
||
|
self.caster = caster
|
||
|
return None
|
||
|
def getGDALDataTypeId(self,type_):
|
||
|
#from GDALDataType enum
|
||
|
map = {'byte':1,'ciqbyte':1,'short':3,'int':4,'float':6,'double':7,
|
||
|
'cshort':8,'cint':9,'cfloat':10,'cdouble':11}
|
||
|
try:
|
||
|
return map[type_.lower()]
|
||
|
except:
|
||
|
print('Unsupported datatype',type_)
|
||
|
raise Exception
|
||
|
|
||
|
def checkLocation(self):
|
||
|
from iscesys.Parsers.FileParserFactory import createFileParser
|
||
|
parser = createFileParser('xml')
|
||
|
#get the properties from the file
|
||
|
prop, fac, misc = parser.parse(self.metadatalocation)
|
||
|
#first check if it exists as it is
|
||
|
filename = ''
|
||
|
|
||
|
if not (os.path.exists(prop['file_name'])):
|
||
|
name = os.path.basename(prop['file_name'])
|
||
|
#check the path relative to the xml file
|
||
|
filename = os.path.join(os.path.split(self.metadatalocation)[0],name)
|
||
|
#check if relative to cwd
|
||
|
if not (os.path.exists(filename)):
|
||
|
filename = os.path.join(os.getcwd(),name)
|
||
|
if not (os.path.exists(filename)):
|
||
|
filename = ''
|
||
|
else:
|
||
|
filename = prop['file_name']
|
||
|
if not filename:
|
||
|
paths = self.uniquePath([os.path.split(prop['file_name'])[0],os.path.split(self.metadatalocation)[0],
|
||
|
os.getcwd()])
|
||
|
toptr = '\n'.join(paths)
|
||
|
print('The image file',name,'specified in the metadata file',self.metadatalocation,
|
||
|
'cannot be found in', 'any of the following default locations:' if len(paths) > 1 else 'in the following location:' ,
|
||
|
toptr)
|
||
|
raise Exception
|
||
|
|
||
|
return filename
|
||
|
def uniquePath(self,paths):
|
||
|
ret = []
|
||
|
for pth in paths:
|
||
|
if not pth in ret:
|
||
|
ret.append(pth)
|
||
|
return ret
|
||
|
|
||
|
def methodSelector(self):
|
||
|
selection = ''
|
||
|
if self._accessorType.lower() == 'api':
|
||
|
selection = 'api'
|
||
|
elif self._accessorType.lower() == self._extra_reader:
|
||
|
selection = self._extra_reader
|
||
|
elif self.accessMode.lower() == 'write':
|
||
|
selection='api'
|
||
|
elif self.accessMode.lower() == 'read':
|
||
|
selection = self._extra_reader
|
||
|
|
||
|
return selection
|
||
|
|
||
|
def createAccessor(self):
|
||
|
if(not self.filename and hasattr(self,'metadatalocation') and self.metadatalocation and not self.accessMode.lower().count('write')):
|
||
|
#it will only keep going if all ok
|
||
|
self.filename = self.checkLocation()
|
||
|
caster = '' or self.caster
|
||
|
filename = self.filename
|
||
|
scheme = self.scheme
|
||
|
self.extraFilename = self.filename + '.' + self._extra_reader
|
||
|
|
||
|
if self._accessor is None:#to avoid creating duplicates
|
||
|
selection = self.methodSelector()
|
||
|
if selection == 'api':
|
||
|
size = DA.getTypeSize(self.dataType)
|
||
|
#to optimize bip access per band we read in memory all bands and then
|
||
|
#set the right band and write the content back leaving the other bands untouched
|
||
|
#this requires a read and write which only works if the file is opened in
|
||
|
#writeread (or readwrite) mode and not just write
|
||
|
if(self.accessMode.lower() == 'write'):
|
||
|
#if(self.scheme.lower() == 'bip' and self.accessMode.lower() == 'write'):
|
||
|
self.accessMode = 'writeread'
|
||
|
elif selection == self._extra_reader:
|
||
|
size = self.getGDALDataTypeId(self.dataType)
|
||
|
filename = self._extraFilename
|
||
|
#GDALAccessor handles all the different scheme in the same way since it reads
|
||
|
#always in BSQ scheme regardless of the under laying scheme
|
||
|
scheme = 'GDAL'
|
||
|
else:
|
||
|
print('Cannot select appropruiate image API')
|
||
|
raise Exception
|
||
|
self._accessor, self._factory = DA.createAccessor(
|
||
|
filename, self.accessMode, size, self.bands,
|
||
|
self.width,scheme,caster,self._extraInfo
|
||
|
)
|
||
|
return None
|
||
|
|
||
|
def finalizeAccessor(self):
|
||
|
try:
|
||
|
DA.finalizeAccessor(self._accessor, self._factory)
|
||
|
except TypeError:
|
||
|
message = "Image %s is already finalized" % str(self)
|
||
|
if ERROR_CHECK_FINALIZE:
|
||
|
raise RuntimeError(message)
|
||
|
else:
|
||
|
print(message)
|
||
|
|
||
|
self._accessor = None
|
||
|
self._factory = None
|
||
|
return None
|
||
|
|
||
|
def getTypeSize(self):
|
||
|
return DA.getTypeSize(self.dataType)
|
||
|
def rewind(self):
|
||
|
DA.rewind(self._accessor)
|
||
|
|
||
|
def createFile(self, lines):
|
||
|
DA.createFile(self._accessor, lines)
|
||
|
|
||
|
def getFileLength(self):
|
||
|
openedHere = False
|
||
|
|
||
|
if self._accessor is None:
|
||
|
openedHere = True
|
||
|
self.initAccessor(self.filename, 'read', int(self.width),
|
||
|
self.dataType, int(self.bands), self.scheme)
|
||
|
self.createAccessor()
|
||
|
length = DA.getFileLength(self._accessor)
|
||
|
|
||
|
if openedHere:
|
||
|
self.finalizeAccessor()
|
||
|
|
||
|
return length
|
||
|
|
||
|
def getAccessor(self):
|
||
|
return self._accessor
|
||
|
|
||
|
def getFilename(self):
|
||
|
return self.filename
|
||
|
|
||
|
def getAccessMode(self):
|
||
|
return self.accessMode
|
||
|
|
||
|
def getSize(self):
|
||
|
return self.size
|
||
|
|
||
|
def getBands(self):
|
||
|
return self.bands
|
||
|
|
||
|
## Get the width associated to the DataAccessor.DataAccessor object created.
|
||
|
#@return \c int width of the DataAccessor.DataAccessor object.
|
||
|
def getWidth(self):
|
||
|
return self.width
|
||
|
|
||
|
def getInterleavedScheme(self):
|
||
|
return self.scheme
|
||
|
|
||
|
def getCaster(self):
|
||
|
return self.caster
|
||
|
|
||
|
def getDataType(self):
|
||
|
return self.dataType
|
||
|
|
||
|
def setFilename(self, val):
|
||
|
self.filename = str(val)
|
||
|
|
||
|
def setAccessMode(self, val):
|
||
|
self.accessMode = str(val)
|
||
|
|
||
|
def setBands(self, val):
|
||
|
self.bands = int(val)
|
||
|
|
||
|
def setWidth(self, val):
|
||
|
self.width = int(val)
|
||
|
|
||
|
def setInterleavedScheme(self, val):
|
||
|
self.scheme = str(val)
|
||
|
|
||
|
def setCaster(self, val):
|
||
|
self.caster = val
|
||
|
|
||
|
def setDataType(self, val):
|
||
|
self.dataType = val
|
||
|
|
||
|
def setExtraInfo(self,ei):
|
||
|
self._extraInfo = ei
|
||
|
pass
|