Generowanie listy wyboru wielowartościowego w ArcGIS przy użyciu narzędzia sprawdzania poprawności bez użycia częstotliwości?

11

Próbuję dostosować kombinację modelu i skryptu znalezioną na stronie blogu ESRI zatytułowanej „Generowanie listy wyboru wielu wartości”.

Doszedłem jednak do wniosku, że część sprawdzania poprawności zastosowana we wbudowanym skrypcie zależy od narzędzia „Częstotliwość” w celu poprawnego działania, ale jest ona dostępna tylko z licencją Advanced i lame. Wpis na blogu wyjaśnia przepływ pracy oraz miejsce pobrania modeli i skryptów (ale chętnie opublikuję je tutaj na żądanie). O ile mi wiadomo, rdzeń funkcjonalności, której szukam, generuje listę opcji wielowartościowych:

wprowadź opis zdjęcia tutaj

.. jest uzależniony od poprawnego działania skryptu sprawdzania poprawności. Bez sprawdzania poprawności nie mogę uzyskać wartości z pola, które pojawią się jako lista. Czy jest coś, co mogę usunąć ze skryptu sprawdzania poprawności, aby uzyskać funkcjonalność, której szukam, czy jest to obejście? Nie znam procesu walidacji. Oto kod do sprawdzania poprawności (miałem zamiar opublikować jako próbkę kodu, ale wygląda na to, że łatwiejsze do naśladowania): wprowadź opis zdjęcia tutaj

[ Uwaga edytora: tutaj jest aktualny kod weryfikacyjny, obraz jest niepoprawny]

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

Czy to możliwe, że moje założenie (poprzez testowanie), że sprawdzanie poprawności jest kluczowym elementem, jest fałszywe i że coś innego nie pozwala na ujawnienie wartości jako listy do wyboru? Z góry bardzo dziękuję. Posiadanie tego rodzaju funkcjonalności naprawdę przyspieszy przyjęcie kilku kluczowych przepływów pracy, które próbuję rozpowszechnić w naszej firmie!

Clickinaway
źródło
1
Jakiej wersji ArcGIS używasz? Pytam, bo o 10.1 arcpy.da.SearchCursorjest znacznie szybszy i bardziej odpowiedni do tego zadania niż starsze arcpy.SearchCursor.
blah238
1
Kod weryfikacyjny dla połączonego zestawu narzędzi różni się od kodu weryfikacyjnego na połączonym obrazie. Ten pierwszy wymaga licencji zaawansowanej, ponieważ korzysta z narzędzia Częstotliwość. Ten ostatni, szczegółowo opisany we wcześniejszym poście na blogu, nie powinien, ponieważ wykorzystuje tylko standardowe funkcje Arcpy, takie jak SearchCursor. Nie mam dla ciebie odpowiedzi, ale jeśli poskładasz je razem, być może uda ci się to rozgryźć.
blah238
@ blah268 Jest 10.2, przepraszam, że tego przegapiłem. Hmm, teraz to bardzo interesująca obserwacja. Przyjrzę się temu, ale jestem ciekawy: czy dobrze rozumiem, że walidacja przekazuje wartości jako listę wyboru? opcja wielokrotnego wyboru jest funkcją, której szukam. Wrócę do ciebie i wielkie dzięki za odpowiedź!
Clickinaway
1
Właściwości parametru narzędzia skryptowego służą do ustawiania listy parametrów i ich właściwości (w tym właściwości MultiValue). Sprawdzanie poprawności narzędzia skryptowego polega na tym, że to konkretne narzędzie wypełnia wartości parametrów wielowartościowych w oparciu o inne wartości parametrów (klasa obiektów i nazwa pola). Bawiłem się nim w przypadku większych klas filmów, nie chciałbym tego produkować. Zbyt wolno, a także błędy, jeśli nie masz zaznaczonej opcji „Zastąp wyniki operacji geoprzetwarzania” w opcjach geoprzetwarzania.
blah238
1
Nie mogę czatować, ale proponuję edytować twoje pytanie, aby szczegółowo opisać twoje wymagania, co próbowałeś, a co nie działa.
blah238

Odpowiedzi:

9

Myślałem, że niektórzy ludzie mogą uznać to za cenne. ESRI był na tyle uprzejmy, aby pomóc sobie z tym poradzić i znaleźć alternatywę dla sprawdzania poprawności zastosowanej w poście na blogu, która nie wymaga licencji Advanced. Chociaż z pewnością musiałem wymyślić kilka dodatkowych elementów, nie mogę liczyć na kod weryfikacyjny. Ale cele uzasadniają środki, co stanowi odpowiedź na moje pytanie. Proszę bardzo:

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

Korzystanie z arcpy.da.SearchCursor bardzo szybko zwraca wartości z wybranego pola, biorąc pod uwagę liczbę rekordów wyszukiwania (przynajmniej w moich danych). Mogę rozpocząć nowy wątek, aby sprawdzić, czy ktoś ma jakieś pomysły na temat zastosowania filtru do sprawdzania poprawności na podstawie zapytania. Mam nadzieję, że to komuś pomoże, ale cieszę się, że mamy odpowiedź!

Clickinaway
źródło
1

Zrobiłem to w inny sposób: używając bazy danych składającej się z pięciu poziomów, bez wybierania pliku kształtu lub pól, po prostu wybierając elementy z pierwszego poziomu, skrypt sprawdzania poprawności generuje wartości dla drugiego poziomu zgodnie z twoim wyborem na pierwszym poziomie, to jej skrypt:

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
źródło
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
źródło
Proszę poprawnie sformatować cały kod.
Marcelo Villa-Piñeros
zostało zrobione, działa w 10.5.0
Younes Idriss
Część kodu jest sformatowana, ale jak widać inne wiersze nie są ( np . Instrukcje importu kodu). Użyj { }przycisku, aby poprawnie sformatować kod.
Marcelo Villa-Piñeros
Wygląda również na to, że brakuje Ci definicji klasy.
Marcelo Villa-Piñeros