Membuat daftar pilihan multinilai di ArcGIS menggunakan Validasi Alat tanpa menggunakan Frekuensi?

11

Saya mencoba mengadaptasi model dan kombinasi skrip yang ditemukan di situs blog ESRI berjudul 'Menghasilkan daftar pilihan multinilai'.

Namun, saya telah menyimpulkan bahwa bagian dari validasi yang digunakan dalam skrip tertanam bergantung pada Alat 'Frekuensi' agar dapat berfungsi dengan baik, tetapi ini hanya tersedia dengan Lisensi lanjutan (lumpuh). Posting blog menjelaskan alur kerja dan tempat untuk mengunduh model dan skrip (tapi saya akan dengan senang hati mempostingnya di sini atas permintaan). Sejauh yang saya tahu, inti dari fungsionalitas yang saya cari, menghasilkan daftar pilihan multinilai:

masukkan deskripsi gambar di sini

..is didasarkan pada skrip validasi yang berfungsi dengan baik. Tanpa validasi, saya tidak bisa mendapatkan nilai dari bidang muncul sebagai daftar. Adakah yang bisa saya hapus dari skrip validasi ini untuk mendapatkan fungsionalitas yang saya kejar, atau ada solusinya? Saya tidak terbiasa dengan proses validasi. Berikut adalah kode untuk validasi (saya akan memposting sebagai Contoh Kode, tetapi sepertinya ini lebih mudah untuk diikuti): masukkan deskripsi gambar di sini

[ Catatan editor: ini kode validasi aktual, gambarnya tidak benar]

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

Mungkinkah asumsi saya (melalui pengujian) bahwa validasi adalah bagian kunci adalah salah, dan bahwa hal lain tidak memungkinkan nilai-nilai diekspos sebagai daftar yang dapat dipilih? Banyak terima kasih sebelumnya. Memiliki jenis fungsi ini akan benar-benar melompat memulai adopsi dari beberapa alur kerja utama yang saya coba distribusikan di perusahaan kami!

Clickinaway
sumber
1
Versi ArcGIS apa yang Anda gunakan? Saya bertanya karena pada 10.1 arcpy.da.SearchCursorjauh lebih cepat dan lebih cocok untuk tugas ini daripada yang lebih tua arcpy.SearchCursor.
blah238
1
Kode validasi untuk kotak alat yang Anda tautkan berbeda dari kode validasi pada gambar yang Anda tautkan. Yang pertama memerlukan lisensi lanjutan karena menggunakan alat Frekuensi. Yang terakhir, dirinci dalam posting blog sebelumnya, tidak boleh karena hanya menggunakan fungsi busur standar seperti SearchCursor. Saya tidak punya jawaban untuk Anda tetapi jika Anda menyatukan keduanya mungkin Anda bisa mengetahuinya.
blah238
@ blah268 Ini 10.2, maaf tidak ada. Hmm, sekarang itu pengamatan yang sangat menarik. Saya akan melihat itu, tetapi saya ingin tahu: apakah saya mengerti benar bahwa validasi adalah apa yang melewati nilai sebagai daftar pilihan? pilihan ganda adalah fungsi yang saya cari. Saya akan membalas Anda, dan terima kasih banyak atas tanggapannya!
Clickinaway
1
Properti parameter alat skrip adalah tempat Anda mengatur daftar parameter dan propertinya (yang mencakup properti MultiValue). Validasi alat skrip adalah tempat alat khusus ini mengisi nilai parameter multinilai berdasarkan nilai parameter lainnya (kelas fitur dan nama bidang). Bermain-main dengannya untuk kelas fitur yang lebih besar, saya tidak akan memproduksinya. Terlalu lambat, dan juga kesalahan keluar jika Anda tidak memiliki "Timpa hasil operasi geoprocessing" dicentang di opsi Geoprocessing.
blah238
1
Saya tidak dapat mengobrol tetapi yang saya sarankan adalah mengedit pertanyaan Anda untuk merinci kebutuhan Anda, apa yang telah Anda coba, dan apa yang tidak berhasil.
blah238

Jawaban:

9

Saya pikir beberapa orang mungkin menganggap ini berharga. ESRI cukup ramah untuk membantu mengatasi hal ini dan menemukan alternatif untuk validasi yang digunakan dalam posting blog yang tidak memerlukan lisensi Tingkat Lanjut. Meskipun saya tentu harus mencari tahu beberapa item tambahan, saya tidak dapat mengambil kredit untuk kode validasi. Tetapi, tujuan membenarkan cara dan ini memenuhi syarat sebagai jawaban untuk pertanyaan saya. Ini dia:

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

Menggunakan arcpy.da.SearchCursor mengembalikan nilai dari bidang yang dipilih dengan sangat cepat mengingat jumlah catatan pencariannya (setidaknya dalam data saya). Saya dapat memulai utas baru untuk melihat apakah ada yang punya ide tentang cara menerapkan filter ke validasi berdasarkan permintaan. Saya harap ini membantu seseorang, tapi saya senang kami punya jawaban!

Clickinaway
sumber
1

Saya melakukannya dengan cara lain: menggunakan basis data terdiri dari tingkat fivel, tanpa memilih shapefile atau bidang hanya dengan memilih item dari tingkat pertama, skrip validasi menghasilkan nilai untuk tingkat kedua sesuai dengan pilihan Anda di tingkat pertama, dengan skripnya:

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."""  
Younes Idriss
sumber
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
Younes Idriss
sumber
Harap format seluruh kode Anda dengan benar.
Marcelo Villa
itu selesai, itu bekerja di 10.5.0
Younes Idriss
Sebagian dari kode Anda diformat, tetapi karena Anda dapat melihat baris-baris lain tidak ( mis . Pernyataan impor kode Anda). Gunakan { }tombol untuk memformat kode Anda dengan benar.
Marcelo Villa
terima kasih atas sarannya
Younes Idriss
Sepertinya Anda juga kehilangan definisi kelas.
Marcelo Villa