Extraire le nombre de sommets dans chaque polygone?

14

J'ai ArcGIS Desktop 10.2 et mon défi est de savoir comment extraire le nombre de sommets dans chaque polygone pour toutes les fonctionnalités comme ceci:

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

J'ai plusieurs parcelles dans ma classe d'entités et je souhaite extraire le nombre de sommets pour toutes les entités séparément, puis je veux afficher les coordonnées XY pour tous les sommets.

pour plus d'informations, je veux juste convertir les sommets pour chaque polygone et afficher le nombre de chaque sommet à partir de 1 nombre, donc si j'ai un polygone et qu'il a 4 sommets, je veux convertir le polygone en sommets i afficher le nombre de sommets comme celui-ci (1,2,3,4,5), puis affichant xy pour chaque sommet, je pense que le véritable défi est de savoir comment convertir tous les polygones en sommets et créer chaque nombre de sommets à partir d'un nombre.

GIS Man
la source
Selon votre modification, voulez-vous que chaque entité ait un ID unique (1 .... n) par entité et des coordonnées XY? Préféreriez-vous qu'une colonne / champ contienne toutes ces informations à des fins d'étiquetage, par exemple [1, 942744.1234, 924654.1234] [2, 952744.1234, 925654.1234] ...?
Aaron
ouais, sinon erreur, un déposé a un ID pour le nombre de sommets de chaque polygone comme ceci (1,2,3,4), (1,2,3,4,5), (1,2,3,4, 5,6,), (1,2,3,4,5,6,7,8,9) etc., alors je pense que xy peut être facile si nous appelons l'outil add xy de arctoolbox
GIS Man

Réponses:

5

Le code ci-dessous combine les autres réponses et ajoute un peu pour numéroter les sommets. résultats

import arcpy
arcpy.env.workspace = "in_memory"
#paths
fc = r"...\polygons"
fc_out = r"...\vertices"
arcpy.MakeFeatureLayer_management(fc, "lyr")
# add fields if needed
for FIELD in ["DRAW_ORDER", "COUNT"]:
    if FIELD not in [field.name for field in arcpy.ListFields(fc)]:
        try:
            arcpy.AddField_management("lyr", FIELD, "SHORT")
        except Exception as e:
            print e
# get the number of points minus overlapping (@dmahr - GSE)
arcpy.CalculateField_management("lyr", "COUNT", "!Shape!.pointCount-!Shape!.partCount", "PYTHON")
# dict to iterate and check count
OIDS = {}
for row in arcpy.da.SearchCursor("lyr", ["OBJECTID", "COUNT"]):
    OIDS[row[0]] = row[1]
del row
# get vertices as points and add XY (@Aaron - GSE)
arcpy.FeatureVerticesToPoints_management("lyr", fc_out)
arcpy.AddXY_management(fc_out)
# start adding a number to the points
for OID in OIDS:
    order_count = 1
    rows = arcpy.da.UpdateCursor(fc_out, ["DRAW_ORDER", "COUNT"], "ORIG_FID = %d"%OID)
    for row in rows:
        # will leave the overlapping as NULL
        if order_count <= OIDS[OID]:
            row[0] = order_count
            rows.updateRow(row)
            order_count += 1
##        # this can set the overlapping to 0 or some unique value (999)
##        else:
##            row[0] = 0
##            rows.updateRow(row)

Les points sont étiquetés dans l'ordre de dessin. Le dernier point (sous le premier) n'aura pas d'étiquette et peut être supprimé en sélectionnant tous les points qui ont des valeurs NULL ou uniques, "DRAW_ORDER" s'ils ne sont pas nécessaires pour la reconstruction. Une requête de définition peut être utilisée pour supprimer les points qui se chevauchent de l'affichage.

Les données XY sont présentes, mais je laisserai cela à vos désirs d'étiquetage / d'affichage. Voir la réponse d'Aaron sur l'ajout d'un champ XY pour l'étiquetage.

Je jouais également avec FeatureClass sur un tableau numpy, mais j'ai terminé cela en premier.

gm70560
la source
merci @ gm70560, j'ai suivi vos variables de code et l'enregistrez sous .py, mais quand je veux l'exécuter, un message d'erreur apparaît, "Le nom de champ spécifié n'existe pas dans la table", alors que puis-je faire ?
GIS Man
voici un écran d'impression depuis mon PC, je viens de définir le chemin de la classe d' entités
GIS Man
Il n'a pas ajouté le champ (?). Que s'est-il passé plus haut dans les résultats? J'ai une salle de chat pour vider les résultats complets. Laisser un commentaire pour que je puisse vérifier la chambre.
gm70560
22

