Obtention de l'étendue de chaque polygone dans le fichier de formes à l'aide d'ArcPy?

20

Dans ArcGIS 10 et Python, je veux obtenir les informations d'étendue (xmax, ymax, xmin, ymin) de chacun des polygones d'un fichier de formes.

Je peux obtenir l'étendue de l'ensemble du fichier de formes en utilisant

file=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
desc=arcpy.Describe(file)
print desc.extent.Xmax

394551.52085039532

Mais je n'arrive pas à comprendre comment obtenir les mêmes informations pour chaque ligne de l'ensemble de données.

rows = arcpy.SearchCursor("100k_trc_tiles_TVM")
for row in rows:
 print row

imprime les 31 lignes de l'ensemble de données, mais

for row in rows:
 desc=arcpy.Describe(row)
 print desc.extent.Xmax

donne une erreur.

Erreur d'exécution: objet: décrire la valeur d'entrée n'est pas un type valide

Je pensais ajouter les valeurs d'étendue à la table en utilisant "calculer la géométrie" mais cela ne donne que le centroïde. Ensuite, je suppose que nous pouvons utiliser quelque chose comme row.GetValue ("xmax").

Cela étant dit, je sais que nous pouvons créer le X / Y, max / min en utilisant la fonction de http://www.ian-ko.com/free/free_arcgis.htm mais il serait préférable d'éviter de devoir ajouter , surtout si ArcPy peut obtenir ces valeurs.

