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?


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.