Fractionner des polygones à mi-chemin à l'aide d'ArcPy?

14

J'essaie de diviser environ 4000 polygones à leur point médian, perpendiculaire à leur axe le plus long (c'est-à-dire à travers la largeur au point médian), comme dans le diagramme ci-dessous.

entrez la description de l'image ici

Idéalement, je voudrais le faire automatiquement et éviter de diviser manuellement chaque polygone. J'ai extrait le milieu des polygones en convertissant les lignes les plus longues qui peuvent être dessinées dans chacun, j'ai juste besoin de déterminer une méthode pour dessiner une ligne de largeur à travers ce point automatiquement.

Les polygones varient dans leur largeur, et donc les outils qui divisent les polygones en définissant des lignes de largeur d'une certaine longueur ne sont pas vraiment ce que je recherche.

Des idées?

Mat
la source
tous les polygones sont-ils convexes?
AnserGIS
Oui, leur forme est plus ou moins similaire à celle illustrée dans le schéma ci-dessus.
Matt
Créez une perpendiculaire comme décrit gis.stackexchange.com/questions/201867/… Utilisez les utiliser et l'original comme entrées pour l' entité à polygoner. Cela aidera à faire près des points aux limites
FelixIP
@Matt ma réponse at-elle résolu votre problème? Si oui, pourriez-vous le marquer comme ayant répondu avec la case à cocher?
BERA

Réponses:

23

Le script ci-dessous produira une nouvelle classe d'entités de polygones divisés et les lignes utilisées pour les diviser. Une licence avancée est requise.

Les polygones seront divisés comme ceci: entrez la description de l'image ici

entrez la description de l'image ici

Utiliser le rectangle du centre de gravité de la géométrie de délimitation minimale comme point médian et réparti sur le rectangle.

import arcpy
print 'Running'
arcpy.env.workspace = r'C:\TEST.gdb'    #Change to match your data
infc = r'polygons123'                   #Change to match your data
outfc_splitlines = r'splitlines'        
outfc_splitpolygons=r'splitpolygons'    

spatial_ref = arcpy.Describe(infc).spatialReference
arcpy.CreateFeatureclass_management(out_path=arcpy.env.workspace, out_name=outfc_splitlines, geometry_type='POLYLINE',spatial_reference=spatial_ref) #Creates a new feature class to hold the split lines

with arcpy.da.SearchCursor(infc,['SHAPE@','SHAPE@X','SHAPE@Y']) as cursor: #For each input polygon create a minimum bounding rectangle
    for row in cursor:
        arcpy.MinimumBoundingGeometry_management(row[0],r'in_memory\bounding','RECTANGLE_BY_WIDTH')
        arcpy.SplitLine_management(r'in_memory\bounding', r'in_memory\splitline') #Split the rectangle into four lines, one for each side
        linelist=[]
        with arcpy.da.SearchCursor(r'in_memory\splitline',['SHAPE@LENGTH','SHAPE@']) as cursor2:
            for row2 in cursor2:
                linelist.append(row2) #Store the lines lenghts and geometries in a list
            linelist=sorted(linelist,key=lambda x: x[0]) #Sort shortest to longest (the two shortest sides of the rectangles come first and second in list)
        arcpy.CopyFeatures_management(in_features=linelist[0][1], out_feature_class=r'in_memory\templine') #Copy the first line to memory
        with arcpy.da.UpdateCursor(r'in_memory\templine',['SHAPE@X','SHAPE@Y']) as cursor3:
            for row3 in cursor3:
                newcentroidx=row[1] #Find x coord of bounding rectangle centroid
                newcentroidy=row[2] #Find y..
                row3[0]=newcentroidx #Assign this to the shortest line
                row3[1]=newcentroidy #Assign this to the shortest line
                cursor3.updateRow(row3) #Move the line to the centroid of bounding rectangle
        arcpy.Append_management(inputs=r'in_memory\templine', target=outfc_splitlines) #Save this line in splitline feature class
#After all split lines are created convert input polygons to lines, merge with split lines and create new polygons from lines.

arcpy.FeatureToLine_management(in_features=infc, out_feature_class=r'in_memory\polytemp')
arcpy.Merge_management(inputs=[r'in_memory\polytemp',outfc_splitlines], output=r'in_memory\templines')
arcpy.FeatureToPolygon_management(in_features=r'in_memory\templines', out_feature_class=outfc_splitpolygons)
print 'Done'

entrez la description de l'image ici

Les attributs seront perdus mais vous pouvez utiliser la jointure spatiale pour les ajouter à nouveau.

BERA
la source
6
Excellente solution. Je pense qu'il convient de noter que la licence Advanced est requise pour effectuer cette opération (splitline, featureToLine et featureToPolygon). De plus, je pense que l'ajout de commentaires dans votre code aidera les nouveaux utilisateurs de python à comprendre ce que fait chaque ligne.
Fezter
Salut @BERA, désolé pour la réponse lente. Le script ne semble pas fonctionner, produisant l'erreur suivante: ERREUR 000466: in_memory \ templine ne correspond pas au schéma des lignes de séparation cibles Échec de l'exécution (ajout).
Matt
1
Essayez de changer la ligne d'ajout en: arcpy.Append_management (inputs = r'in_memory \ templine ', target = outfc_splitlines, schema_type =' NO_TEST ')
BERA
Semble obtenir une autre erreur, cette fois: Erreur d'analyse IndentationError: unindent ne correspond à aucun niveau d'indentation externe (ligne 28)
Matt
Vous devez avoir 8 espaces avant l'arcpy.Append_manag ...
BERA