Arcgis中创建Python脚本工具


相比于自定义工具箱的源脚本和参数定义难以集中管理的缺点,在Python工具箱中,参数定义、代码验证和源代码都在同一位置进行处理,因而,Python 工具的创建和维护更加容易。此外,Python 工具箱支持脚本工具不支持的功能,例如值表、复合数据类型和自定义许可检查。Python 工具箱 (.pyt) 只是一个基于 ASCII 的文件,该文件定义了工具箱和一个或多个工具。
环境:ArcGis10.2

创建工具步骤

第一步:

在arcgis中任意选择一个文件夹,右键选择新建——Python Toolbox。
在这里插入图片描述

第二步:

编写工具内容,右键新建工具箱的菜单——Edit。这边打开默认是UTF-8编码的,此时如果里面存在中文可能会乱码,需要把txt另存为ANSI编码。
在这里插入图片描述

第三步:

Python工具箱打开后已经有了一个模板了,接下来只需要在相应的位置写自己的工具实现逻辑就行。写完后的样子,样例代码放在最后了
在这里插入图片描述

定义工具

工具箱Toolbox

__init__方法:定义了工具箱的属性,
self.label定义标签
self.alias定义别名
self.tools定义了包含的所有工具名称列表

工具类

工具类中共有以下六个方法:

1、init

必填信息。定义了工具属性
label:标注是工具的显示名称,如“目录”窗口 中所示
description:工具的描述
canRunInBackground:如果 canRunInBackground 取消设置或设置为 True,此工具将遵循地理处理选项 对话框中的当前后台处理 设置。

2、getParameterInfo

可选。定义了参数,每个参数用Parameter类创建对象。其中参数parameter属性:
displayName:工具对话框中显示的参数名称
name:Python 中的工具语法中显示的参数名称
datatype:每个 Python 工具箱的工具参数都有关联的数据类型。打开脚本工具对话框后,地理处理使用数据类型检查参数值。数据类型也可用于浏览数据 - 只有与参数数据类型匹配的数据才会显示在浏览对话框中。https://desktop.arcgis.com/zh-cn/arcmap/10.6/analyze/creating-tools/defining-parameter-data-types-in-a-python-toolbox.htm
parameterType:提供三种 parameterType 选项:
必选 - 必须提供值才能执行工具。
可选 - 不需要为参数提供值。
派生 - 该参数只适用于输出参数(请参阅下文的方向参数)。派生的输出参数不会显示在工具对话框中。
direction:该属性定义参数是工具的输入参数还是工具的输出参数。如果将 parameterType 设置为“派生”,则应将参数 direction 设置为“输出”。
multiValue:是否为多值参数。
filter:可以限定参数类型。
displayOrder:定义参数在工具框的显示顺序。
parameterDependencies:定义参数依赖性。

3、isLicensed

可选。可以控制许可行为,验证能否执行,检入检出许可。如果isLicensed方法返回False,则工具不能执行。如果该方法返回True或未使用该方法,则工具可以执行。

4、updateParameters

可选。定义了工具内部验证的过程,比如输入数据达到某个条件,则启用或者禁用某个参数,或者为某个参数设置默认值。

5、updateMessage

可选。在从内部验证例程返回后调用。您可以检查在内部验证过程中创建的消息并根据需要进行更改。

6、execute

必填信息,包含了工具执行逻辑,必要方法,只包括该方法也可以运行工具,但是没有参数界面。

进度条的使用

脚本中进度条使用

代码

import arcpy
import socket


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "测试工具箱"
        self.alias = "测试"
        # List of tool classes associated with this toolbox
        self.tools = [Intersect, CalculateField]


