Comment les gens utilisent-ils les structures de données et les classes Python dans ArcPy?

16

Cette question peut révéler mon ignorance sur la programmation, mais je suis curieux de savoir comment les gens utilisent différentes structures de données python dans ArcPy.

Cette page répertorie les structures de données en Python. Je comprends comment les listes peuvent être implémentées dans SIG (liste des classes d'entités, liste des types d'entités, liste des trames de données, etc.). Je comprends également comment les ensembles peuvent être utilisés (pour supprimer les doublons). Comment les gens implémentent-ils des tuples, des dictionnaires et d'autres structures de données dans ArcPy? Existe-t-il également d'autres exemples de listes et d'ensembles que je n'ai pas répertoriés?

De plus, sans aucun doute, les gens créent des classes personnalisées dans ArcPy. Dans quelles circonstances et situations en avez-vous besoin? Pouvez-vous fournir des exemples? Est-ce que quelqu'un crée des classes personnalisées qui héritent des classes arcpy intégrées?

Je n'ai pas besoin de réponses à toutes ces questions, je suis simplement curieux de savoir comment les gens utilisent Python dans SIG et quels flux de travail nécessitent ces personnalisations.

Fezter
la source
4
Question intéressante mais qui n'a pas de réponse définitive. Devrait être un wiki communautaire.
RK

Réponses:

14

De nombreuses fonctions arcpy qui acceptent plusieurs entrées acceptent les objets de liste Python.

Par exemple, la Dissolve_managementfonction accepte une liste de noms de champs à dissoudre:

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

Un tuple peut être utilisé à la place d'une liste lorsque vous n'avez pas besoin de modifier l'ordre ou le nombre d'éléments, car les tuples sont immuables . Ils constituent une structure de données utile pour des éléments de données hétérogènes mais liés, tels que les éléments d'un horodatage ou les coordonnées d'un point. Vous verrez souvent des listes de tuples, où un tuple sert d'enregistrement distinct avec un nombre fixe d'attributs, tandis que la liste peut facilement changer de taille, être réorganisée (triée), etc. Voir cette question StackOverflow pour plus d'informations sur les utilisations de listes vs tuples.

Un dictionnaire peut être utilisé comme table de recherche rapide pour mettre en mémoire cache un ensemble relativement petit mais fréquemment utilisé de paires clé-valeur. J'ai vu un exemple intéressant de cela sur les forums ArcGIS: http://forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

Leur utilisation d'un dictionnaire au lieu d'une jointure a accéléré leur calcul de 3,5 heures à 15 minutes.

Un exemple plus simple pourrait être si vous avez un million d'enregistrements d'adresses avec un attribut avec le nom d'état abrégé (CA), mais à des fins d'affichage, vous voulez épeler le nom correct (Californie), vous pouvez utiliser ce dictionnaire comme table de recherche lorsque remplir un champ de nom d'état complet.

Je n'ai pas trouvé le besoin d'écrire une classe en Python pour une utilisation dans arcpy moi-même, mais cela ne veut pas dire qu'il n'y a pas un tel cas d'utilisation. Une classe peut être utile lorsque vous disposez d'un ensemble de fonctions (comportements) étroitement liées qui opèrent sur certaines entrées (données) et que vous souhaitez pouvoir utiliser ces données et comportements de manière orientée objet, mais c'est plus va probablement être spécifique à la logique métier et non lié à arcpy.

blah238
la source
7

Blah238 couvre bien ce sujet, donc je vais juste ajouter quelques exemples de mon propre travail. Je développe beaucoup de données sur les aéroports, et l'une des choses que je dois faire régulièrement est de lire dans l'ordre le long des points d'axe de piste étudiés à partir d'une piste. On pourrait penser que ces points seraient déjà en règle (dans la base de données SIG), mais ils le sont rarement. Les points d'axe se produisent tous les 10 pieds le long de l'axe et sont flanqués de chaque côté par deux autres rangées de points d'arpentage espacés de 10 pieds. Vous obtenez l'image: une pléthore de points ... et généralement tous mélangés dans une base de données. Avec ce que je fais dans mes scripts, il est généralement plus facile de simplement sélectionner les points d'axe par attributs (ou spatialement si nécessaire), de lire les coordonnées de chacun et de vider les résultats dans une liste Python. Je peux ensuite trier, pop, inverser, etc.

