Effectuer plusieurs calculs dans la table d'attributs ArcGIS?

8

J'ai une feuille de calcul Excel existante développée pour suivre les données spécifiques des bornes d'incendie, elle est périodiquement mise à jour et jointe aux données spatiales des bornes d'incendie dans ArcGIS. Dans la feuille de calcul, il existe un certain nombre de colonnes pour saisir des données relatives à la pression statique, à la pression résiduelle et au débit.

entrez la description de l'image ici

En utilisant la capacité nominale à 20 PSI dans une formule de test de débit d'incendie pour calculer le débit d'incendie, le tableur calcule automatiquement. Le calcul est le suivant.

Fire Flow = Flow * ((Static - 20)/(Static - Residual))^0.54

Je ne suis pas sûr de la meilleure façon d'attaquer cela et je recherche des suggestions. Sur la base des résultats du calcul, j'ai une colonne supplémentaire avec une déclaration IF qui indique la couleur appropriée du flux d'incendie à laquelle la borne devrait être peinte. Pour ceux qui ne le savent pas, la couleur de la bouche d'incendie est un indicateur pour incendier le personnel en cas d'urgence les conditions d'écoulement du feu. J'ai fait quelques recherches et développé le script python suivant:

def Reclass !Bon_Color!:
     if ( !Fire_Flow! <= 0):
       return Black
     elif ( !Fire_Flow! >= 1 and !Fire_Flow! <= 499):
       return  Red
     elif ([Fire_Flow] > 499 and [Fire_Flow] <= 999):
       return Orange
     elif ( !Fire_Flow! > 999 and !Fire_Flow! <= 1499):
         return Green
     elif ( !Fire_Flow! > 1499):
         return Blue
  end if

Je voudrais savoir si les calculs mentionnés ci-dessus, utilisés dans la feuille de calcul Excel, pourraient être répliqués dans la table attributaire de la base de données en utilisant la calculatrice de champ et l'analyseur python? Plutôt que de se fier à la feuille de calcul Excel et à la nécessité de rejoindre les données.

LandArch
la source
5
Ils le peuvent, mais il s'agit plus d'une question SQL que d'une question SIG.
Dan C
Leur seconde moitié peut être effectuée via Field Calculator, je n'ai qu'à obtenir le bon codage Python.
LandArch
S'il s'agit d'une question sur ArcGIS Field Calculator et son analyseur Python, je pense que vous devriez le modifier pour que cela soit clair et éviter qu'il ne soit fermé pour être trop large (en posant deux questions).
PolyGeo
Je pense que vous aurez plus de facilité avec cela si vous le faites à l'arrière-plan, dans la base de données SQL qui stocke les fonctionnalités. Vous pouvez configurer une requête de mise à jour pour qu'elle s'exécute quotidiennement ou quelque soit la fréquence pour calculer ces valeurs et vous n'avez pas à y repenser. Vous pouvez également le créer en tant que «colonne calculée», qui sera automatiquement remplie avec les valeurs correctes lorsque vous éditez le calque. Parlez à votre administrateur db.
Dan C
@Dan CI n'est pas en désaccord avec vous. Malheureusement, nous n'avons pas d'administrateur de base de données. Je suppose que je le suis. J'ai trouvé suffisamment de choses pour configurer PostgreSQL afin que nous puissions utiliser les données sur le terrain dans l'application ARCGIS Collector sur une tablette. Je pense que Python et la calculatrice de champ peuvent être ma meilleure option uniquement pour que j'apprenne quelque chose que je pourrai utiliser plus tard.
LandArch

Réponses:

4

Votre code python est logique mais contient quelques erreurs. Collez-le dans la case "Code de script pré-logique" dans la calculatrice de champ:

def Reclass (fire_flow):
     if (fire_flow <= 0):
       return "Black"
     elif (fire_flow >= 1 and fire_flow <= 499):
       return "Red"
     elif (fire_flow > 499 and fire_flow <= 999):
       return "Orange"
     elif (fire_flow > 999 and fire_flow <= 1499):
       return "Green"
     elif (fire_flow > 1499):
       return "Blue"

Ensuite, dans la case en dessous, collez:

Reclass (!Fire_Flow!)

