2019-01-16 19:40:08 +00:00
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 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
import sys
import os
import math
import logging
import contextlib
from iscesys . Dumpers . XmlDumper import XmlDumper
from iscesys . Component . Configurable import Configurable
from iscesys . ImageApi . DataAccessorPy import DataAccessor
from iscesys . ImageApi import CasterFactory as CF
from iscesys . DictUtils . DictUtils import DictUtils as DU
from isceobj . Util import key_of_same_content
from isceobj . Util . decorators import pickled , logged
from iscesys . Component . Component import Component
import numpy as np
from isceobj . Util . decorators import use_api
# # \namespace ::isce.components.isceobj.Image Base class for Image API
# # This is the default copy list-- it is not a class attribute because the
# # I decided the class wwas too big-- but that's strictly subjective.
ATTRIBUTES = ( ' bands ' , ' scheme ' , ' caster ' , ' width ' , ' filename ' , ' byteOrder ' ,
' dataType ' , ' xmin ' , ' xmax ' , ' numberGoodBytes ' , ' firstLatitude ' ,
' firstLongitude ' , ' deltaLatitude ' , ' deltaLongitude ' )
# # Map various byte order codes to Image's.
ENDIAN = { ' l ' : ' l ' , ' L ' : ' l ' , ' < ' : ' l ' , ' little ' : ' l ' , ' Little ' : ' l ' ,
' b ' : ' b ' , ' B ' : ' b ' , ' > ' : ' b ' , ' big ' : ' b ' , ' Big ' : ' b ' }
# long could be machine dependent
sizeLong = DataAccessor . getTypeSizeS ( ' LONG ' )
TO_NUMPY = { ' BYTE ' : ' i1 ' , ' SHORT ' : ' i2 ' , ' INT ' : ' i4 ' , ' LONG ' : ' i ' + str ( sizeLong ) , ' FLOAT ' : ' f4 ' , ' DOUBLE ' : ' f8 ' ,
' CFLOAT ' : ' c8 ' , ' CDOUBLE ' : ' c16 ' }
BYTE_ORDER = Component . Parameter ( ' byteOrder ' ,
public_name = ' BYTE_ORDER ' ,
default = sys . byteorder [ 0 ] . lower ( ) ,
type = str ,
mandatory = False ,
doc = ' Endianness of the image. ' )
WIDTH = Component . Parameter ( ' width ' ,
public_name = ' WIDTH ' ,
default = None ,
type = int ,
mandatory = False ,
private = True ,
doc = ' Image width ' )
LENGTH = Component . Parameter ( ' length ' ,
public_name = ' LENGTH ' ,
default = None ,
type = int ,
mandatory = False ,
private = True ,
doc = ' Image length ' )
SCHEME = Component . Parameter ( ' scheme ' ,
public_name = ' SCHEME ' ,
default = ' BIP ' ,
type = str ,
mandatory = False ,
doc = ' Interleaving scheme of the image. ' )
CASTER = Component . Parameter ( ' caster ' ,
public_name = ' CASTER ' ,
default = ' ' ,
type = str ,
mandatory = False ,
private = True ,
doc = ' Type of conversion to be performed from input '
+ ' source to output source. Being input or output source will depend on the type of operations performed (read or write) ' )
NUMBER_BANDS = Component . Parameter ( ' bands ' ,
public_name = ' NUMBER_BANDS ' ,
default = 1 ,
type = int ,
mandatory = False ,
doc = ' Number of image bands. ' )
'''
COORD1 = Component . Parameter ( ' coord1 ' ,
public_name = ' COORD1 ' ,
default = None ,
type = int ,
mandatory = True ,
doc = ' Horizontal coordinate. ' )
COORD2 = Component . Parameter ( ' coord2 ' ,
public_name = ' COORD2 ' ,
default = None ,
type = int ,
mandatory = True ,
doc = ' Vertical coordinate. ' )
'''
DATA_TYPE = Component . Parameter ( ' dataType ' ,
public_name = ' DATA_TYPE ' ,
default = ' ' ,
type = str ,
mandatory = True ,
doc = ' Image data type. ' )
IMAGE_TYPE = Component . Parameter ( ' imageType ' ,
public_name = ' IMAGE_TYPE ' ,
default = ' ' ,
type = str ,
mandatory = False ,
private = True ,
doc = ' Image type used for displaying. ' )
FILE_NAME = Component . Parameter ( ' filename ' ,
public_name = ' FILE_NAME ' ,
default = ' ' ,
type = str ,
mandatory = True ,
doc = ' Name of the image file. ' )
EXTRA_FILE_NAME = Component . Parameter ( ' _extraFilename ' ,
public_name = ' EXTRA_FILE_NAME ' ,
default = ' ' ,
type = str ,
private = True ,
mandatory = False ,
doc = ' For example name of vrt metadata. ' )
ACCESS_MODE = Component . Parameter ( ' accessMode ' ,
public_name = ' ACCESS_MODE ' ,
default = ' ' ,
type = str ,
mandatory = True ,
doc = ' Image access mode. ' )
DESCRIPTION = Component . Parameter ( ' description ' ,
public_name = ' DESCRIPTION ' ,
default = ' ' ,
type = str ,
mandatory = False ,
private = True ,
doc = ' Image description ' )
XMIN = Component . Parameter ( ' xmin ' ,
public_name = ' XMIN ' ,
default = None ,
type = float ,
mandatory = False ,
private = True ,
doc = ' Minimum range value ' )
XMAX = Component . Parameter ( ' xmax ' ,
public_name = ' XMAX ' ,
default = None ,
type = float ,
mandatory = False ,
private = True ,
doc = ' Maximum range value ' )
ISCE_VERSION = Component . Parameter ( ' isce_version ' ,
public_name = ' ISCE_VERSION ' ,
default = None ,
type = str ,
mandatory = False ,
private = True ,
doc = ' Information about the isce release version. ' )
COORD1 = Component . Facility (
' coord1 ' ,
public_name = ' Coordinate1 ' ,
module = ' isceobj.Image ' ,
factory = ' createCoordinate ' ,
args = ( ) ,
mandatory = True ,
doc = ' First coordinate of a 2D image (width). '
)
COORD2 = Component . Facility (
' coord2 ' ,
public_name = ' Coordinate2 ' ,
module = ' isceobj.Image ' ,
factory = ' createCoordinate ' ,
args = ( ) ,
mandatory = True ,
doc = ' Second coordinate of a 2D image (length). '
)
@pickled
class Image ( DataAccessor , Configurable ) :
logging_name = ' isce.isceobj.Image.Image '
parameter_list = (
BYTE_ORDER ,
SCHEME ,
CASTER ,
NUMBER_BANDS ,
WIDTH ,
LENGTH ,
DATA_TYPE ,
IMAGE_TYPE ,
FILE_NAME ,
EXTRA_FILE_NAME ,
ACCESS_MODE ,
DESCRIPTION ,
XMIN ,
XMAX ,
ISCE_VERSION
)
facility_list = (
COORD1 ,
COORD2
)
family = ' image '
def __init__ ( self , family = ' ' , name = ' ' ) :
# There is an hack to set the first latitude and longitude (see setters) so coord1 and 2
# need to be defined when calling Configurable.__init__ which will try to call the setters
self . catalog = { }
self . descriptionOfVariables = { }
self . descriptionOfFacilities = { }
self . _dictionaryOfFacilities = { }
self . typeOfVariables = { }
self . unitsOfVariables = { }
self . dictionaryOfOutputVariables = { }
self . dictionaryOfVariables = { }
self . mandatoryVariables = [ ]
self . optionalVariables = [ ]
# since we hacked the with to call coord1 the facilities need to be defined when calling
# Configurable.__init__
self . _facilities ( )
self . updateParameters ( )
DataAccessor . __init__ ( self )
Configurable . __init__ ( self , family if family else self . __class__ . family , name = name )
self . _instanceInit ( )
self . _isFinalized = False
return None
# To facilitate the use of numpy to manipulate isce images
def toNumpyDataType ( self ) :
return TO_NUMPY [ self . dataType . upper ( ) ]
def updateParameters ( self ) :
self . extendParameterList ( Configurable , Image )
super ( Image , self ) . updateParameters ( )
# # New usage is: image.copy_attribute(image', *args), replacing:
# # ImageUtil.ImageUtil.ImageUtil.copyAttributes(image, image', *args)
def copy_attributes ( self , other , * args ) :
for item in args or ATTRIBUTES :
try :
setattr ( other , item , getattr ( self , item ) )
except AttributeError :
pass
return other
# Why reinventing the wheel when there is deepcopy
# # This method makes a new image sub-class object that are copies of
# # existing ones.
def copy ( self , access_mode = None ) :
obj_new = self . copy_attributes ( self . __class__ ( ) )
if access_mode :
obj_new . setAccessMode ( access_mode )
obj_new . createImage ( )
return obj_new
def clone ( self , access_mode = None ) :
import copy
obj_new = copy . deepcopy ( self )
if access_mode :
obj_new . setAccessMode ( access_mode )
return obj_new
# # Call the copy method, as a context manager
@contextlib.contextmanager
def ccopy ( self , access_mode = None ) :
result = self . copy ( access_mode = access_mode )
yield result
result . finalizeImage ( )
pass
# # creates a DataAccessor.DataAccessor instance. If the parameters tagged
# # as mandatory are not set, an exception is thrown.
def createImage ( self ) :
self . createAccessor ( )
da = self . getAccessor ( )
###Intercept for GDAL
if self . methodSelector ( ) != ' api ' :
return None
try :
fsize = os . path . getsize ( self . filename )
except OSError :
print ( " File " , self . filename , " not found " )
raise OSError
size = self . getTypeSize ( )
if ( fsize != self . width * self . length * size * self . bands ) :
print ( " Image.py::createImage():Size on disk and size computed from metadata for file " , \
self . filename , " do not match " )
sys . exit ( 1 )
self . _isFinalized = False
return None
def memMap ( self , mode = ' r ' , band = None ) :
if self . scheme . lower ( ) == ' bil ' :
immap = np . memmap ( self . filename , self . toNumpyDataType ( ) , mode ,
shape = ( self . coord2 . coordSize , self . bands , self . coord1 . coordSize ) )
if band is not None :
immap = immap [ : , band , : ]
elif self . scheme . lower ( ) == ' bip ' :
immap = np . memmap ( self . filename , self . toNumpyDataType ( ) , mode ,
shape = ( self . coord2 . coordSize , self . coord1 . coordSize , self . bands ) )
if band is not None :
immap = immap [ : , : , band ]
elif self . scheme . lower ( ) == ' bsq ' :
immap = np . memmap ( self . filename , self . toNumpyDataType ( ) , mode ,
shape = ( self . bands , self . coord2 . coordSize , self . coord1 . coordSize ) )
if band is not None :
immap = immap [ band , : , : ]
return immap
def asMemMap ( self , filename ) :
if self . scheme . lower ( ) == ' bil ' :
immap = np . memmap ( filename , self . toNumpyDataType ( ) , ' w+ ' ,
shape = ( self . coord2 . coordSize , self . bands , self . coord1 . coordSize ) )
elif self . scheme . lower ( ) == ' bip ' :
immap = np . memmap ( filename , self . toNumpyDataType ( ) , ' w+ ' ,
shape = ( self . coord2 . coordSize , self . coord1 . coordSize , self . bands ) )
elif self . scheme . lower ( ) == ' bsq ' :
immap = np . memmap ( filename , self . toNumpyDataType ( ) , ' w+ ' ,
shape = ( self . bands , self . coord2 . coordSize , self . coord1 . coordSize ) )
return immap
# intercept the dump method and the adaptToRender to make sure the the coor2.coordSize is set.
# the assignment does the trick
@use_api
def dump ( self , filename ) :
self . length = self . length
super ( Image , self ) . dump ( filename )
self . renderVRT ( )
@use_api
def adaptToRender ( self ) :
self . length = self . length
'''
##
# Initialize the image instance from an xml file
def load ( self , filename ) :
from iscesys . Parsers . FileParserFactory import createFileParser
parser = createFileParser ( ' xml ' )
#get the properties from the file
prop , fac , misc = parser . parse ( filename )
self . init ( prop , fac , misc )
'''
@use_api
def renderHdr ( self , outfile = None ) :
from datetime import datetime
from isceobj . XmlUtil import xmlUtils as xml
from isce import release_version , release_svn_revision , release_date , svn_revision
odProp = xml . OrderedDict ( )
odFact = xml . OrderedDict ( )
odMisc = xml . OrderedDict ( )
# hack since the length is normally not set but obtained from the file
# size, before rendering make sure that coord1.size is set to length
self . coord2 . coordSize = self . length
self . renderToDictionary ( self , odProp , odFact , odMisc )
# remove key,value pair with empty value (except if value is zero)
DU . cleanDictionary ( odProp )
DU . cleanDictionary ( odFact )
DU . cleanDictionary ( odMisc )
odProp [ ' ISCE_VERSION ' ] = " Release: %s , svn- %s , %s . Current: svn- %s . " % \
( release_version , release_svn_revision , release_date , svn_revision )
outfile = outfile if outfile else self . getFilename ( ) + ' .xml '
firstTag = ' imageFile '
XD = XmlDumper ( )
XD . dump ( outfile , odProp , odFact , odMisc , firstTag )
self . renderVRT ( )
return None
# This method renders an ENVI HDR file similar to the XML file.
def renderEnviHDR ( self ) :
'''
Renders a bare minimum ENVI HDR file , that can be used to directly ingest the outputs into
a GIS package .
'''
typeMap = { ' BYTE ' : 1 ,
' SHORT ' : 2 ,
' INT ' : 3 ,
' LONG ' : 14 ,
' FLOAT ' : 4 ,
' DOUBLE ' : 5 ,
' CFLOAT ' : 6 ,
' CDOUBLE ' : 9 }
orderMap = { ' L ' : 0 ,
' B ' : 1 }
tempstring = """ ENVI
description = { { Data product generated using ISCE } }
samples = { 0 }
lines = { 1 }
bands = { 2 }
header offset = 0
file type = ENVI Standard
data type = { 3 }
interleave = { 4 }
byte order = { 5 }
"""
map_infostr = """ coordinate system string = {{ GEOGCS[ " GCS_WGS_1984 " ,DATUM[ " D_WGS_1984 " ,SPHEROID[ " WGS_1984 " ,6378137, 298.257223563]],PRIMEM[ " Greenwich " ,0],UNIT[ " Degree " ,0.0174532925199433]]}}
map_info = { { Geographic Lat / Lon , 1.0 , 1.0 , { 0 } , { 1 } , { 2 } , { 3 } , WGS - 84 , units = Degrees } } """
flag = False
try :
if ( self . coord1 . coordStart == 0. ) and \
( self . coord2 . coordStart == 0. ) and \
( self . coord1 . coordDelta == 1. ) and \
( self . coord2 . coordDelta == 1. ) :
flag = True
except :
pass
outfile = self . getFilename ( ) + ' .hdr '
outstr = tempstring . format ( self . width , self . length ,
self . bands , typeMap [ self . dataType . upper ( ) ] ,
self . scheme . lower ( ) ,
orderMap [ ENDIAN [ self . byteOrder ] . upper ( ) ] )
if not flag :
outstr + = map_infostr . format ( self . coord1 . coordStart ,
self . coord2 . coordStart ,
self . coord1 . coordDelta ,
- self . coord2 . coordDelta )
with open ( outfile , ' w ' ) as f :
f . write ( outstr )
return
# This method renders and ENVI HDR file similar to the XML file.
def renderVRT ( self , outfile = None ) :
'''
Renders a bare minimum ENVI HDR file , that can be used to directly ingest the outputs into a GIS package .
'''
import xml . etree . ElementTree as ET
typeMap = { ' BYTE ' : ' Byte ' ,
' SHORT ' : ' Int16 ' ,
' CIQBYTE ' : ' Int16 ' ,
' INT ' : ' Int32 ' ,
' FLOAT ' : ' Float32 ' ,
' DOUBLE ' : ' Float64 ' ,
' CFLOAT ' : ' CFloat32 ' ,
' CDOUBLE ' : ' CFloat64 ' }
sizeMap = { ' BYTE ' : 1 ,
' SHORT ' : 2 ,
' CIQBYTE ' : 2 ,
' INT ' : 4 ,
' FLOAT ' : 4 ,
' DOUBLE ' : 8 ,
' CFLOAT ' : 8 ,
' CDOUBLE ' : 16 }
orderMap = { ' L ' : ' LSB ' ,
' B ' : ' MSB ' }
def indentXML ( elem , depth = None , last = None ) :
if depth == None :
depth = [ 0 ]
if last == None :
last = False
tab = ' ' * 4
if ( len ( elem ) ) :
depth [ 0 ] + = 1
elem . text = ' \n ' + ( depth [ 0 ] ) * tab
lenEl = len ( elem )
lastCp = False
for i in range ( lenEl ) :
if ( i == lenEl - 1 ) :
lastCp = True
indentXML ( elem [ i ] , depth , lastCp )
if ( not last ) :
elem . tail = ' \n ' + ( depth [ 0 ] ) * tab
else :
depth [ 0 ] - = 1
elem . tail = ' \n ' + ( depth [ 0 ] ) * tab
else :
if ( not last ) :
elem . tail = ' \n ' + ( depth [ 0 ] ) * tab
else :
depth [ 0 ] - = 1
elem . tail = ' \n ' + ( depth [ 0 ] ) * tab
return
srs = " EPSG:4326 "
flag = False
try :
if ( self . coord1 . coordStart == 0. ) and \
( self . coord2 . coordStart == 0. ) and \
( self . coord1 . coordDelta == 1. ) and \
( self . coord2 . coordDelta == 1. ) :
flag = True
except :
pass
if not outfile :
outfile = self . getFilename ( ) + ' .vrt '
root = ET . Element ( ' VRTDataset ' )
root . attrib [ ' rasterXSize ' ] = str ( self . width )
root . attrib [ ' rasterYSize ' ] = str ( self . length )
if not flag :
print ( ' Writing geotrans to VRT for {0} ' . format ( self . filename ) )
ET . SubElement ( root , ' SRS ' ) . text = " EPSG:4326 "
gtstr = " {0} , {1} , 0.0, {2} , 0.0, {3} " . format ( self . coord1 . coordStart ,
self . coord1 . coordDelta ,
self . coord2 . coordStart ,
self . coord2 . coordDelta )
ET . SubElement ( root , ' GeoTransform ' ) . text = gtstr
nbytes = sizeMap [ self . dataType . upper ( ) ]
for band in range ( self . bands ) :
broot = ET . Element ( ' VRTRasterBand ' )
broot . attrib [ ' dataType ' ] = typeMap [ self . dataType . upper ( ) ]
broot . attrib [ ' band ' ] = str ( band + 1 )
broot . attrib [ ' subClass ' ] = " VRTRawRasterBand "
elem = ET . SubElement ( broot , ' SourceFilename ' )
elem . attrib [ ' relativeToVRT ' ] = " 1 "
elem . text = os . path . basename ( self . getFilename ( ) )
ET . SubElement ( broot , ' ByteOrder ' ) . text = orderMap [ ENDIAN [ self . byteOrder ] . upper ( ) ]
if self . scheme . upper ( ) == ' BIL ' :
ET . SubElement ( broot , ' ImageOffset ' ) . text = str ( band * self . width * nbytes )
ET . SubElement ( broot , ' PixelOffset ' ) . text = str ( nbytes )
ET . SubElement ( broot , ' LineOffset ' ) . text = str ( self . bands * self . width * nbytes )
elif self . scheme . upper ( ) == ' BIP ' :
ET . SubElement ( broot , ' ImageOffset ' ) . text = str ( band * nbytes )
ET . SubElement ( broot , ' PixelOffset ' ) . text = str ( self . bands * nbytes )
ET . SubElement ( broot , ' LineOffset ' ) . text = str ( self . bands * self . width * nbytes )
elif self . scheme . upper ( ) == ' BSQ ' :
ET . SubElement ( broot , ' ImageOffset ' ) . text = str ( band * self . width * self . length * nbytes )
ET . SubElement ( broot , ' PixelOffset ' ) . text = str ( nbytes )
ET . SubElement ( broot , ' LineOffset ' ) . text = str ( self . width * nbytes )
root . append ( broot )
indentXML ( root )
tree = ET . ElementTree ( root )
tree . write ( outfile , encoding = ' unicode ' )
return
# #
# This method initialize the Image.
# @param filename \c string the file name associated with the image.
# @param accessmode \c string access mode of the file.
# @param bands \c int number of bands of the interleaving scheme.
# @param type \c string data type used to store the data.
# @param width \c int width of the image.
# @param scheme \c string interleaving scheme.
# @param caster \c string type of caster (ex. 'DoubleToFloat').
def initImage ( self , filename , accessmode , width ,
type = None , bands = None , scheme = None , caster = None ) :
self . initAccessor ( filename , accessmode , width , type , bands , scheme , caster )
# # This method gets the pointer associated to the DataAccessor.DataAccessor
# # object created.
# @return \c pointer pointer to the underlying DataAccessor.DataAccessor
# # object.
def getImagePointer ( self ) :
return self . getAccessor ( )
# # gets the string describing the image for the user
# #@return \c text description string describing the image in English for
# # the user
def getDescription ( self ) :
return self . description
# # This method appends the string describing the image for the user create
# # a list.
# #@param doc \c text description string describing the image in English for
# # the user
def addDescription ( self , doc ) :
if self . description == ' ' :
self . description = [ doc ]
elif isinstance ( self . description , list ) :
self . description . append ( doc )
# # This method gets the length associated to the DataAccessor.DataAccessor
# # object created.
# # @return \c int length of the underlying DataAccessor.DataAccessor object.
@use_api
def getLength ( self ) :
if not self . coord2 . coordSize :
self . coord2 . coordSize = self . getFileLength ( )
return self . coord2 . coordSize
# Always call this function if createImage() was previously invoked.
# It deletes the pointer to the object, closes the file associated with
# the object, frees memory.
def finalizeImage ( self ) :
if not self . _isFinalized :
self . finalizeAccessor ( )
self . _isFinalized = True
def setImageType ( self , val ) :
self . imageType = str ( val )
def setLength ( self , val ) :
# needed because the __init__ calls self.lenth = None which calls this
# function and the casting would fail. with time possibly need to
# refactor all the image API with better inheritance
if val is not None :
self . coord2 . coordSize = int ( val )
def getWidth ( self ) :
return self . coord1 . coordSize
def setWidth ( self , val ) :
# see getLength
if val is not None :
width = int ( val )
self . coord1 . coordSize = width
# self.width = width
# DataAccessor.setWidth(self, width)
def setXmin ( self , val ) :
# see getLength
if not val is None :
xmin = val
self . coord1 . coordStart = xmin
def getXmin ( self ) :
return self . coord1 . coordStart
def setXmax ( self , val ) :
# see getLength
if not val is None :
xmax = val
self . coord1 . coordEnd = xmax
def getXmax ( self ) :
return self . coord1 . coordEnd
def setByteOrder ( self , byteOrder ) :
try :
b0 = ENDIAN [ byteOrder ]
except KeyError :
self . logger . error (
self . __class__ . __name__ +
" .setByteOorder got a bad argument: " +
str ( byteOrder )
)
raise ValueError ( str ( byteOrder ) +
" is not a valid byte ordering, e.g. \n " +
str ( ENDIAN . keys ( ) ) )
self . byteOrder = b0
return None
# # Set the caster type if needed
# @param accessMode \c string access mode of the file. Can be 'read' or 'write'
# @param dataType \c string is the dataType from or to the caster writes or reads.
def setCaster ( self , accessMode , dataType ) :
self . accessMode = accessMode
if ( accessMode == ' read ' ) :
self . caster = CF . getCaster ( self . dataType , dataType )
elif ( accessMode == ' write ' ) :
self . caster = CF . getCaster ( dataType , self . dataType )
else :
print ( ' Unrecorgnized access mode ' , accessMode )
raise ValueError
@property
def extraFilename ( self ) :
return self . _extraFilename
@extraFilename.setter
def extraFilename ( self , val ) :
self . _extraFilename = val
def setFirstLatitude ( self , val ) :
self . coord2 . coordStart = val
def setFirstLongitude ( self , val ) :
self . coord1 . coordStart = val
def setDeltaLatitude ( self , val ) :
self . coord2 . coordDelta = val
def setDeltaLongitude ( self , val ) :
self . coord1 . coordDelta = val
def getFirstLatitude ( self ) :
return self . coord2 . coordStart
def getFirstLongitude ( self ) :
return self . coord1 . coordStart
def getDeltaLatitude ( self ) :
return self . coord2 . coordDelta
def getDeltaLongitude ( self ) :
return self . coord1 . coordDelta
def getImageType ( self ) :
return self . imageType
def getByteOrder ( self ) :
return self . byteOrder
def getProduct ( self ) :
return self . product
def setProduct ( self , val ) :
self . product = val
'''
def _facilities ( self ) :
self . coord1 = self . facility ( ' coord1 ' , public_name = ' Coordinate1 ' , module = ' isceobj.Image ' , factory = ' createCoordinate ' , mandatory = True , doc = ' First coordinate of a 2D image (witdh). ' )
self . coord2 = self . facility ( ' coord2 ' , public_name = ' Coordinate2 ' , module = ' isceobj.Image ' , factory = ' createCoordinate ' , mandatory = True , doc = ' Second coordinate of a 2D image (length). ' )
'''
firstLatitude = property ( getFirstLatitude , setFirstLatitude )
firstLongitude = property ( getFirstLongitude , setFirstLongitude )
deltaLatitude = property ( getDeltaLatitude , setDeltaLatitude )
deltaLongitude = property ( getDeltaLongitude , setDeltaLongitude )
width = property ( getWidth , setWidth )
length = property ( getLength , setLength )
xmin = property ( getXmin , setXmin )
xmax = property ( getXmax , setXmax )
pass
class ImageCoordinate ( Configurable ) :
family = ' imagecoordinate '
def __init__ ( self , family = ' ' , name = ' ' ) :
# # Call super with class name
Configurable . __init__ ( self , family if family else self . __class__ . family , name = name )
self . coordDescription = ' '
self . _parameters ( )
return None
@property
def coordStart ( self ) :
return self . _coordStart
@coordStart.setter
def coordStart ( self , val ) :
self . _coordStart = val
@property
def coordEnd ( self ) :
if self . _coordEnd is None and self . _coordSize is not None :
self . _coordEnd = self . _coordStart + self . _coordSize * self . _coordDelta
return self . _coordEnd
@coordEnd.setter
def coordEnd ( self , val ) :
self . _coordEnd = val
@property
def coordSize ( self ) :
return self . _coordSize
@coordSize.setter
def coordSize ( self , val ) :
self . _coordSize = val
@property
def coordDelta ( self ) :
return self . _coordDelta
@coordDelta.setter
def coordDelta ( self , val ) :
self . _coordDelta = val
def _parameters ( self ) :
self . _coordStart = self . parameter ( ' coordStart ' , public_name = ' startingValue ' , default = 0 , units = ' ' ,
type = float , mandatory = False ,
doc = " Starting value of the coordinate. " )
self . _coordEnd = self . parameter ( ' coordEnd ' , public_name = ' endingValue ' , default = None , units = ' ' ,
type = float , mandatory = False ,
2019-03-04 19:03:45 +00:00
doc = " Ending value of the coordinate. " )
2019-01-16 19:40:08 +00:00
self . _coordDelta = self . parameter ( ' coordDelta ' , public_name = ' delta ' , default = 1 , units = ' ' ,
type = float , mandatory = False ,
doc = " Coordinate quantization. " )
self . _coordSize = self . parameter ( ' coordSize ' , public_name = ' size ' , default = None ,
type = int ,
mandatory = False ,
private = True ,
doc = " Coordinate size. " )
pass