Exemplo n.º 1
0
class DiscrertizeFields(ArcTool):
    """
    

    """

    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        DiscrertizeFields.id = DiscrertizeFields.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, DiscrertizeFields.id)

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), debugging=True)

        self.log.debug(msgInitStart)
        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension("spatial")
        except LicenseError, e:
            self.log.error(e)
            return 1

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 2
0
    def __init__(self, parameters, service, *args, **kwargs):
        """Constructor initializes the Geoprocessor using
		:mod:`arcgisscripting` and loops thorugh all the available parameters
		in the Geoprocessor. Will raise an exception if problems occur with the
		Geoprocessor. Parameters are intended to be used in subclasses.
		
		Parameters:
		parameters - parameters object holding parameter information
		
		"""
        Tool.__init__(self, parameters)

        self._backend = 'arcgis'

        # TODO: handle the ArcGIS versions correctly
        try:

            # Inialize the logger for this tool. Logging system must be set up
            # before doing thishis
            self.logger = ArcLogger("Zupport.ArcTool", debugging=True)
            self.logger.debug('[%s] Acquiring geoprocessor' % service)
            self.gp = get_geoprocessor(10)
            # Set the scratch workspace explicitly to ESRI default
            self.gp.ScratchWorkspace = os.path.join(os.path.expanduser('~'),
                                                    'AppData', 'Local', 'Temp')

        except ImportError, e:
            self.logger.error('ArcGIS not present in the system.')
            sys.exit(1)
Exemplo n.º 3
0
class DiscrertizeFields(ArcTool):
    """
    

    """
    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        DiscrertizeFields.id = DiscrertizeFields.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, DiscrertizeFields.id)

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        self.log.debug(msgInitStart)
        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 4
0
class CrossSelect(ArcTool):
    
    implements(IGISTool)
    
    """ ArcTool for batch selecting pixels from rasters in workspace based on 
    a single raster.
    
    Tool works on a set of rasters in a workspace and uses a reference raster's
    unique values to select pixels from target rasters. For example, if 
    reference raster would represent land use classes [1, 2, 3] and rasters A
    and B would have continuous values ArcCrossSelect would create 6 new rasters
    -> 1 / land use class / value raster.

    (0) Reference raster [refraster] - String representing reference raster 
                                       based on which the selection will be 
                                       made (required)
    (1) Input workspace [inworkspace] - String representing the source 
                                         workspace that contains value rasters
                                         (required)
    (2) Output workspace [outworkspace] - String for the location of the 
                                          resulting rasters (required)
    (3) Include values [include] - List holding values in the reference raster
                                   to include (optional, default: None)
    (4) Exclude values [exclude] - List holding values in the reference raster
                                   to exclude (optional, default: None)
    (5) Raster format [raster_type] - String for the output raster format
                                     (optional, default: "img")
    (6) Output name tag [tag] - String to tag the the output names. Will be 
                                placed between the raster name body and value 
                                identifier. tag = kp -> A_kp1.img
    """

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        CrossSelect.id = CrossSelect.id + 1
        self.id = CrossSelect.id
        self.name = self.__module__.split('.')[-1]
        
        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
                                             debugging=True)

        self.log.debug(msgInitStart)

        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1
        
        self.service = service
        
        self.log.debug(msgInitSuccess)
Exemplo n.º 5
0
class CrossSelect(ArcTool):

    implements(IGISTool)

    """ ArcTool for batch selecting pixels from rasters in workspace based on
    a single raster.

    Tool works on a set of rasters in a workspace and uses a reference raster's
    unique values to select pixels from target rasters. For example, if
    reference raster would represent land use classes [1, 2, 3] and rasters A
    and B would have continuous values ArcCrossSelect would create 6 new rasters
    -> 1 / land use class / value raster.

    (0) Reference raster [refraster] - String representing reference raster
                                       based on which the selection will be
                                       made (required)
    (1) Input workspace [inworkspace] - String representing the source
                                         workspace that contains value rasters
                                         (required)
    (2) Output workspace [outworkspace] - String for the location of the
                                          resulting rasters (required)
    (3) Include values [include] - List holding values in the reference raster
                                   to include (optional, default: None)
    (4) Exclude values [exclude] - List holding values in the reference raster
                                   to exclude (optional, default: None)
    (5) Raster format [raster_type] - String for the output raster format
                                     (optional, default: "img")
    (6) Output name tag [tag] - String to tag the the output names. Will be
                                placed between the raster name body and value
                                identifier. tag = kp -> A_kp1.img
    """

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        CrossSelect.id = CrossSelect.id + 1
        self.id = CrossSelect.id
        self.name = self.__module__.split('.')[-1]

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        self.log.debug(msgInitStart)

        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 6
