Dzielenie wielokątów w punkcie środkowym za pomocą ArcPy?

14

Próbuję rozdzielić około 4000 wielokątów w ich punkcie środkowym, prostopadłym do ich najdłuższej osi (tj. Na całej szerokości w punkcie środkowym), jak na poniższym schemacie.

wprowadź opis zdjęcia tutaj

Idealnie byłoby zrobić to automatycznie i unikać ręcznego dzielenia każdego wielokąta. Wyodrębniłem punkt środkowy wielokątów, konwertując najdłuższe linie, które można narysować w każdej z nich, po prostu muszę określić metodę automatycznego rysowania linii szerokości w tym punkcie.

Wielokąty różnią się szerokością, a zatem narzędzia, które dzielą wielokąty, definiując linie szerokości o określonej długości, nie są tak naprawdę tym, czego szukam.

Jakieś pomysły?

Matt
źródło
czy wszystkie wielokąty są wypukłe?
AnserGIS
Tak, mają mniej więcej kształt podobny do pokazanego na powyższym schemacie.
Matt
Utwórz prostopadle, jak opisano gis.stackexchange.com/questions/201867/... Użyj ich i oryginalnych jako danych wejściowych dla funkcji do wielokąta. Pomoże to zbliżyć się do punktów na granicach
FelixIP
@Matt czy moja odpowiedź rozwiązała Twój problem? Jeśli tak, czy możesz zaznaczyć to pole wyboru jako odpowiedź?
BERA

Odpowiedzi:

23

Poniższy skrypt wygeneruje nową klasę elementów podzielonych wielokątów i linii używanych do ich podziału. Wymagana jest licencja zaawansowana.

Wielokąty zostaną podzielone w następujący sposób: wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Korzystanie z prostokąta środka ciężkości minimalnej geometrii granicznej jako punktu środkowego i podziału na prostokąt.

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'

wprowadź opis zdjęcia tutaj

Atrybuty zostaną utracone, ale możesz użyć łączenia przestrzennego, aby je dodać ponownie.

BERA
źródło
6
Świetne rozwiązanie. Myślę, że należy zauważyć, że do wykonania tej operacji wymagana jest licencja Advanced (splitline, featureToLine i featureToPolygon). Ponadto myślę, że dodanie kilku komentarzy w całym kodzie pomoże nowym użytkownikom Pythona zrozumieć, co robi każda linia.
Fezter
Cześć @BERA, przepraszam za powolną odpowiedź. Wydaje się, że skrypt nie działa, generując następujący błąd: ERROR 000466: in_memory \ templine nie zgadza się ze schematem docelowych linii podziału Nie udało się wykonać (Dołącz).
Matt
1
Spróbuj zmienić wiersz dołączenia na: arcpy.Append_management (input = r'in_memory \ templine ', target = outfc_splitlines, schema_type =' NO_TEST ')
BERA
Wydaje się, że tym razem pojawia się kolejny błąd: Błąd analizy Błąd wcięcia Błąd: unindent nie pasuje do żadnego zewnętrznego poziomu wcięcia (wiersz 28)
Matt.
Musisz mieć 8 spacji przed arcpy.Append_manag ...
BERA