Jak ludzie używają struktur danych i klas Python w ArcPy?

16

To pytanie może ujawnić moją niewiedzę na temat programowania, ale jestem ciekawy, w jaki sposób ludzie używają różnych struktur danych Pythona w ArcPy.

Ta strona zawiera listę struktur danych w Pythonie. Rozumiem, w jaki sposób listy mogą być implementowane w GIS (lista klas elementów, lista typów elementów, lista ramek danych itp.). Rozumiem, w jaki sposób można również używać zestawów (do usuwania duplikatów). W jaki sposób ludzie wdrażają krotki, słowniki i inne struktury danych w ArcPy? Czy są też inne przykłady list i zestawów, których nie wymieniłem?

Ponadto bez wątpienia ludzie tworzą niestandardowe klasy w ArcPy. W jakich okolicznościach i sytuacjach tego potrzebujesz? Czy możesz podać przykłady? Czy ktoś tworzy niestandardowe klasy, które dziedziczą po wbudowanych klasach arcpy?

Nie wymagam odpowiedzi na wszystkie te pytania, jestem tylko ciekawy, jak ludzie używają Pythona w GIS i jakie przepływy pracy wymagają tych dostosowań.

Fezter
źródło
4
Ciekawe pytanie, ale nie ma ostatecznej odpowiedzi. Powinna być wiki społeczności.
RK

Odpowiedzi:

14

Wiele funkcji arcpy, które przyjmują wiele danych wejściowych, akceptuje obiekty listy Python.

Na przykład Dissolve_managementfunkcja akceptuje listę nazw pól do rozpuszczenia:

arcpy.Dissolve_management("taxlots", "C:/output/output.gdb/taxlots_dissolved",
    ["LANDUSE", "TAXCODE"], "", "SINGLE_PART", "DISSOLVE_LINES")

Krotki można użyć zamiast listy, gdy nie trzeba modyfikować kolejności ani liczby elementów, ponieważ krotki są niezmienne . Są one użyteczną strukturą danych dla heterogenicznych, ale powiązanych fragmentów danych, takich jak elementy znacznika czasu lub współrzędne punktu. Często widzisz listy krotek, w których krotka służy jako odrębny rekord ze stałą liczbą atrybutów, podczas gdy lista może łatwo zmienić rozmiar, zostać ponownie uporządkowana (posortowana) itp. Zobacz to pytanie StackOverflow, aby uzyskać więcej informacji na temat zastosowań list a krotki.

Słownik może być używany jako tabela szybkiego wyszukiwania do buforowania stosunkowo niewielkiego, ale często używanego zestawu par klucz-wartość w pamięci. Ciekawy przykład tego widziałem na forach ArcGIS: http://forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

Używanie słownika zamiast łączenia przyspieszyło ich obliczenia z 3,5 godziny do 15 minut.

Prostszym przykładem może być, jeśli masz milion rekordów adresów z atrybutem o skróconej nazwie stanu (CA), ale do celów wyświetlania chcesz przeliterować prawidłową nazwę (Kalifornia), możesz użyć tego słownika jako tabeli odnośników, gdy wypełnianie pełnego pola nazwy stanu.

Nie znalazłem potrzeby pisania klasy w Pythonie do użytku w Arcpy, ale to nie znaczy, że nie ma takiego przypadku użycia. Klasa może być przydatna, gdy masz zestaw ściśle powiązanych funkcji (zachowań), które działają na niektórych danych wejściowych (danych) i chcesz mieć możliwość korzystania z tych danych i zachowań w sposób obiektowy, ale jest to bardziej prawdopodobnie będzie to specyficzne dla logiki biznesowej i niezwiązane z arkami.

rev blah238
źródło
7

Blah238 dobrze omawia ten temat, więc dodam tylko kilka przykładów z mojej własnej pracy. Opracowuję wiele danych na lotniskach, a jedną z rzeczy, które muszę regularnie robić, jest czytanie w kolejności wzdłuż badanych punktów linii centralnej drogi startowej od pasa startowego. Można by pomyśleć, że te punkty byłyby już w porządku (w bazie danych GIS), ale rzadko są. Punkty linii środkowej pojawiają się co 10 stóp wzdłuż linii środkowej i są otoczone po obu stronach dwoma innymi rzędami punktów pomiarowych rozmieszczonych w odległości 10 stóp od siebie. Otrzymujesz obraz: mnóstwo punktów ... i zazwyczaj wszystkie są połączone razem w oparciu o bazę danych. Z tym, co robię w moich skryptach, zwykle najłatwiej jest po prostu wybrać punkty linii środkowej według atrybutów (lub przestrzennie, jeśli to konieczne), odczytać współrzędne dla każdego z nich i zrzucić wyniki na listę Pythona. Następnie mogę sortować, pop, odwracać itp.

Podobnie, korzystam ze słowników Python w szerokim zakresie (prawdopodobnie znacznie więcej niż niektórzy by to zaakceptowali). Muszę tworzyć zestawy wektorów jednostek 3D dla każdego końca pasa startowego na lotnisku i mam stały dostęp do nich w ramach skryptu i robię to w wielu moich skryptach. W innych słownikach przechowuję także wiele innych zestawów regularnie używanych danych. Podobnie jak listy, są szybkie i elastyczne. Wysoce polecany.

Jeśli chodzi o klasy, tak jak Blah238, nie znalazłem potrzeby tworzenia żadnych. Prawdopodobnie w moich skryptach preferowana jest klasa, ale tak naprawdę nie byłem w stanie zidentyfikować tych miejsc. Ktoś z większym doświadczeniem programistycznym prawdopodobnie szybko je znajdzie.