0
Arquivo: core.py Projeto: cbig/zupport
class ArcTool(Tool):
	
	"""
	Class to represent a generic ArcGIS scripting tool.

	This class is intended mostly to be subclassed and provides methods for
	getting the input parameters for the Geoprocessor (GP). ArcGIS must be
	present in the system. Class should not be instantiated, but instead used as
	a super class. Class and its derivatives have three user cases:

	1. Subclasses are instantiated *from within ArcGIS* (Toolbox): the
	GP will get all the provided parameters and it is up to the
	subclasses to handle them correctly.

	2. Subclasses are instantiated *directly from command line*: the
	GP will get all the provided parameters and it is up to the
	subclasses to handle them correctly.

	3. Subclasses are instantiated *from elsewhere in code*: the parameters
	provided by the Geoprocessor will not be what expected.

	Setting the workspace is the responsibility of subclasses.
	"""

	def __init__(self, parameters, service, *args, **kwargs):
		"""Constructor initializes the Geoprocessor using
		:mod:`arcgisscripting` and loops thorugh all the available parameters
		in the Geoprocessor. Will raise an exception if problems occur with the
		Geoprocessor. Parameters are intended to be used in subclasses.
		
		Parameters:
		parameters - parameters object holding parameter information
		
		"""
		Tool.__init__(self, parameters)
		
		self._backend = 'arcgis'
		
		# TODO: handle the ArcGIS versions correctly
		try:
		
			# Inialize the logger for this tool. Logging system must be set up
			# before doing thishis
			self.logger = ArcLogger("Zupport.ArcTool", debugging=True)
			self.logger.debug('[%s] Acquiring geoprocessor' % service)
			self.gp = get_geoprocessor(10)
			# Set the scratch workspace explicitly to ESRI default
			self.gp.ScratchWorkspace = os.path.join(os.path.expanduser('~'), 
														'AppData', 'Local', 
														'Temp')
		
		except ImportError, e:
			self.logger.error('ArcGIS not present in the system.')
			sys.exit(1)
		except:
Exemplo n.º 7
0
class ArcTool(Tool):
    """
	Class to represent a generic ArcGIS scripting tool.

	This class is intended mostly to be subclassed and provides methods for
	getting the input parameters for the Geoprocessor (GP). ArcGIS must be
	present in the system. Class should not be instantiated, but instead used as
	a super class. Class and its derivatives have three user cases:

	1. Subclasses are instantiated *from within ArcGIS* (Toolbox): the
	GP will get all the provided parameters and it is up to the
	subclasses to handle them correctly.

	2. Subclasses are instantiated *directly from command line*: the
	GP will get all the provided parameters and it is up to the
	subclasses to handle them correctly.

	3. Subclasses are instantiated *from elsewhere in code*: the parameters
	provided by the Geoprocessor will not be what expected.

	Setting the workspace is the responsibility of subclasses.
	"""
    def __init__(self, parameters, service, *args, **kwargs):
        """Constructor initializes the Geoprocessor using
		:mod:`arcgisscripting` and loops thorugh all the available parameters
		in the Geoprocessor. Will raise an exception if problems occur with the
		Geoprocessor. Parameters are intended to be used in subclasses.
		
		Parameters:
		parameters - parameters object holding parameter information
		
		"""
        Tool.__init__(self, parameters)

        self._backend = 'arcgis'

        # TODO: handle the ArcGIS versions correctly
        try:

            # Inialize the logger for this tool. Logging system must be set up
            # before doing thishis
            self.logger = ArcLogger("Zupport.ArcTool", debugging=True)
            self.logger.debug('[%s] Acquiring geoprocessor' % service)
            self.gp = get_geoprocessor(10)
            # Set the scratch workspace explicitly to ESRI default
            self.gp.ScratchWorkspace = os.path.join(os.path.expanduser('~'),
                                                    'AppData', 'Local', 'Temp')

        except ImportError, e:
            self.logger.error('ArcGIS not present in the system.')
            sys.exit(1)
        except:
Exemplo n.º 8
0
    def __init__(self, parameters, service, *args, **kwargs):
        ArcRasterTool.__init__(self, parameters, service, *args, **kwargs)

        CalculateRasterGroup.id = CalculateRasterGroup.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, CalculateRasterGroup.id)

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 9
0
Arquivo: core.py Projeto: cbig/zupport
	def __init__(self, parameters, service, *args, **kwargs):
		"""Constructor initializes the Geoprocessor using
		:mod:`arcgisscripting` and loops thorugh all the available parameters
		in the Geoprocessor. Will raise an exception if problems occur with the
		Geoprocessor. Parameters are intended to be used in subclasses.
		
		Parameters:
		parameters - parameters object holding parameter information
		
		"""
		Tool.__init__(self, parameters)
		
		self._backend = 'arcgis'
		
		# TODO: handle the ArcGIS versions correctly
		try:
		
			# Inialize the logger for this tool. Logging system must be set up
			# before doing thishis
			self.logger = ArcLogger("Zupport.ArcTool", debugging=True)
			self.logger.debug('[%s] Acquiring geoprocessor' % service)
			self.gp = get_geoprocessor(10)
			# Set the scratch workspace explicitly to ESRI default
			self.gp.ScratchWorkspace = os.path.join(os.path.expanduser('~'), 
														'AppData', 'Local', 
														'Temp')
		
		except ImportError, e:
			self.logger.error('ArcGIS not present in the system.')
			sys.exit(1)
Exemplo n.º 10
0
    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        MultiConvertRaster.id = MultiConvertRaster.id + 1
        self.id = MultiConvertRaster.id
        self.name = self.__module__.split('.')[-1]

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1
Exemplo n.º 11
0
	def __init__(self, parameters, service,  *args, **kwargs):
		ArcRasterTool.__init__(self, parameters, service, *args, **kwargs)

		CalculateRasterGroup.id = CalculateRasterGroup.id + 1
		self.name = self.__class__.__name__
		# Identifier is a combination of the name and the class counter
		self.id = (self.name, CalculateRasterGroup.id)

		self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
                                             debugging=True)

		self.service = service

		self.log.debug(msgInitSuccess)
Exemplo n.º 12
0
	def __init__(self, parameters, service, *args, **kwargs):
		ArcTool.__init__(self, parameters, service, *args, **kwargs)

		MultiConvertRaster.id = MultiConvertRaster.id + 1
		self.id = MultiConvertRaster.id
		self.name = self.__module__.split('.')[-1]
		
		self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
											 debugging=True)
		

		# Tool needs spatial analyst in order to run
		# TODO: this should be moved to ToolValidator
		try:
			self.register_extension('spatial')
		except LicenseError, e:
			self.log.error(e)
			return 1
Exemplo n.º 13
0
    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        Aggregate.id = Aggregate.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, Aggregate.id)
        
        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
                                             debugging=True)
        
        self.log.debug(msgInitStart)
        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1
Exemplo n.º 14
0
class Aggregate(ArcTool):
    """ ArcTool for aggregating data to desired resolution while preserving 
    true NoData values.
    
    Tool will create new subfolders into the output workspace according to 
    target resolution if they do not exist.

    Parameters:
    
    (1) Input raster [inraster] 
    
        String representing the source workspace that contains rasters to be
        aggregated (required)
          
    (2) Output raster [outraster] 
        
        String for the location of the resulting rasters (required)
    
    (3) Cell factor [factors] 
        
        Integer cell factor (multiplier) to be used in the aggregation. 
        Original cell size will be taken from the rasters in the input 
        workspace. (required)
    
    (4) Nodata mode [nodata] 
        
        Boolean defining whether NoData mode is used. 
        True -> resulting aggregated rasters will have NoData
        False -> resulting aggregated rasters will not have NoData
        (required, default: True)
    
    (5) Extent [extent]
    
        String containing 'minX minY maxX maxY' that will be passed on
        to Arcpy.Extent class.
        (optional)
          
    (6) Mask (mask)
    
        String representing raster that will be used as a mask (optional)
        
    (7) Raster type [raster_type] 
    
        String file extension for output raster type (optional)
    

    """
    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        Aggregate.id = Aggregate.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, Aggregate.id)

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        self.log.debug(msgInitStart)
        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 15
