빈도를 사용하지 않고 도구 검증을 사용하여 ArcGIS에서 다중 값 선택 목록을 생성 하시겠습니까?


11

ESRI의 블로그 사이트 '다중 값 선택 목록 생성' 에있는 모델 및 스크립트 조합을 수정하려고합니다 .

그러나 임베디드 스크립트에 사용 된 유효성 검사 중 일부는 제대로 작동하기 위해 '주파수'도구에 의존하지만이 기능은 Advanced license (lame)에서만 사용할 수 있습니다. 블로그 게시물에서는 워크 플로와 모델 및 스크립트를 다운로드 할 수있는 위치에 대해 설명합니다 (하지만 요청시 여기에 게시하겠습니다). 내가 알 수있는 한, 내가 따르는 기능의 핵심은 다중 값 선택 목록을 생성합니다.

여기에 이미지 설명을 입력하십시오

..은 유효성 검사 스크립트가 올바르게 작동하는 것으로 가정합니다. 유효성 검사가 없으면 필드에서 값을 목록으로 표시 할 수 없습니다. 이 유효성 검사 스크립트에서 제거하여 제거 할 수있는 기능이 있습니까? 아니면 해결 방법이 있습니까? 유효성 검사 프로세스에 익숙하지 않습니다. 다음은 유효성 검사를위한 코드입니다 (코드 샘플로 게시하려고했지만 따르기가 더 쉬운 것 같습니다). 여기에 이미지 설명을 입력하십시오

[ 편집자 주 : 여기에 실제 검증 코드가 있습니다. 이미지가 올바르지 않습니다]

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

1
연결 한 도구 상자의 확인 코드는 연결 한 이미지의 확인 코드와 다릅니다. 전자는 빈도 도구를 사용하므로 고급 라이센스가 필요합니다. 이전 블로그 게시물에서 자세히 설명 된 후자는 SearchCursor와 같은 표준 arcpy 함수 만 사용하기 때문이 아닙니다. 나는 당신에게 답이 없지만 둘을 함께 조각하면 아마 알아낼 수 있습니다.
blah238

@ blah268 10.2입니다. 죄송합니다. 흠, 이제 매우 흥미로운 관찰입니다. 나는 그것을 볼 것이지만, 나는 궁금하다 : 유효성 검사가 선택 목록으로 값을 전달하는 것임을 올바르게 이해하고 있습니까? 객관식은 내가 추구하는 기능입니다. 다시 연락 드리겠습니다. 답변 해 주셔서 감사합니다.
Clickinaway

1
스크립트 도구 매개 변수 속성은 매개 변수 목록과 해당 속성 (MultiValue 속성 포함)을 설정하는 곳입니다. 스크립트 도구 유효성 검사는이 특정 도구가 다른 매개 변수 값 (기능 클래스 및 필드 이름)을 기반으로 다중 값 매개 변수 값을 채우는 곳입니다. 더 큰 기능 클래스를 위해 그것을 가지고 놀면서, 나는 이것을 프로덕션에 넣지 않을 것입니다. 지오 프로세싱 옵션에서 "지오 프로세싱 작업의 출력 덮어 쓰기"를 선택하지 않은 경우 너무 느리고 오류가 발생합니다.
blah238

1
채팅을 할 수는 없지만 요구 사항, 시도한 내용 및 작동하지 않는 내용을 자세히 설명하기 위해 질문을 편집하는 것입니다.
blah238

답변:


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

나는 다른 방법으로 그것을 수행했다 : 데이터베이스를 사용하는 것은 모양 파일이나 필드를 선택하지 않고 다섯 번째 수준으로 구성됩니다. 첫 번째 수준에서 항목을 선택하기 만하면 유효성 검사 스크립트가 첫 번째 수준에서 선택한 두 번째 수준의 값을 생성합니다.

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

전체 코드를 올바르게 형식화하십시오.
Marcelo Villa-Piñeros

10.5.0에서 작업 완료
Younes Idriss

코드의 일부는 형식화되어 있지만 다른 행은 표시되지 않습니다 ( 예 : 코드의 import 문). { }버튼을 사용 하여 코드를 올바르게 포맷하십시오.
Marcelo Villa-Piñeros

또한 클래스 정의가 누락 된 것 같습니다.
Marcelo Villa-Piñeros
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.