L'indentation dans ce bloc supérieur est un peu inhabituelle, mais la quantité exacte d'indentation n'a pas d'importance tant que les lignes sont correctement indentées les unes par rapport aux autres.

Les erreurs:

def Reclass !Bon_Color!:

Lorsque vous définissez une fonction, vous devez la suivre avec une liste de paramètres que la fonction utilise pour effectuer son travail. La liste doit être entre parenthèses. Dans votre cas, vous n'utilisez qu'un seul paramètre d'entrée, votre numéro Fire_Flow.

if ( !Fire_Flow! <= 0):
   return Black

Vous allez passer !Fire_Flow!dans la fonction, une fois que vous êtes dans la fonction, cette valeur est affectée à la variable fire_flow, alors faites plutôt référence à cette variable. De plus, vous devez mettre des Blackguillemets, donc une chaîne est retournée. De la façon dont vous l'avez ici, votre script recherche une variable nommée Blackà renvoyer, et elle n'existe pas.

end if

Vous n'avez pas besoin de terminer si vous êtes en Python.

Pour votre premier champ, le numéro de flux d'incendie, vous devez nommer vos champs de manière appropriée et l'opérateur des exposants en Python n'est **pas. ^Collez-le dans la case du bas de la calculatrice de champ:

!Fire_Flow! = !Flow! * ((!Static! - 20)/(!Static! - !Residual!))**0.54

Si vous devez mettre à jour plusieurs champs simultanément, je suis d'accord avec MacroZED qu'un curseur de mise à jour est la meilleure façon, mais ceux-ci peuvent être un peu déroutants si vous êtes nouveau sur Python.

Dan C
la source
Merci, cela a fonctionné pour calculer la couleur du capot, des réflexions sur le calcul de l'autre partie du si?
LandArch
@LandArch Désolé, je pensais que la question disait que cette partie avait été prise en charge. Je vais ajouter ça.
Dan C
2

Cela peut certainement être fait dans ArcGIS sans avoir besoin d'exceller. Si ces champs (pression statique, pression résiduelle et débit) sont déjà dans un ensemble de données, nous pouvons utiliser les curseurs suivants pour ajouter les nouveaux champs et les mettre à jour:

import arcpy

ds = r"path/to/dataset"    

with arcpy.da.UpdateCursor(ds, ["Fire_Flow", "Colour"]) as ucursor:
    with arcpy.da.SearchCursor(ds, ["Static", "Residual", "Flow", "Fire_Flow"]) as scursor:
        for urow in ucursor:
             for srow in scursor:
                 urow[0] = "{}" * (("{}"-20)/("{}"-"{}"))**0.54.format(srow[2], srow[0], srow[0], srow[1])
                 ucursor.updateRow(urow)
                 if srow[3] <= 0:
                     urow[1] = "Black"
                     if srow[3] >= 1 and srow[3] <= 499:
                         urow[1] = "Red"
                         if srow[3] > 499 and srow[3] <= 999:
                             urow[1] = "Orange"
                             if srow[3] > 999 and srow[3] <= 1499:
                                 urow[1] = "Green"
                                 if srow[3] > 1499:
                                     urow[1] = "Blue"
                                     ucursor.updateRow(urow)
MacroZED
la source
Je ne veux pas ajouter les colonnes, je veux juste mettre à jour ensuite lorsque le test de statique, résiduel et de flux est effectué et que le nombre est ajouté.
LandArch
pas de problème, vous pouvez simplement supprimer cela. mal éditer le script pour refléter cela. Le script devra être réexécuté à chaque fois que les valeurs Static, Residual ou Flow changeront. Mais cette méthode sera plus rapide que le champ Calculer.
MacroZED
J'obtiens l'erreur suivante, le [#] doit-il être modifié car il ne s'agit pas des lignes 1 à 3 dans la table attributaire? Erreur d'exécution Traceback (dernier appel le plus récent): Fichier "<string>", ligne 5, dans <module> RuntimeError: impossible d'ouvrir 'path / to / dataset'
LandArch
Non, l'erreur est due au fait que vous n'avez pas spécifié l'ensemble de données. La variable "ds" doit être remplacée par votre ensemble de données réel.
MacroZED
Désolé pour la tenue de la main, je dois inclure le chemin physique, par exemple C: / ....
LandArch