0
class CalculateRasterGroup(ArcRasterTool):
    """ ArcTool for doing arithmetics on multiple rasters with NoData.
	
	Normally NoData propagates with summation (value + NoData = NoData), 
	subtraction, multiplication and converting NoData to a value (e.g. 0) is 
	not desirable in order not to mix NoData with real values. 
	ArcCalculateRasterGroup works with a set of rasters  (defined by a naming 
	convention) and builds a result raster where NoData values are preserved
	and value cells are used in a simple raster algebra operation.

	Parameters:
	(0) Input workspace [inws] - String input workspace holding the rasters
								  	(required)
	(1) Output workspace [outws] -  String path to output workspace (required)
	(2) Operator [operator] -  String defining which raster algebra operation
							   is applied to rasters (required)
	(3) Group template [template] - String used to define which rasters are
							  		grouped into a set (optional); syntax is 
							  		based on key identifiers: name_body_<ID>
							  		where name body is a common sub string
							  		shared by all rasters in the same group and
							  		<ID> is identifies rasters within group
	(4) Group identifier [identifier] - String identifying template tag that 
										is/are used as a basis for grouping 
										(optional); 
	(5) Reference table [reftable] - DataFrame object used for lookup 
									(optional); this lookup table can be used
									for extra grouping not apparent from the 
									naming convention. <ID2> is used for lookup
									link from <ID1>. For example 
									index_PUULAJI_11.img with template 
									<BODY1>_<BODY2>_<ID2> would match column
									"PUULAJI" with value 11 to a grouping 
									variable in reference group [refgroup]
	(6) Reference fields [reffields] - Tuple defining the field mapping in the 
									  dataframe. ("A", "B") would match values
									  from <ID1> in field A to a value in field
									  "B".
									  

	"""
    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcRasterTool.__init__(self, parameters, service, *args, **kwargs)

        CalculateRasterGroup.id = CalculateRasterGroup.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, CalculateRasterGroup.id)

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        self.service = service

        self.log.debug(msgInitSuccess)

    def __del__(self):
        if CalculateRasterGroup:
            CalculateRasterGroup.id = CalculateRasterGroup.id - 1

    def run(self):

        try:
            self.validate_parameters()

            self.workspace = str(self.get_parameter(0))
            self.log.debug('Found %s rasters in workspace %s' %
                           (len(self.files), self.workspace))
            wildcard = self.get_parameter(1)
            template = self.get_parameter(2)
            grouptags = self.get_parameter(3)
            operator = parse_operator(self.get_parameter(4))

            outws = self.get_parameter(5)
            # These will be None if not provided
            reftable = self.get_parameter(6)
            reffields = self.get_parameter(7)
            self.log.debugging = bool(self.get_parameter(8))

            # Use mapping reffields[0] -> reffields[1] from reftable

            fields = reftable.get_fields()
            if reffields[0] not in fields:
                raise ParameterError(
                    "Provided reference field %s not found in refernce table %s"
                    % (reffields[0], reftable))
            if reffields[1] not in fields:
                raise ParameterError(
                    "Provided reference field %s not found in refernce table %s"
                    % (reffields[1], reftable))

            mapping = {}
            for value in reftable.get_all_values(reffields[0]):
                # 9999 is missing value
                if value == 9999:
                    continue
                match_row = reftable.where_field_equal(reffields[0], value)
                mapping[value] = getattr(match_row, reffields[1])

            # Parse the raster files in the workspace based on the group tags
            rasteriterator = ArcRasterGroupIterator(self, self.workspace,
                                                    wildcard, template)
            rasteriterator.set_grouping(grouptags, mapping)

            # Calculate the job queue length based on provided options. If no
            # identifying field is used, the length of rasters defines the job
            # queue length
            job_length = len(rasteriterator)

            # Set the tool progressor
            if self.log.gui:
                self.log.setProgressor("Summing multiple rasters...",
                                       max=job_length)

            # Iterate over the parsed workspace. Remember that group is a list
            # of ParsedFileNames
            for group_id, group in rasteriterator.iteritems():

                self.log.debug('Group %s (%s) has %s rasters' %
                               (int(group_id), reffields[1], len(group)))

                # Each raster within the group is summed to a common result
                # raster -> each group has one output raster

                # Check that body identifiers are ok
                name_bodies = [raster.body for raster in group]
                if not all([item == name_bodies[0] for item in name_bodies]):
                    self.log.progressor(
                        'Multiple name bodies found, defaulting to %s' %
                        (name_bodies[0]),
                        log='warning')

                if group[0].extension:
                    extension = group[0].extension
                else:
                    extension = ""

                output_zero = os.path.join(
                    outws, '%s_%s_%s%s%s' %
                    (group[0].get_tag('BODY1'), int(group_id),
                     group[0].get_tag('BODY3'), "TMP", extension))
                cmds = []

                for raster in group:

                    cmds.append(
                        "self.gp.sa.Con(self.gp.sa.IsNull('%s'), 0, '%s')" %
                        (raster, raster))

                cmd = operator.join(cmds)

                self.log.info('Summing rasters in group %s' % int(group_id))
                #res = self.gp.sa.SingleOutputMapAlgebra(cmd, output_zero)
                op1 = eval(cmd)
                op1.save(output_zero)

                self.log.debug('Reclassifying NoData for group %s' %
                               int(group_id))
                output = output_zero.replace('TMP', '')
                cmd = 'self.gp.sa.SetNull(%s == 0)' % output_zero
                op2 = self.gp.sa.SetNull(output_zero, output_zero,
                                         "VALUE <= 0")
                op2.save(output)
                self.gp.Delete_management(output_zero)

                if self.log.gui:
                    self.log.setProgressorPosition()

            return 1

        except Exception, e:
            self.log.exception(e)
            return 1

        self.log.info('Finished running tool %s' % self.name)
        return 0
