Select to view content in your preferred language

Is there a possibility in ArcMap to automatically fill a given shape with smaller polygons of a given shape?

6178
21
10-25-2016 06:58 AM
AndreasEugster2
Deactivated User

Like I have a rectangle (3x5m) as a vector layer... now I would like to fill this 3x5m rectangle optimal with smaller polygons in a given shape (1x2m rectangles).
I didn't find anything helpful yet....

21 Replies
DarrenWiens2
MVP Alum

Here's my attempt. It's not necessarily the optimal. You could rotate the grid axes and compare to see which holds the most rectangles. There is also the distinct possibility that neither orientations optimally fill the original rectangle (i.e. there is often a remainder that could fit more small rectangles rotated by 90 degrees).

recs = 'recs' # rectangle feature layer
mbr = arcpy.MinimumBoundingGeometry_management(recs,r'in_memory\mbr',mbg_fields_option='MBG_FIELDS') # get MBRs
grids = [] # merge list to be populated
out_grid = r'in_memory\out_grid' # final output
sr = arcpy.Describe(recs).spatialReference # CRS
grid_h = 20 # cell height, aligned to long axis of rectangle
grid_w = 10 # cell width, aligned to short axis of rectangle
with arcpy.da.SearchCursor(mbr,['SHAPE@','OID@','MBG_Width','MBG_Length','MBG_Orientation'], spatial_reference=sr) as cursor:
    for row in cursor: # loop through MBRs
        grid = r'in_memory\grid_' + str(row[1]) # temp grid
        dy = math.cos(math.radians(row[4])) * row[3] # y diff along long side
        dx = math.sin(math.radians(row[4])) * row[3] # x diff along long side
        y_axis = str(row[0].firstPoint.X + dx) + ' ' + str(row[0].firstPoint.Y + dy) # rotation point
        origin = str(row[0].firstPoint.X) + ' ' + str(row[0].firstPoint.Y) # starting point
        arcpy.env.outputCoordinateSystem = sr # set CRS for fishnet
        arcpy.CreateFishnet_management(grid,origin,y_axis,grid_w,grid_h,int(row[3]/grid_h),int(row[3]/grid_w),labels='NO_LABELS',geometry_type='POLYGON') # make fishnet
        temp_lyr = 'sel_' + str(row[1]) # temp layer
        arcpy.MakeFeatureLayer_management(grid,temp_lyr) # make feature layer
        arcpy.SelectLayerByLocation_management(temp_lyr,"WITHIN_CLEMENTINI",row[0],selection_type='NEW_SELECTION') # select grid cells inside MBR
        arcpy.SelectLayerByAttribute_management(temp_lyr,"SWITCH_SELECTION") # switch selection
        arcpy.DeleteFeatures_management(temp_lyr) # delete cells outside MBR
        grids.append(grid) # add to merge list
arcpy.Merge_management(grids,out_grid) # merge‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

0 Kudos
ScottMoyer
Deactivated User

Another suggestion is to:

1. Start editing in ArcMap the feature class with 3x5 polygons,

2. Select (all) the 3x5 polygons,

3. Go to Editor, then Buffer...

4. Enter -1 (negative one) to make an inner polygon 1x3

Scott

0 Kudos