使用工具验证而不使用频率在ArcGIS中生成多值选择列表?


11

我正在尝试改编ESRI博客网站上的模型和脚本组合,标题为 “生成多值选择列表”。

但是,我得出的结论是,嵌入式脚本中使用的部分验证依赖于“频率”工具才能正常运行,但这仅适用于Advanced许可(lam)。博客文章解释了工作流程以及在何处下载模型和脚本(但我会根据要求将它们愉快地发布在此处)。据我所知,我所追求的功能的核心是生成一个多值选择列表:

在此处输入图片说明

..取决于验证脚本是否正常运行。没有验证,我无法从字段中获取值以列表形式显示。有什么我可以从验证脚本中删除的东西来获得我想要的功能,还是有解决方法?我不熟悉验证过程。这是验证的代码(我打算作为代码示例发布,但是看起来可能更容易理解): 在此处输入图片说明

[ 编者注:这是实际的验证码,图片不正确]

import arcpy

class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parmater
    has been changed."""
    if self.params[1].altered: #Set condition - if the input field value changes
        if self.params[1].value: #if the field parameter has a value
            for field in arcpy.Describe(self.params[0].value).fields: #iterate through fields in the input dataset
                if field.name.lower() == self.params[1].value.value.lower(): #find the field object with the same name as field parameter
                    try:
                        if self.params[2].values: #if this parameter has seleted values
                            oldValues = self.params[2].values #set old values to the selected values
                    except Exception:
                        pass
                    values = set() #create an empty set
                    fieldname = self.params[1].value.value #set the value of variable fieldname equal to the input field value
                    FrequencyTable = arcpy.Frequency_analysis (self.params[0].value, "in_memory\Frequency", self.params[1].value.value, "") #for large tables create a frequency table
                    cursor = arcpy.SearchCursor(FrequencyTable, "", "", self.params[1].value.value, "{0} A".format(self.params[1].value.value)) #open a search cursor on the frequency table
                    for row in cursor: #loop through each value
                        values.add(row.getValue(fieldname)) #add the value to the set
                    self.params[2].filter.list = sorted(values) #set the filter list equal to the sorted values
                    newValues = self.params[2].filter.list
                    try:
                        if len(oldValues): # if some values are selected
                            self.params[2].values = [v for v in oldValues if v in newValues] # check if seleted values in new list,
                            # if yes, retain the seletion.
                    except Exception:
                        pass

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

我的假设(通过测试)是否可能是验证是关键,是否有其他假设不允许将值显示为可选列表呢?提前谢谢了。拥有这种类型的功能,将真正促使我尝试在公司中分发的几个关键工作流程的采用!


1
您正在使用哪个版本的ArcGIS?我问是因为10.1 arcpy.da.SearchCursor比旧版本更快,更适合此任务arcpy.SearchCursor
blah238 2014年

1
链接的工具箱的验证码与链接的图像中的验证码不同。前者需要使用高级许可证,因为它使用了频率工具。后者不应在较早的博客文章中详细介绍,因为它仅使用标准的arcpy函数(如SearchCursor),因此不应该。对于您,我没有答案,但是如果您将两者结合在一起,也许您可​​以解决。
blah238 2014年

@ blah268其10.2,很抱歉错过了。嗯,这是一个非常有趣的观察。我会看的,但我很好奇:我是否正确理解验证是将值作为选择列表传递的原因?多项选择是我追求的功能。我会尽快回复您,非常感谢您的回复!
Clickinaway 2014年

1
脚本工具参数属性是您在其中设置参数及其属性(包括MultiValue属性)的列表的地方。脚本工具验证是在此特定工具根据其他参数值(功能类和字段名称)填充多值参数值的地方。对于较大的要素类使用它,我不会将其投入生产。太慢了,如果没有在“地理处理”选项中选中“覆盖地理处理操作的输出”,也会出错。
blah238

1
我无法聊天,但我建议编辑您的问题以详细说明您的要求,您尝试过的内容以及不起作用的内容。
blah238 2014年

Answers:


9

我认为有些人可能会觉得这很有价值。ESRI非常有礼貌,可以帮助完成此工作,并找到博客文章中使用的验证的替代方法,而无需高级许可证。虽然我当然必须找出一些其他事项,但我不能相信验证代码。但是,目的证明了手段是正确的,这有资格回答我的问题。干得好:

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    if self.params[0].value and self.params[1].value:
        self.params[2].filter.list = sorted({row[0] for row in arcpy.da.SearchCursor(self.params[0].value, self.params[1].value.value) if row[0]})

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

考虑到其搜索记录的数量(至少在我的数据中),使用arcpy.da.SearchCursor可以非常快速地从选定字段返回值。我可能会启动一个新线程,以查看是否有人对基于查询的过滤器应用于验证有任何想法。我希望这对某人有帮助,但很高兴我们有一个答案!


1

我以另一种方式做到了:使用包含5个级别的数据库,而无需选择shapefile或字段,仅通过从第一级中选择项目即可,验证脚本会根据您在第一级中的选择生成第二级的值,即脚本:

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):  
    """Setup arcpy and the list of tool parameters."""  
    self.params = arcpy.GetParameterInfo()  



  def initializeParameters(self):  
    """Refine the properties of a tool's parameters.  This method is  
    called when the tool is opened."""  
    return  

  def updateParameters(self):

    fc="C:/LUCS/System_shapes/sys.shp"
##    fc = arcpy.MakeFeatureLayer_management(Lucssys)  
    """Modify the values and properties of parameters before internal  
    validation is performed.  This method is called whenever a parmater  
    has been changed."""  
##    if self.params[0].value and self.params[0].value:


    fc="C:/LUCS/System_shapes/sys.shp"  
    col=  ("L1_NAM") 
    self.params[0].filter.list = [str(val) for val in  
                                    sorted(  
                                      set(  
                                        row.getValue(col)  
                                        for row in arcpy.SearchCursor(fc, None, None,col)))]  
    if self.params[0].value not in self.params[0].filter.list:  
      self.params[0].value = self.params[0].filter.list[0]


    if self.params[0].value:

        fc="C:/LUCS/System_shapes/sys.shp"  
        col1=  ("L1_NAM")
        col2=  ("L2_NAM") 
        fields=(col1,col2)
##___________level2___________________________________________________________
    fc="C:/LUCS/System_shapes/sys.shp" 
    col1=  ("L1_NAM")
    col2=  ("L2_NAM") 
    fields=(col1,col2)

    Level0list=[]
    Level0list_uniq=[]
    cursor = arcpy.SearchCursor(fc)
    for row in cursor:
              if (row.getValue(col1)) ==(str(self.params[0].value)):
                      Level0list.append (row.getValue(col2))

    for elem in Level0list:
              if elem not in Level0list_uniq:
                  Level0list_uniq.append(elem)


    if self.params[1].value not in self.params[1].filter.list:  
        self.params[1].filter.list =Level0list_uniq
##________________level3______________________________________________________        
    fc="C:/LUCS/System_shapes/sys.shp" 
    col2=  ("L2_NAM")
    col3=  ("L3_NAM") 
    fields=(col2,col3)
    Level2list=[]
    Level2list_uniq=[]
    cursor = arcpy.SearchCursor(fc)
    for row in cursor:
              if (row.getValue(col2)) ==(str(self.params[1].value)):
                      Level2list.append (row.getValue(col3))
    for elem in Level2list:
              if elem not in Level2list_uniq:
                  Level2list_uniq.append(elem)
    if self.params[2].value not in self.params[2].filter.list:  
        self.params[2].filter.list =Level2list_uniq
##________________level4______________________________________________________        
    fc="C:/LUCS/System_shapes/sys.shp" 
    col3=  ("L3_NAM")
    col4=  ("L4_NAM") 
    fields=(col3,col4)

    Level3list=[]
    Level3list_uniq=[]
    cursor = arcpy.SearchCursor(fc)
    for row in cursor:
              if (row.getValue(col3)) ==(str(self.params[2].value)):
                      Level3list.append (row.getValue(col4))
    for elem in Level3list:
              if elem not in Level3list_uniq:
                  Level3list_uniq.append(elem)
    if self.params[3].value not in self.params[3].filter.list:  
        self.params[3].filter.list =Level3list_uniq
##________________level5______________________________________________________        
    fc="C:/LUCS/System_shapes/sys.shp" 
    col4=  ("L4_NAM")
    col5=  ("L5_NAM") 
    fields=(col4,col5)

    Level4list=[]
    Level4list_uniq=[]
    cursor = arcpy.SearchCursor(fc)
    for row in cursor:
              if (row.getValue(col4)) ==(str(self.params[3].value)):
                      Level4list.append (row.getValue(col5))
    for elem in Level4list:
              if elem not in Level4list_uniq:
                  Level4list_uniq.append(elem)
    if self.params[4].value not in self.params[4].filter.list:  
        self.params[4].filter.list =Level4list_uniq

  def updateMessages(self):  
    """Modify the messages created by internal validation for each tool  
    parameter.  This method is called after internal validation."""  

0
Add new conditions to ensure a single option when the same term exists in more than one category. ِand to force arcpy to deal with arabic fonts

import arcpy
import sys

reload(sys)

sys.setdefaultencoding('utf-8')

class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""



  def __init__(self):  
    """Setup arcpy and the list of tool parameters."""  
    self.params = arcpy.GetParameterInfo()  




  def updateParameters(self):

    fc="C:/LUCS/System_shapes/sys.shp"
    col=  ("L1_NAM")
 ##________________level1_________________

    self.params[0].filter.list = [str(val) for val in  
                                    sorted(  
                                      set(  
                                        row.getValue(col)  
                                        for row in arcpy.SearchCursor(fc, None, None,col)))]  
    if self.params[0].value not in self.params[0].filter.list:  
      self.params[0].value = self.params[0].filter.list[0]



    if self.params[0].value:

        fc="C:/LUCS/System_shapes/sys.shp"  
        col1=  ("L1_NAM")
        col2=  ("L2_NAM")
        col3=  ("L3_NAM") 
        col4=  ("L4_NAM")
        col5=  ("L5_NAM") 
        fields=(col1,col2,col3,col4,col5)
        Level1list=[]
        Level1list_uniq=[]
        Level2list=[]
        Level2list_uniq=[]
        Level3list=[]
        Level3list_uniq=[]
        Level4list=[]
        Level4list_uniq=[]
        Level5list=[]
        Level5list_uniq=[]

        cursor = arcpy.SearchCursor(fc)
        for row in cursor:
                        if (row.getValue(col1)) ==(str(self.params[0].value)):
                                Level1list.append (row.getValue(col2))

        for elem in Level1list:
                        if elem not in Level1list_uniq:
                            Level1list_uniq.append(elem)


        if self.params[1].value not in self.params[1].filter.list:  
              self.params[1].filter.list =Level1list_uniq
      ##________________level3_________________        
        cursor = arcpy.SearchCursor(fc)
        for row in cursor:
                  if (row.getValue(col1)) ==(str(self.params[0].value)):
                    if (row.getValue(col2)) ==(str(self.params[1].value)):
                            Level2list.append (row.getValue(col3))
        for elem in Level2list:
                    if elem not in Level2list_uniq:
                        Level2list_uniq.append(elem)
        if self.params[2].value not in self.params[2].filter.list:  
              self.params[2].filter.list =Level2list_uniq
      ##________________level4_______________       
        cursor = arcpy.SearchCursor(fc)
        for row in cursor:
              if (row.getValue(col1)) ==(str(self.params[0].value)):

                    if (row.getValue(col3)) ==(str(self.params[2].value)):
                            Level3list.append (row.getValue(col4))
        for elem in Level3list:
                    if elem not in Level3list_uniq:
                        Level3list_uniq.append(elem)
        if self.params[3].value not in self.params[3].filter.list:  
              self.params[3].filter.list =Level3list_uniq
      ##________________level5_______________      
        cursor = arcpy.SearchCursor(fc)
        for row in cursor:
            if (row.getValue(col1)) ==(str(self.params[0].value)):
                    if (row.getValue(col4)) ==(str(self.params[3].value)):
                            Level4list.append (row.getValue(col5))
        for elem in Level4list:
                    if elem not in Level4list_uniq:
                        Level4list_uniq.append(elem)
        if self.params[4].value not in self.params[4].filter.list:  
              self.params[4].filter.list =Level4list_uniq

    return

请正确格式化整个代码。
MarceloVilla-Piñeros19年

它已经完成,并在10.5.0中工作
Younes Idriss

您的部分代码已格式化,但是您可以看到其他行未格式化(例如,代码的import语句)。使用{ }按钮正确设置代码格式。
MarceloVilla-Piñeros19年

看起来您好像缺少类的定义。
MarceloVilla-Piñeros19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.