Exemplo n.º 16
0
class MultiConvertRaster(ArcTool):
    """ ArcTool for converting feature layers to rasters based on multiple
	attribute selections.

	TODO: parameters require a dictionary -> how will this handled by Toolbox
		  GUI?

	Parameters:
	(0) Input feature [infeature]:
	
		String representing source feature class (required)
		 
	(1) Input condition fields [inconfields]: 
	
		';'-separated list (String) of field names or a dictionary. List of 
		field names will create a cartesian product of all unique values in the 
		fields (same as ['all']below). 
		
		A dictionary {field_name: [values]} defines which fields and 
		values will be used for conditions. If [values] = [x1, x2, ..., x3]
		then x-values are used as values, if [values] = ['all'] then all values 
		are used (required)
		
	(2) Input value field [invalue]:
	
		String naming the field for output raster values [required]
									  
	(3) Output workspace [outws]:
	
		String path to output workspace (required)
		
	(4) Pixel size [pixelsize]: 
	
		Integer defining the output resolution (required)
	
	(5) Raster type [raster_type]:
		
		String file extension for output raster type (optional)
	
	(6) Fixed extent [extent]: 
	
		String defining a feature class or raster which extent will be used 
		(optional)
		
	(7) Snap raster [snap_raster]:
	
		String defining a raster to which result will be snapped
		(optional)

	"""
    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        MultiConvertRaster.id = MultiConvertRaster.id + 1
        self.id = MultiConvertRaster.id
        self.name = self.__module__.split('.')[-1]

        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__),
                             debugging=True)

        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1

        self.service = service

        self.log.debug(msgInitSuccess)