De même, j'utilise beaucoup les dictionnaires Python (probablement beaucoup plus que certains ne l'approuveraient). Je dois créer des ensembles de vecteurs d'unité 3D pour chaque extrémité de piste dans un aéroport, et j'y accède constamment dans un script et je le fais dans plusieurs de mes scripts. Je conserve également de nombreux autres ensembles de données régulièrement consultées dans les dictionnaires. Comme les listes, elles sont rapides et flexibles. Hautement recommandé.

En ce qui concerne les cours, comme Blah238, je n'ai trouvé aucun besoin d'en créer. Il y a probablement quelques cas où une classe serait préférée dans mes scripts, mais je n'ai vraiment pas pu identifier ces endroits. Quelqu'un avec plus d'expérience en programmation les trouverait probablement rapidement.

flûte celtique
la source
5

Moi aussi, j'adore les dictionnaires - utilisez-les tout le temps. Cette méthode obtient des propriétés de référence spatiale et les stocke toutes dans un 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

Cet extrait de méthode extrait des géométries de points à partir de deux classes de fonctions, j'utilise ensuite les géométries plus tard pour faire quelques trig:

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

BEAUCOUP de ce sur quoi je travaille actuellement consiste à extraire les coordonnées et les attributs des classes d'entités vectorielles et des rasters afin que les données puissent être transférées dans un autre logiciel qui ne sait même pas ce que sont les données SIG. Donc, j'utilise beaucoup de listes et de dictionnaires pour cela.

Chad Cooper
la source
Merci d'avoir répondu. Pourquoi un dictionnaire est-il un meilleur choix qu'une autre structure de données dans ces cas?
Fezter
J'aime juste pouvoir appeler mes valeurs par mes clés.
Chad Cooper
2
une autre raison pour laquelle les dict peuvent être préférables est qu'ils sont lus beaucoup plus rapidement que les listes car ils ne sont pas classés. par conséquent, les listes très longues peuvent prendre un peu plus de temps à traiter si elles contiennent de nombreuses entrées.
ndimhypervol
@gotanuki True, et si vous devez utiliser une grande liste, utilisez plutôt un tuple, car ils sont également plus rapides que les listes.
Chad Cooper
2

Lisez ceci tout en préparant une réponse et avez dû faire quelques modifications ..

Je ne suis pas un expert en Python, mais je pense que l'idée derrière l'utilisation des classes est que vous pouvez instancier un objet qui a un tas de méthodes prêtes à l'emploi qui se rapportent à la structure des données ainsi que la centralisation de vos méthodes. Il existe également des avantages à portée variable avec les classes par rapport aux modules, le lien ci-dessus y arrive quelque peu.

J'ai une classe appelée featureLayer (probablement pas nommée en python ... j'apprends toujours). Je peux faire

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)

La définition pour ce faire est une méthode de classe qui itère simplement les entités, les pièces et les sommets. Ensuite, je peux transformer mon objet points en une instance de FeatureLayer et faire d'autres choses que ma classe a.

Je pense que si les classes sont correctement construites, elles devraient désactiver la fonctionnalité. Par exemple, je vais bientôt commencer à refactoriser pour avoir une classe featureLayer qui a des méthodes et des attributs que toutes les couches d'entités ont. Héritez-en ensuite pour créer une instance de classe featureLayerStrict qui héritera de tous les attributs / méthodes de featureLayers mais qui sera instanciée avec un type de géométrie spécifique comme le polygone.

Justin
la source
4
Consultez le guide de style Python (aka PEP 8) pour les conventions de dénomination.
blah238
0

Je travaille principalement en VB .net mais je me retrouve de plus en plus à utiliser python et arcpy. En VB, j'aime et j'essaie d'utiliser Enums car cela rend la lecture du code plus claire. Les versions antérieures de python n'implémentaient pas Enums, donc un hack devait créer une classe exposant certaines propriétés, un tas d'exemples sont discutés sur Stack Overflow . Il semble maintenant que la dernière version de python implémente ceux-ci, ce qui est discuté ici .

Hornbydd
la source