예제 #1
0
def _set_time_param(time):
    time_val = time
    if time is not None:
        if type(time) is list:
            if isinstance(time[0], datetime.datetime) or isinstance(
                    time[0], datetime.date):
                if time[0].tzname() is None or time[0].tzname() != "UTC":
                    time[0] = time[0].astimezone(datetime.timezone.utc)
            if isinstance(time[1], datetime.datetime) or isinstance(
                    time[1], datetime.date):
                if time[1].tzname() is None or time[1].tzname() != "UTC":
                    time[1] = time[1].astimezone(datetime.timezone.utc)
            starttime = _date_handler(time[0])
            endtime = _date_handler(time[1])
            if starttime is None:
                starttime = 'null'
            if endtime is None:
                endtime = 'null'
            time_val = "%s,%s" % (starttime, endtime)
        else:
            time_val = _date_handler(time)

    return time_val
예제 #2
0
    def _execute(self, params):
        caller_fnname = inspect.stack()[1][3]

        # print("Will call " + url +  " with these parameters:")

        name_type = self._method_params[caller_fnname]
        name_name = self._param_names[caller_fnname]
        return_values = self._return_values[caller_fnname]

        task_name = name_type[caller_fnname]
        url = self.url + "/" + task_name + "/execute"

        #---------------------in---------------------#

        for key, value in params.items():
            # print(k + " = " + str(v))
            if key in name_type:
                py_type = name_type[key]
                if py_type in [FeatureSet, LinearUnit, DataFile, RasterData]:
                    if type(value) in [
                            FeatureSet, LinearUnit, DataFile, RasterData
                    ]:
                        params[key] = value.to_dict()
                    elif _is_geoenabled(value) or hasattr(value, 'spatial'):
                        params[key] = value.spatial.__feature_set__
                    elif type(value) in [SpatialDataFrame]:
                        params[key] = value.__feature_set__
                    elif type(value) == str:
                        try:
                            klass = py_type  # type[value]
                            params[key] = klass.from_str(value)
                        except:
                            pass
                elif py_type == datetime.datetime:
                    params[key] = _date_handler(value)
        #--------------------------------------------#

        params.update({"f": "json"})

        gp_params = {}

        for param_name, param_value in params.items():
            gp_param_name = name_name.get(param_name, param_name)
            gp_params[gp_param_name] = param_value

        # copy environment variables if set
        if 'env:outSR' not in params and arcgis.env.out_spatial_reference is not None:
            gp_params['env:outSR'] = arcgis.env.out_spatial_reference

        if 'env:processSR' not in params and arcgis.env.process_spatial_reference is not None:
            gp_params['env:processSR'] = arcgis.env.process_spatial_reference

        if 'returnZ' not in params and arcgis.env.return_z is not False:
            gp_params['returnZ'] = True

        if 'returnM' not in params and arcgis.env.return_m is not False:
            gp_params['returnM'] = True

        resp = None

        if self.properties.executionType == 'esriExecutionTypeSynchronous':
            resp = self._con.post(url, gp_params, token=self._token)

            output_dict = {}

            for result in resp['results']:
                retParamName = result['paramName']
                ret_param_name = _camelCase_to_underscore(retParamName)
                ret_type = name_type[ret_param_name]
                ret_val = None
                if ret_type in [FeatureSet, LinearUnit, DataFile, RasterData]:
                    jsondict = result['value']
                    if jsondict is not None:
                        if 'mapImage' in jsondict:  # http://resources.esri.com/help/9.3/arcgisserver/apis/rest/gpresult.html#mapimage
                            ret_val = jsondict
                        else:
                            result_obj = ret_type.from_dict(jsondict)
                            result_obj._con = self._con
                            result_obj._token = self._token
                            ret_val = result_obj
                    else:
                        ret_val = jsondict
                else:
                    ret_val = result['value']

                output_dict[ret_param_name] = ret_val

            num_returns = len(resp['results'])
            if num_returns == 1:
                return output_dict[name_type['return_name']]
            else:
                ret_names = []
                for return_value in return_values:
                    ret_names.append(return_value['name'])

                NamedTuple = collections.namedtuple('ToolOutput', ret_names)
                tool_output = NamedTuple(**
                                         output_dict)  #TODO: preserve ordering
                return tool_output

        else:
            task_url = "{}/{}".format(self.url, task_name)
            submit_url = "{}/submitJob".format(task_url)
            job_info = self._con.post(submit_url, gp_params, token=self._token)
            job_id = job_info['jobId']
            try:
                isCan = False
                job_info = super()._analysis_job_status(task_url, job_info)
            except KeyboardInterrupt:
                cancel_url = "%s/jobs/%s/cancel" % (task_url,
                                                    job_info['jobId'])
                params = {'f': "json"}
                job_info = self._con.get(path=cancel_url, params=params)
                isCan = True
            if isCan:
                job_info = super()._analysis_job_status(task_url, job_info)
            resp = super()._analysis_job_results(task_url, job_info, job_id)
            # print('***'+str(resp))

            output_dict = {}
            for retParamName in resp.keys():
                ret_param_name = _camelCase_to_underscore(retParamName)
                ret_type = name_type[ret_param_name]
                ret_val = None
                if ret_type in [FeatureSet, LinearUnit, DataFile, RasterData]:
                    jsondict = resp[retParamName]
                    if jsondict is not None:
                        if 'mapImage' in jsondict:
                            ret_val = jsondict
                        else:
                            result = ret_type.from_dict(jsondict)
                            result._con = self._con
                            result._token = self._token
                            ret_val = result
                    else:
                        ret_val = jsondict
                else:
                    ret_val = resp[retParamName]

                output_dict[ret_param_name] = ret_val

            # tools with output map service - add another output:
            result_layer = self.properties.resultMapServerName
            if result_layer != '':
                #job_id = job_info.get("jobId")
                result_layer_url = self.url.replace(
                    '/GPServer', '/MapServer') + '/jobs/' + job_id

                output_dict['result_layer'] = MapImageLayer(
                    result_layer_url, self._gis)

            num_returns = len(resp)
            if num_returns == 1:
                return output_dict[name_type[
                    'return_name']]  # *** output_dict[return_values[0]['name']]
            else:
                ret_names = []
                for return_value in return_values:
                    ret_names.append(return_value['name'])

                NamedTuple = collections.namedtuple('ToolOutput', ret_names)
                tool_output = NamedTuple(**
                                         output_dict)  #TODO: preserve ordering
                return tool_output
