頻度を使用せずにツール検証を使用してArcGISで複数値選択リストを生成しますか?


11

「複数値選択リストの生成」というタイトル ESRIのブログサイトにあるモデルとスクリプトの組み合わせを適応させようとしてい ます。

ただし、埋め込みスクリプトで使用される検証の一部は、適切に機能するために「周波数」ツールに依存していると結論付けましたが、これはAdvancedライセンス(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関数を使用するだけなので、そうすべきではありません。答えはありませんが、2つをつなぎ合わせれば理解できるかもしれません。
blah238 14年

@ blah268 10.2、それを見逃してすみません。うーん、今では非常に興味深い観察です。私はそれを見ていきますが、私は興味があります:検証が​​値を選択リストとして渡すものであることを正しく理解していますか?多肢選択は私が求めている機能です。返信させていただきます。
Clickinaway 14年

1
スクリプトツールのパラメータープロパティは、パラメーターのリストとそのプロパティ(MultiValueプロパティを含む)を設定する場所です。スクリプトツールの検証では、この特定のツールが他のパラメーター値(機能クラスとフィールド名)に基づいて複数値パラメーター値を設定します。大規模なフィーチャクラスでそれをいじってみて、私はこれを実稼働環境に入れません。速度が遅すぎます。また、ジオプロセシングオプションで[ジオプロセシング操作の出力を上書きする]がオンになっていない場合はエラーになります。
blah238 14年

1
チャットはできませんが、質問を編集して、要件、試行したこと、機能していないことを詳しく説明することをお勧めします。
blah238 14年

回答:


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つのレベルで構成し、シェープファイルまたはフィールドを選択せず​​に、最初のレベルから項目を選択するだけで、検証スクリプトは最初のレベル、つまりスクリプトの選択に従って2番目のレベルの値を生成します:

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

コード全体を適切にフォーマットしてください。
マルセロヴィラ

それは行われ、10.5.0で機能しました
Younes Idriss

あなたのコードの一部はフォーマットされていますが、見ることができるように、他の行は(されない例えば、あなたのコードのimport文は)。{ }ボタンを使用して、コードを適切にフォーマットします。
マルセロヴィラ

アドバイスをありがとう
ユネスイドリス

また、クラスの定義が欠落しているように見えます。
マルセロヴィラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.