Fondamentalement, je dois obtenir les étendues à alimenter dans l'outil de découpage pour découper 30 zones de données (selon les feuilles de carte au 1: 100 000) pour le géotraitement car l'outil de fractionnement échoue en raison de la grande taille du jeu de données (voir Pourquoi Intersect donne ERREUR 999999: Erreur lors de l'exécution de la fonction Topologie non valide [Trop de points de terminaison de ligne]? ). Je veux automatiser cela car il est répété sur un certain nombre d'ensembles de données.

=== script de travail ===

# Emulates Arc Info SPLIT tool by using Clip but
# Requires a FC from which each row is used as the input clip feature.
# Each row must be rectangular.
# Used on 12GB FGDB with 100 million records.


#Licence: Creative Commons
#Created by: George Corea; [email protected], [email protected]
import arcpy, string

#inFrame=arcpy.GetParameterAsText(0) # Input dataframe FC
#inFile=arcpy.GetParameterAsText(1) # Input FC for splitting
#outDir=arcpy.GetParameterAsText(2) # Output FGDB

inFrame=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
inFile=r"c:\junk\106\data\7_Merge.gdb\FullRez_m2b"
outDir=r"D:\SCRATCH\Projects\206\datasplit\test_slaasp.gdb"
#NameField="Name_1"

#arcpy.env.workspace = r"C:/Workspace"
arcpy.env.overwriteOutput = True

rows = arcpy.SearchCursor(inFrame)
shapeName = arcpy.Describe(inFrame).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    Name = row.Name_1
    print "Executing clip on: "+str(Name)
    extent = feat.extent
    #print extent.XMin,extent.YMin,extent.XMax,extent.YMax
# Create an in_memory polygon
    XMAX = extent.XMax
    XMIN = extent.XMin
    YMAX = extent.YMax
    YMIN = extent.YMin
    pnt1 = arcpy.Point(XMIN, YMIN)
    pnt2 = arcpy.Point(XMIN, YMAX)
    pnt3 = arcpy.Point(XMAX, YMAX)
    pnt4 = arcpy.Point(XMAX, YMIN)
    array = arcpy.Array()
    array.add(pnt1)
    array.add(pnt2)
    array.add(pnt3)
    array.add(pnt4)
    array.add(pnt1)
    polygon = arcpy.Polygon(array)
    ShapeFile = outDir+"\\temp_poly"
    arcpy.CopyFeatures_management(polygon, ShapeFile)

    #print Name
### Set local variables
    in_features = inFile
    clip_features = ShapeFile
    out_feature_class = outDir+"\\"+Name
    xy_tolerance = "0.22"

    # Execute Clip

    try:
        arcpy.Clip_analysis(in_features, clip_features, out_feature_class, xy_tolerance)
        print "Completed: "+str(Name)
    except:
        error = arcpy.GetMessages()
        print "Failed on: "+str(Name)+" due to "+str(error)
GeorgeC
la source
2
Vous n'avez pas besoin d'écrire la fonction de clip sur le disque, utilisez simplement le polygone en mémoire, par exemple: polygon = arcpy.Polygon (array) arcpy.Clip_analysis (in_features, polygon, out_feature_class, xy_tolerance)
user2856
tks. Une idée de la façon dont je peux exporter la ligne vers un nouveau fichier de forme afin qu'elle soit utilisée, plutôt que simplement l'étendue de la ligne? C'est pour qu'il puisse également gérer des clips non rectangulaires.
GeorgeC
1
Eh bien, si vous voulez juste découper par cette fonction, dans le même script, utilisez simplement l'objet fonction. Encore une fois, pas besoin d'exporter vers un fichier de forme, par exemple: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
user2856
Pour un fichier de formes ou pour chaque polygone d'un fichier de formes? On dirait que vous parlez de deux choses distinctes ici.
Rayner
y a-t-il un seul objet polygone dans votre fichier de formes? sinon, utilisez la boucle for pour l'étendue de vos objets.
Aragon

Réponses:

26

Obtenez l'objet forme dans votre curseur et accédez à sa propriété d'extension. Voir l'aide d'ArcGIS Utilisation de la géométrie dans Python :

shapeName = arcpy.Describe(inFeatures).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    extent = feat.extent
    print extent.XMin,extent.YMin,extent.XMax,extent.YMax
user2856
la source
1
Merci Luke. Cela a très bien fonctionné. Je modifierai ma question pour avoir le nouveau code de travail si quelqu'un veut utiliser un outil qui - Utilise le jeu d'outils Clip de manière itérative pour découper les régions rectangulaires d'une grande classe d'entités. Émule la fonctionnalité de l'outil Arc Info Split sans se bloquer avec des ensembles de données pouvant atteindre 10 Go FGDB et 100 millions d'enregistrements.
GeorgeC
Une chose - j'ai dû coder en dur le nom de la colonne pour obtenir l'équivalent de Name = row.Name_1 en essayant l'attribut name comme; NameField = "Name_1"; Name = row.NameField; ou Name = row + "." + NameField où NameField = arcpy.GetParameterAsText (2) et le nom est conservé dans la colonne Name_1. Des idées? Remarque I; ai utilisé ";" pour désigner une nouvelle ligne.
GeorgeC
1
figuré ci-dessus - row.GetValue (xxx) de gis.stackexchange.com/questions/16586/…
GeorgeC
7

Le jeu d'outils Bounding Container fait exactement ce que vous voulez. Si vous voulez juste des extraits de code, examinez les fonctions dans les scripts, on traite explicitement de l'étendue.

ÉDITER

Je dois ajouter que le script ajoutera des valeurs à un champ Gauche, Droite, Haut et Bas dans le fichier de sortie créé qui peut être utilisé pour un traitement ultérieur


la source
Merci. Va le vérifier. J'espère que je pourrai utiliser le code dans mes scripts / modèles python.
GeorgeC
2

Je viens d'essayer la géométrie de délimitation minimale (enveloppe) (dans la gestion des données) dans ArcGIS 10 et elle semble faire exactement la même chose, pour tous les champs.

Sid
la source
1

Une autre façon serait de faire un SearchCursor () sur le fichier de formes, alors vous pouvez utiliser row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...
Ruth
la source
1

Comme indiqué dans Extraction de coordonnées de sommets de polygone dans ArcMap? vous pouvez obtenir les sommets d'un polygone, puis ajouter les coordonnées x et y de chaque sommet en tant que champs dans la table attributaire. Cela a la limitation de ne pas attacher les coordonnées max / min directement à chaque polygone, mais cela peut être réalisé de plusieurs manières.

La méthode que je connais le mieux est de lire les champs x et y dans des listes python en utilisant le module pyshp , qui peut ensuite être trié pour trouver des valeurs maximales et minimales pour chaque polygone. Pyshp peut ensuite être utilisé pour ouvrir une classe d'écriture pour ajouter de nouveaux champs aux polygones d'origine et écrire ces valeurs max et min dans le polygone correct.

Je crois que cela peut être fait en utilisant l'arcpy, mais j'ai eu beaucoup de problèmes avec l'écriture dans les fichiers de formes en 9.3 en utilisant le géoprocesseur, donc je préfère la méthode pyshp, mais je ne suis pas sûr que le module arcpy ait résolu ces problèmes.

sgrieve
la source
0

Avez-vous essayé de mettre en majuscule le «M» dans «XMax»? Je pense que c'est censé être:

print desc.extent.XMax

au lieu de

print desc.extent.Xmax

selon la documentation . Bien sûr, cela me fait me demander comment votre premier extrait de code a fonctionné. Quoi qu'il en soit, essayez-le!

dmahr
la source