La façon la plus simple de procéder consiste à ajouter un nouveau champ entier à la table attributaire de la couche parcelles. Ensuite, exécutez la calculatrice de champ avec l'expression suivante:

!Shape!.pointCount-!Shape!.partCount

Le !Shape!.pointCountrenvoie le nombre total de sommets dans l'entité. Cependant, le premier sommet de chaque pièce est répété à la fin, afin de fermer l'entité. Pour gérer cela, soustrayez un sommet pour chaque pièce à l'aide -!Shape!.partCount.

Notez que vous devrez utiliser l'analyseur Python pour que cette expression fonctionne.

Calculatrice de terrain

dmahr
la source
c'est vraiment assez cool, mais ne fournira pas le XY pour chacun de ces sommets. Il semble que la réponse serait d'utiliser les deux réponses (c'est-à-dire aussi @ Aaron's) pour obtenir toutes les informations demandées.
Roland
@Roland Vous avez raison ... J'ai raté la partie de la question sur les sommets XY. Dans ce cas, vous devrez utiliser la SearchCursorméthode dans la réponse d'Aaron ou un outil de géotraitement comme Feature Vertices To Points (bien que cet outil nécessite une licence ArcGIS for Desktop Advanced).
dmahr
merci beaucoup @dmahr, je pense qu'il manque une étape, lorsque je calcule la valeur, le résultat est le nombre de sommets, donc si j'ai une classe d'entités parcellaires avec 5 sommets, je veux l'afficher comme ceci 1,2,3 , 4,5 sur chaque sommet, ne comptez pas tous les sommets dans un seul numéro, le vrai défi, comment afficher le numéro pour chaque sommet à partir de 1 numéro pour chaque parcelle.
GIS Man
12

dmahr a fourni une bonne solution pour compter les sommets. Pour une manière non programmatique d'étiqueter chaque point avec les coordonnées XY, essayez le workflow suivant:

  1. Sommets d'entités aux points
  2. Ajoutez deux nouveaux champs (type: double) dans le nouveau point FC "X", "Y"
  3. Calculez la géométrie. Champ de clic droit> Calculer la géométrie ...> Coordonnée X du point (répéter pour le champ Y)
  4. Ajoutez un autre champ "XY" (type: Texte)
  5. Calculez le champ "XY" dans la calculatrice de champ, où XY =

    str (! x!) + "," + str (! y!)

  6. Caractéristiques des étiquettes. Calque de clic droit> Etiquettes> Champ d'étiquette: XY

Cela produit les résultats suivants:

entrez la description de l'image ici

Vous pouvez également effectuer ces actions par programmation à l'aide explode_to_pointsd'un curseur de recherche (comme début).

Déconstruisez une entité en ses points ou sommets individuels. Si explode_to_points est défini sur True, une entité multipoint avec cinq points, par exemple, est représentée par cinq lignes.

(La valeur par défaut est False)

arcpy.da.SearchCursor (in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})
Aaron
la source
semble qu'il faudrait un post-traitement ou utiliser la réponse de @ dmahr pour obtenir une sommation par fonctionnalité de # de sommets.
Roland
4

Si l'on ne veut pas calculer un nouveau champ et que l'on veut juste récupérer un certain nombre de sommets par couche très rapidement (à des fins de généralisation, par exemple lors de l'exposition des ensembles de données sur le Web), il est possible de créer un outil de script personnalisé à l'intérieur d'un boîte à outils ou exposer le code en tant que complément Python.

Code d'outil de script personnalisé:

import arcpy
in_fc = arcpy.GetParameterAsText(0)

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])
arcpy.AddMessage("***************************************")
arcpy.AddMessage("Number of vertices in the layer: {0}".format(count_vertices))
arcpy.AddMessage("***************************************")

Code complémentaire Python (sélectionnez une couche dans la table des matières pour compter les sommets):

import arcpy
import pythonaddins

arcpy.env.overwriteOutput = True
mxd = arcpy.mapping.MapDocument("current")
in_fc = pythonaddins.GetSelectedTOCLayerOrDataFrame()

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])

pythonaddins.MessageBox(count_vertices, 'Number of vertices in {0}'.format(in_fc.name), 0)
Alex Tereshenkov
la source