Exemplo n.º 17
0
class CalculateRasterGroup(ArcRasterTool):
	""" ArcTool for doing arithmetics on multiple rasters with NoData.
	
	Normally NoData propagates with summation (value + NoData = NoData), 
	subtraction, multiplication and converting NoData to a value (e.g. 0) is 
	not desirable in order not to mix NoData with real values. 
	ArcCalculateRasterGroup works with a set of rasters  (defined by a naming 
	convention) and builds a result raster where NoData values are preserved
	and value cells are used in a simple raster algebra operation.

	Parameters:
	(0) Input workspace [inws] - String input workspace holding the rasters
								  	(required)
	(1) Output workspace [outws] -  String path to output workspace (required)
	(2) Operator [operator] -  String defining which raster algebra operation
							   is applied to rasters (required)
	(3) Group template [template] - String used to define which rasters are
							  		grouped into a set (optional); syntax is 
							  		based on key identifiers: name_body_<ID>
							  		where name body is a common sub string
							  		shared by all rasters in the same group and
							  		<ID> is identifies rasters within group
	(4) Group identifier [identifier] - String identifying template tag that 
										is/are used as a basis for grouping 
										(optional); 
	(5) Reference table [reftable] - DataFrame object used for lookup 
									(optional); this lookup table can be used
									for extra grouping not apparent from the 
									naming convention. <ID2> is used for lookup
									link from <ID1>. For example 
									index_PUULAJI_11.img with template 
									<BODY1>_<BODY2>_<ID2> would match column
									"PUULAJI" with value 11 to a grouping 
									variable in reference group [refgroup]
	(6) Reference fields [reffields] - Tuple defining the field mapping in the 
									  dataframe. ("A", "B") would match values
									  from <ID1> in field A to a value in field
									  "B".
									  

	"""
	implements(IGISTool)

	id = 0

	def __init__(self, parameters, service,  *args, **kwargs):
		ArcRasterTool.__init__(self, parameters, service, *args, **kwargs)

		CalculateRasterGroup.id = CalculateRasterGroup.id + 1
		self.name = self.__class__.__name__
		# Identifier is a combination of the name and the class counter
		self.id = (self.name, CalculateRasterGroup.id)

		self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
                                             debugging=True)

		self.service = service

		self.log.debug(msgInitSuccess)

	def __del__(self):
		if  CalculateRasterGroup:
			CalculateRasterGroup.id = CalculateRasterGroup.id - 1
	
	def run(self):
		
		try:
			self.validate_parameters()
				
			self.workspace = str(self.get_parameter(0))
			self.log.debug('Found %s rasters in workspace %s' % (len(self.files),
																 self.workspace))
			wildcard = self.get_parameter(1)
			template = self.get_parameter(2)
			grouptags = self.get_parameter(3)
			operator = parse_operator(self.get_parameter(4))
			
			outws = self.get_parameter(5)
			# These will be None if not provided
			reftable = self.get_parameter(6)
			reffields = self.get_parameter(7)
			self.log.debugging = bool(self.get_parameter(8))
			
			# Use mapping reffields[0] -> reffields[1] from reftable
			
			fields = reftable.get_fields()
			if reffields[0] not in fields:
				raise ParameterError("Provided reference field %s not found in refernce table %s" % (reffields[0], reftable))
			if reffields[1] not in fields:
				raise ParameterError("Provided reference field %s not found in refernce table %s" % (reffields[1], reftable))
			
			mapping = {}
			for value in reftable.get_all_values(reffields[0]):
				# 9999 is missing value
				if value == 9999:
					continue
				match_row = reftable.where_field_equal(reffields[0], value)
				mapping[value] = getattr(match_row, reffields[1])
				
			
			# Parse the raster files in the workspace based on the group tags
			rasteriterator = ArcRasterGroupIterator(self, self.workspace, 
												    wildcard, template)
			rasteriterator.set_grouping(grouptags, mapping)
			
			# Calculate the job queue length based on provided options. If no
			# identifying field is used, the length of rasters defines the job
			# queue length
			job_length = len(rasteriterator)
			
			# Set the tool progressor
			if self.log.gui:
				self.log.setProgressor("Summing multiple rasters...",
										max=job_length)
			
			# Iterate over the parsed workspace. Remember that group is a list
			# of ParsedFileNames
			for group_id, group in rasteriterator.iteritems():
				
				self.log.debug('Group %s (%s) has %s rasters' % (int(group_id), 
																 reffields[1],
																 len(group)))
				
				# Each raster within the group is summed to a common result 
				# raster -> each group has one output raster
				
				# Check that body identifiers are ok
				name_bodies = [raster.body for raster in group]
				if not all([item == name_bodies[0] for item in name_bodies]):
					self.log.progressor('Multiple name bodies found, defaulting to %s' % (name_bodies[0]), 
									log='warning')
					
				if group[0].extension:
					extension = group[0].extension
				else:
					extension = ""
				
				output_zero = os.path.join(outws, '%s_%s_%s%s%s' % (group[0].get_tag('BODY1'),
																  int(group_id),
																  group[0].get_tag('BODY3'),
																  "TMP",
																  extension))																  
				cmds = []
				
				for raster in group:
					
					cmds.append("self.gp.sa.Con(self.gp.sa.IsNull('%s'), 0, '%s')" % (raster, raster))
					
				cmd = operator.join(cmds)
				
				self.log.info('Summing rasters in group %s' % int(group_id))
				#res = self.gp.sa.SingleOutputMapAlgebra(cmd, output_zero)
				op1 = eval(cmd)
				op1.save(output_zero)
				
				self.log.debug('Reclassifying NoData for group %s' % int(group_id))
				output = output_zero.replace('TMP', '')
				cmd = 'self.gp.sa.SetNull(%s == 0)' % output_zero
				op2 = self.gp.sa.SetNull(output_zero, output_zero, "VALUE <= 0")
				op2.save(output)
				self.gp.Delete_management(output_zero)
				
				if self.log.gui:
					self.log.setProgressorPosition()
			
			return 1
					
		except Exception, e:
			self.log.exception(e)
			return 1

		self.log.info('Finished running tool %s' % self.name)
		return 0