class Intersect(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        # 初始化工具类
        self.label = "相交"
        self.description = "相交工具描述"
        self.canRunInBackground = False

    def getParameterInfo(self):
        # 定义工具的参数
        """Define parameter definitions"""
        in_features = arcpy.Parameter(displayName="输入要素",
                                      name="in_features",
                                      datatype="GPFeatureLayer",
                                      parameterType="Required",
                                      direction="Input",
                                      multiValue=True)
        in_features.filter.list = ["Polygon"]

        # Derived Output Features parameter
        out_features = arcpy.Parameter(
            displayName="输出要素",
            name="out_features",
            datatype="GPFeatureLayer",
            parameterType="输出",
            direction="Output")
        params = [in_features, out_features]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        # 返回该工具是否获得执行许可。
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        # 在用户每次在工具对话框中更改参数时调用。从 updateParameters 返回后,地理处理将调用它的内部验证例程。
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        # 在从内部验证例程返回后调用。您可以检查在内部验证过程中创建的消息并根据需要进行更改。
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
        # 工具的源代码
        in_features = parameters[0].valueAsText
        out_feature = parameters[1].valueAsText
        arcpy.Intersect_analysis(in_features, out_feature)
        return


class CalculateField(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "计算随机值"
        self.description = "计算随机值描述"
        self.canRunInBackground = False
        self.params = arcpy.GetParameterInfo()

    def getParameterInfo(self):
        """Define parameter definitions"""
        # 定义工具面板上的参数形式
        in_features = arcpy.Parameter(
            displayName="Input Features",
            name="in_features",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input"
        )

        vt = arcpy.Parameter(
            name='summary_fields',
            displayName='融合字段',
            datatype='Field',
            direction='Input',
            parameterType='Optional',
            multiValue=True
        )
        vt.parameterDependencies = [in_features.name]

        out_features = arcpy.Parameter(
            displayName="输出要素",
            name="out_features",
            datatype="GPFeatureLayer",
            parameterType="输出",
            direction="Output")

        params = [in_features, vt, out_features]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        r = socket.gethostbyname(socket.gethostname())
        if r == '192.168.2.58':
            return True
        return False

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        if parameters[0].altered:
            parameters[2].enabled = True
        else:
            parameters[2].enabled = False
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        try:
            if parameters[0].altered:
                field_names = []
                fields = arcpy.ListFields(parameters[0].valueAsText)
                for field in fields:
                    field_names.append(field.baseName.upper())
                if not ("BSM" in field_names):
                    parameters[0].setErrorMessage("输入要素必须包含 BSM 字段")
        except Exception as e:
            parameters[0].setErrorMessage(e.message)
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
        in_features = parameters[0].valueAsText
        out_feature = parameters[2].valueAsText
        arcpy.env.overwriteOutput = True
        arcpy.Copy_management(in_features, out_feature)
        arcpy.AddField_management(out_feature, 'RandomNum', 'LONG')
        arcpy.SetProgressor("default", "This is the default progressor")
        record_count = int(arcpy.GetCount_management(out_feature).getOutput(0))
        if record_count == 0:
            raise ValueError("{0} has no records to count".format(out_feature))
        increment = 1
        arcpy.SetProgressor("step", "Step progressor: Counting from 0 to {0}".format(record_count), 0, record_count,
                            increment)  # 方法主要有五个参数,p1-对话框名称类型;p2-消息字符串;p3-进度的最小值默认0,;p4-进度的最大值默认100;p5-步进值 一般情况为1
        with arcpy.da.UpdateCursor(out_feature, ["RandomNum", 'OID@']) as cursor:
            for row in cursor:
                row[0] = rando()
                cursor.updateRow(row)
                arcpy.SetProgressorLabel("Iteration: {0}".format(row[1]))  # 方法是处理进度中设置处理消息的方法
                arcpy.SetProgressorPosition()  # 步进的方法,处理改变进度时调用
        arcpy.SetProgressorPosition(record_count)
        arcpy.ResetProgressor()  # 将进度条重置为初始状态
        return


# 生成随机整数1-5
def rando():
    import random
    rand = int(random.uniform(1, 6))
    return rand

好记心不如烂笔头,写写记记罢了

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值