예제 #3
0
def _execute_gp_tool(gis,
                     task_name,
                     params,
                     param_db,
                     return_values,
                     use_async,
                     url,
                     webtool=False,
                     add_token=True,
                     return_messages=False,
                     future=False):
    if gis is None:
        gis = arcgis.env.active_gis

    gp_params = {"f": "json"}

    # ---------------------in---------------------#
    for param_name, param_value in params.items():
        #print(param_name + " = " + str(param_value))
        if param_name in param_db:
            py_type, gp_param_name = param_db[param_name]
            if param_value is None:
                param_value = ''
            gp_params[gp_param_name] = param_value
            if py_type == FeatureSet:
                if webtool:
                    if isinstance(param_value, (tuple, list)):
                        gp_params[gp_param_name] = [
                            _layer_input_gp(p) for p in param_value
                        ]
                    else:
                        gp_params[gp_param_name] = _layer_input_gp(param_value)

                else:
                    try:
                        from arcgis.features.geo._accessor import _is_geoenabled
                    except:

                        def _is_geoenabled(o):
                            return False

                    if type(param_value) == FeatureSet:
                        gp_params[gp_param_name] = param_value.to_dict()
                    elif _is_geoenabled(param_value):
                        gp_params[gp_param_name] = json.loads(
                            json.dumps(param_value.spatial.__feature_set__,
                                       default=_date_handler))
                    elif type(param_value) == str:

                        try:
                            klass = py_type
                            gp_params[gp_param_name] = klass.from_str(
                                param_value)

                        except:
                            pass

            elif py_type in [LinearUnit, DataFile, RasterData]:
                if type(param_value) in [LinearUnit, DataFile, RasterData]:
                    gp_params[gp_param_name] = param_value.to_dict()

                elif type(param_value) == str:

                    try:
                        klass = py_type
                        gp_params[gp_param_name] = klass.from_str(param_value)

                    except:
                        pass

                elif isinstance(param_value, arcgis.gis.Layer):
                    gp_params[gp_param_name] = param_value._lyr_dict

            elif py_type == datetime.datetime:
                gp_params[gp_param_name] = _date_handler(param_value)
    # --------------------------------------------#

    _set_env_params(gp_params, params)

    # for param_name, param_value in gp_params.items():
    #     print(param_name + " = " + str(param_value))

    gptool = arcgis.gis._GISResource(url, gis)

    if use_async:
        task_url = "{}/{}".format(url, task_name)
        submit_url = "{}/submitJob".format(task_url)
        if add_token and submit_url.lower().find("arcgis.com") == -1:
            try:
                job_info = gptool._con.post(submit_url,
                                            gp_params,
                                            token=gptool._token)
            except:
                job_info = gptool._con.post(submit_url, gp_params)
        else:
            job_info = gptool._con.post(submit_url, gp_params)
        job_id = job_info['jobId']
        if future:
            executor = concurrent.futures.ThreadPoolExecutor(1)
            future = executor.submit(
                _future_op,
                *(gptool, task_url, job_info, job_id, param_db, return_values,
                  return_messages))
            executor.shutdown(False)
            gpjob = GPJob(future=future,
                          gptool=gptool,
                          jobid=job_id,
                          task_url=task_url,
                          gis=gptool._gis,
                          notify=arcgis.env.verbose)
            return gpjob
        job_info = _analysis_job_status(gptool, task_url, job_info)
        resp = _analysis_job_results(gptool, task_url, job_info, job_id)

        # ---------------------async-out---------------------#
        output_dict = {}
        for retParamName in resp.keys():
            output_val = resp[retParamName]
            try:
                ret_param_name, ret_val = _get_output_value(
                    gptool, output_val, param_db, retParamName)
                output_dict[ret_param_name] = ret_val
            except KeyError:
                pass  # cannot handle unexpected output as return tuple will change

        # tools with output map service - add another output:
        # result_layer = '' #***self.properties.resultMapServerName
        if gptool.properties.resultMapServerName != '':
            job_id = job_info.get("jobId")
            result_layer_url = url.replace('/GPServer',
                                           '/MapServer') + '/jobs/' + job_id

            output_dict['result_layer'] = MapImageLayer(
                result_layer_url, gptool._gis)

        num_returns = len(resp)
        if return_messages:
            return _return_output(num_returns, output_dict,
                                  return_values), job_info

        return _return_output(num_returns, output_dict, return_values)

    else:  # synchronous
        exec_url = url + "/" + task_name + "/execute"
        if add_token:
            resp = gptool._con.post(exec_url, gp_params, token=gptool._token)
        else:
            resp = gptool._con.post(exec_url, gp_params)

        output_dict = {}

        for result in resp['results']:
            retParamName = result['paramName']

            output_val = result['value']
            try:
                ret_param_name, ret_val = _get_output_value(
                    gptool, output_val, param_db, retParamName)
                output_dict[ret_param_name] = ret_val
            except KeyError:
                pass  # cannot handle unexpected output as return tuple will change

        num_returns = len(resp['results'])
        if return_messages:
            return _return_output(num_returns, output_dict,
                                  return_values), job_info
        return _return_output(num_returns, output_dict, return_values)