Разделить полигоны в средней точке с помощью ArcPy?

14

Я пытаюсь разделить около 4000 полигонов в их средней точке, перпендикулярно их самой длинной оси (то есть поперек ширины в средней точке), как показано на диаграмме ниже.

введите описание изображения здесь

В идеале я хотел бы сделать это автоматически и избегать разбиения каждого полигона вручную. Я извлек среднюю точку полигонов, преобразовав самые длинные линии, которые можно нарисовать в каждой, мне просто нужно определить метод для рисования линии ширины через эту точку автоматически.

Полигоны различаются по ширине, и поэтому инструменты, которые разделяют полигоны путем определения ширины линий определенной длины, на самом деле не то, что я ищу.

Есть идеи?

Matt
источник
все ли многоугольники выпуклые?
AnserGIS
Да, они более или менее имеют форму, аналогичную показанной на приведенной выше диаграмме.
Мэтт
Создайте перпендикуляр, как описано gis.stackexchange.com/questions/201867/… Используйте их и оригиналы в качестве входных данных для полигона. Это поможет делать рядом по точкам границы
FelixIP
@ Матт, мой ответ решил твою проблему? Если да, то можете ли вы пометить его как ответившийся флажком?
BERA

Ответы:

23

Сценарий ниже выведет новый класс пространственных объектов с разделенными полигонами и линии, используемые для их разделения. Требуется расширенная лицензия.

Полигоны будут разбиты следующим образом: введите описание изображения здесь

введите описание изображения здесь

Используя центр тяжести прямоугольника с минимальной ограничивающей геометрией в качестве средней точки и разделив его по прямоугольнику.

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'

введите описание изображения здесь

Атрибуты будут потеряны, но вы можете использовать Spatial Join, чтобы добавить их снова.

BERA
источник
6
Отличное решение. Я думаю, следует отметить, что для выполнения этой операции требуется расширенная лицензия (splitline, featureToLine и featureToPolygon). Кроме того, я думаю, что добавление некоторых комментариев в ваш код поможет новым пользователям Python понять, что делает каждая строка.
Фезтер
Привет @BERA, извините за медленный ответ. Сценарий, похоже, не работает, выводя следующую ошибку: ОШИБКА 000466: in_memory \ templine не соответствует схеме целевых линий разделения Не удалось выполнить (Добавить).
Мэтт
1
Попробуйте изменить добавить строку на: arcpy.Append_management (входы = r'in_memory \ templine», цель = outfc_splitlines, schema_type = 'NO_TEST')
Бера
Кажется, на этот раз получаю еще одну ошибку: Ошибка синтаксического анализа IndentationError: unindent не соответствует ни одному внешнему уровню отступа (строка 28)
Matt
Вы должны иметь 8 пробелов перед arcpy.Append_manag ...
BERA