flet celtycki
źródło
5

Ja też uwielbiam słowniki - używaj ich cały czas. Ta metoda pobiera niektóre właściwości odniesień przestrzennych i przechowuje wszystko w dict:

def get_coord_sys(self, in_dataset):
    """Get and return info on dataset coord sys/projection"""
    spatial_ref = arcpy.Describe(in_dataset).spatialReference
    # Get spatial ref props and put in dictionary
    spat_ref_dict = {}
    spat_ref_dict["name"] = spatial_ref.name
    spat_ref_dict["type"] = spatial_ref.type
    spat_ref_dict["gcs_code"] = spatial_ref.GCSCode
    spat_ref_dict["gcs_name"] = spatial_ref.GCSName
    spat_ref_dict["pcs_code"] = spatial_ref.PCSCode
    spat_ref_dict["pcs_name"] = spatial_ref.PCSName
    return spat_ref_dict

Ten fragment kodu wyodrębnia geometrie punktów z dwóch klas obiektów, a następnie używam geometrii później, aby wykonać trygonometr:

def build_fields_of_view(self):
        """For all KOPs in a study area, build left, right, center FoV triangles"""
        try:    
            fcs = {os.path.join(self.gdb, "WindFarmArray"):[], os.path.join(self.gdb, "KOPs"):[]}
            # Build a dict of WTG and KOP array geometries, looks like:
            #  {'KOPs': [[1, -10049.2697098718, 10856.699451165374], 
            #            [2, 6690.4377855260946, 15602.12386816188]], 
            #   'WindFarmArray': [[1, 5834.9321158060666, 7909.3822339441513], 
            #                     [2, 6111.1759513214511, 7316.9684107396561]]}
            for k, v in fcs.iteritems():
                rows = arcpy.SearchCursor(k, "", self.sr)
                for row in rows:
                    geom = row.shape
                    point = geom.getPart()
                    id = row.getValue("OBJECTID")
                    v.append([id, point.X, point.Y])   

            kops = fcs[os.path.join(self.gdb, "KOPs")] # KOP array
            wtgs = fcs[os.path.join(self.gdb, "WindFarmArray")] # WTG array

DUŻO tego, nad czym obecnie pracuję, polega na wyodrębnieniu współrzędnych i atrybutów z klas obiektów wektorowych i rastrów, aby dane mogły zostać przekazane do innego oprogramowania, które nawet nie wie, jakie są dane GIS. Często używam do tego list i słowników.

Chad Cooper
źródło
Dziękuję za odpowiedź. Dlaczego w takich przypadkach słownik jest lepszym wyborem niż inna struktura danych?
Fezter
Po prostu lubię mieć możliwość wywoływania moich wartości za pomocą klawiszy.
Chad Cooper
2
innym powodem, dla którego dyktanda mogą być preferowane, jest to, że są one czytane znacznie szybciej niż listy, ponieważ nie są uporządkowane. dlatego bardzo długie listy mogą zająć trochę więcej czasu, jeśli zawierają wiele wpisów.
ndimhypervol
@gotanuki Prawda, a jeśli potrzebujesz użyć dużej listy, użyj krotki, ponieważ są one również szybsze niż listy.
Chad Cooper
2

Przeczytaj to , przygotowując odpowiedź i musiałem wprowadzić pewne zmiany.

Nie jestem ekspertem w Pythonie, ale myślę, że pomysł za pomocą klas polega na tym, że możesz utworzyć instancję obiektu, który ma wiele gotowych metod, które dotyczą struktury danych, a także centralizacji metod. Istnieją również pewne zalety zakresu zmiennego w porównaniu z klasami i modułami, powyższe łącze nieco do tego prowadzi.

Mam klasę o nazwie featureLayer (prawdopodobnie nie nazywa się pythonowo ... wciąż się uczy). mogę zrobić

sys.path.append(r"\\Path\To\Scripts")
import gpFuncs as gpF
fc = arcpy.GetParameterAsText(0)
featureLayer = gpF.featureLayer(fc)
points = featureLayer.featureVerticesToPoints(featureid, "", first_and_last)

Definicja, aby to zrobić, jest metodą klasową, która po prostu iteruje operacje, części i wierzchołki. Następnie mogę zmienić obiekt point w instancję featureLayer i robić inne rzeczy, które ma moja klasa.

Myślę, że jeśli poprawnie zbudowane, klasy powinny unieważnić funkcjonalność. Na przykład wkrótce zacznę refaktoryzację, dzięki czemu będę mieć klasę featureLayer, która ma metody i atrybuty, które mają wszystkie warstwy cech. Następnie odziedzicz po nim, aby zbudować instancję klasy featureLayerStrict, która odziedziczy wszystkie atrybuty / metody featureLayers, ale utworzy instancję z określonym typem geometrii, takim jak wielokąt.

Justin
źródło
4
Zapoznaj się z przewodnikiem po stylu Python (znanym również jako PEP 8), aby uzyskać konwencje nazewnictwa.
blah238,
0

Pracuję głównie w VB .net, ale coraz częściej używam Pythona i Arcpy. W VB lubię i próbuję używać Enums, ponieważ sprawia, że ​​czytanie kodu jest jaśniejsze. Wcześniejsze wersje Pythona nie implementowały Enums, więc hack miał na celu stworzenie klasy ujawniającej pewne właściwości, kilka przykładów omówiono na temat przepełnienia stosu . Teraz wygląda na to, że najnowsza wersja Pythona implementuje te, które zostały omówione tutaj .

Hornbydd
źródło