Exemplo n.º 18
0
class Aggregate(ArcTool):
    """ ArcTool for aggregating data to desired resolution while preserving 
    true NoData values.
    
    Tool will create new subfolders into the output workspace according to 
    target resolution if they do not exist.

    Parameters:
    
    (1) Input raster [inraster] 
    
        String representing the source workspace that contains rasters to be
        aggregated (required)
          
    (2) Output raster [outraster] 
        
        String for the location of the resulting rasters (required)
    
    (3) Cell factor [factors] 
        
        Integer cell factor (multiplier) to be used in the aggregation. 
        Original cell size will be taken from the rasters in the input 
        workspace. (required)
    
    (4) Nodata mode [nodata] 
        
        Boolean defining whether NoData mode is used. 
        True -> resulting aggregated rasters will have NoData
        False -> resulting aggregated rasters will not have NoData
        (required, default: True)
    
    (5) Extent [extent]
    
        String containing 'minX minY maxX maxY' that will be passed on
        to Arcpy.Extent class.
        (optional)
          
    (6) Mask (mask)
    
        String representing raster that will be used as a mask (optional)
        
    (7) Raster type [raster_type] 
    
        String file extension for output raster type (optional)
    

    """
    implements(IGISTool)

    id = 0

    def __init__(self, parameters, service, *args, **kwargs):
        ArcTool.__init__(self, parameters, service, *args, **kwargs)

        Aggregate.id = Aggregate.id + 1
        self.name = self.__class__.__name__
        # Identifier is a combination of the name and the class counter
        self.id = (self.name, Aggregate.id)
        
        self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
                                             debugging=True)
        
        self.log.debug(msgInitStart)
        # Tool needs spatial analyst in order to run
        # TODO: this should be moved to ToolValidator
        try:
            self.register_extension('spatial')
        except LicenseError, e:
            self.log.error(e)
            return 1
        
        self.service = service
        
        self.log.debug(msgInitSuccess)
Exemplo n.º 19
0
class MultiConvertRaster(ArcTool):
	""" ArcTool for converting feature layers to rasters based on multiple
	attribute selections.

	TODO: parameters require a dictionary -> how will this handled by Toolbox
		  GUI?

	Parameters:
	(0) Input feature [infeature]:
	
		String representing source feature class (required)
		 
	(1) Input condition fields [inconfields]: 
	
		';'-separated list (String) of field names or a dictionary. List of 
		field names will create a cartesian product of all unique values in the 
		fields (same as ['all']below). 
		
		A dictionary {field_name: [values]} defines which fields and 
		values will be used for conditions. If [values] = [x1, x2, ..., x3]
		then x-values are used as values, if [values] = ['all'] then all values 
		are used (required)
		
	(2) Input value field [invalue]:
	
		String naming the field for output raster values [required]
									  
	(3) Output workspace [outws]:
	
		String path to output workspace (required)
		
	(4) Pixel size [pixelsize]: 
	
		Integer defining the output resolution (required)
	
	(5) Raster type [raster_type]:
		
		String file extension for output raster type (optional)
	
	(6) Fixed extent [extent]: 
	
		String defining a feature class or raster which extent will be used 
		(optional)
		
	(7) Snap raster [snap_raster]:
	
		String defining a raster to which result will be snapped
		(optional)

	"""
	implements(IGISTool)

	id = 0

	def __init__(self, parameters, service, *args, **kwargs):
		ArcTool.__init__(self, parameters, service, *args, **kwargs)

		MultiConvertRaster.id = MultiConvertRaster.id + 1
		self.id = MultiConvertRaster.id
		self.name = self.__module__.split('.')[-1]
		
		self.log = ArcLogger("Zupport.%s" % (self.__class__.__name__), 
											 debugging=True)
		

		# Tool needs spatial analyst in order to run
		# TODO: this should be moved to ToolValidator
		try:
			self.register_extension('spatial')
		except LicenseError, e:
			self.log.error(e)
			return 1
		
		self.service = service
		
		self.log.debug(msgInitSuccess)