How to generate grid with offset and assign values to the cells of a the grid?

2848
28
Jump to solution
06-23-2018 08:04 PM
HushamMohamed
Occasional Contributor

I have to generate thousands of cells as a grid, and then I have to assign  values to the cells, so far I know the a fishnet tool can generate the grid but how can I manage to create the offset.  May some one have better Idea.


The details of the grid are as illustrated in the attached diagram.
I have 5 Rows and 6 column,    after the 3rd column  the grid should start with B, other numbering should be the same as A.

0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

I guess you could use something like this:

def main():
    import arcpy

    # settings
    fc_out = r'C:\GeoNet\RectangleBlocks\data.gdb\result01'
    sr = arcpy.SpatialReference(2276)  # NAD_1983_StatePlane_Texas_North_Central_FIPS_4202_Feet?
    x_start = 2523853.5  # lower left
    y_start = 7124354.1  # lower left
    rect_width = 10.0
    rect_height = 5.0
    num_blocks_h = 6
    num_blocks_v = 5
    num_rect_in_block_h = 4
    num_rect_in_block_v = 8
    spacing_h = 3.0
    spacing_v = 3.0

    rectangles = []

    # loop through blocks
    for block_h in range(num_blocks_h):
        for block_v in range(num_blocks_v):
            # loop through rectangles
            for rect_h in range(num_rect_in_block_h):
                for rect_v in range(num_rect_in_block_v):
                    x_min = x_start + block_h * spacing_h + block_h * num_rect_in_block_h * rect_width + rect_h * rect_width
                    y_min = y_start + block_v * spacing_v + block_v * num_rect_in_block_v * rect_height + rect_v * rect_height
                    x_max = x_min + rect_width
                    y_max = y_min + rect_height
                    rectangle = CreateRactangle(x_min, y_min, x_max, y_max, sr)
                    rectangles.append(rectangle)

    arcpy.CopyFeatures_management(rectangles, fc_out)


def CreateRactangle(x_min, y_min, x_max, y_max, sr):
    coords = [[x_min, y_min], [x_min, y_max], [x_max, y_max],
              [x_max, y_min], [x_min, y_min]]
    return arcpy.Polygon(arcpy.Array([arcpy.Point(*coord) for coord in coords]), sr)

if __name__ == '__main__':
    main()

Which results in:

View solution in original post

28 Replies
HushamMohamed
Occasional Contributor

The Only problem I am facing now, is how to generate the grid with offset.

I mean did fishnet support creating the polygons with offset, for each row and column?

0 Kudos
XanderBakker
Esri Esteemed Contributor

You can use the fishnet as you commented for each block of 32 rectangles, but if you have many blocks you might want to script it using some python code. For that you would need to define the initial coordinate (lower left for instance), the number of blocks horizontally and vertically, the size of each rectangle (width and height) and the spacing between the blocks.

HushamMohamed
Occasional Contributor

thanks ,  yes I do have many blocks,  I have to think of that script.

0 Kudos
XanderBakker
Esri Esteemed Contributor

If you can provide the following data:

  •  the initial coordinate (lower left for instance),
  • The spatial reference to be used
  • the number of blocks horizontally and vertically,
  • the size of each rectangle (width and height)
  • the spacing between the blocks

... I'm sure we can help you with that script

0 Kudos
HushamMohamed
Occasional Contributor

Thank you Bakker for your help.
the initial coordinate (lower left for instance)= (2523853.5,7124354.1)
The spatial reference to be used (NAD83 / Texas North Central(ftUS) )
the number of blocks horizontally and vertically, (Horizontally 6, Vertically 5
the size of each rectangle (width and height): 40x40ft
the spacing between the blocks: 3ft

after that I need to divide each block to 32 sub sections (w:10ft h:5ft) just like what I have in attached pic, and fill the attribute similar as shown in the attached pic.

0 Kudos
XanderBakker
Esri Esteemed Contributor

I guess you could use something like this:

def main():
    import arcpy

    # settings
    fc_out = r'C:\GeoNet\RectangleBlocks\data.gdb\result01'
    sr = arcpy.SpatialReference(2276)  # NAD_1983_StatePlane_Texas_North_Central_FIPS_4202_Feet?
    x_start = 2523853.5  # lower left
    y_start = 7124354.1  # lower left
    rect_width = 10.0
    rect_height = 5.0
    num_blocks_h = 6
    num_blocks_v = 5
    num_rect_in_block_h = 4
    num_rect_in_block_v = 8
    spacing_h = 3.0
    spacing_v = 3.0

    rectangles = []

    # loop through blocks
    for block_h in range(num_blocks_h):
        for block_v in range(num_blocks_v):
            # loop through rectangles
            for rect_h in range(num_rect_in_block_h):
                for rect_v in range(num_rect_in_block_v):
                    x_min = x_start + block_h * spacing_h + block_h * num_rect_in_block_h * rect_width + rect_h * rect_width
                    y_min = y_start + block_v * spacing_v + block_v * num_rect_in_block_v * rect_height + rect_v * rect_height
                    x_max = x_min + rect_width
                    y_max = y_min + rect_height
                    rectangle = CreateRactangle(x_min, y_min, x_max, y_max, sr)
                    rectangles.append(rectangle)

    arcpy.CopyFeatures_management(rectangles, fc_out)


def CreateRactangle(x_min, y_min, x_max, y_max, sr):
    coords = [[x_min, y_min], [x_min, y_max], [x_max, y_max],
              [x_max, y_min], [x_min, y_min]]
    return arcpy.Polygon(arcpy.Array([arcpy.Point(*coord) for coord in coords]), sr)

if __name__ == '__main__':
    main()

Which results in:

HushamMohamed
Occasional Contributor

Yes Yes that's it. Thank you Bakker, I did not test it yet but from code and the result, hat was exactly what I am looking for.   its just missing the attribute tables, I will try the field calculator for that.

Will get back to you ASAP.

I do appreciate that

0 Kudos
HushamMohamed
Occasional Contributor

Thank you Xander, this worked as supposed to be "smarter".

One last question-is it possible to generate the attribute as requested earlier?.

Thanks Again

0 Kudos
XanderBakker
Esri Esteemed Contributor

With the attribute table you are referring to labels for each rectangle shown in you image, right?

If so, let's clear up some doubts I have about the coding. Please correct me where I'm wrong.

  • The code is defined by 3 parts separated by dashes
  • Part 1 is a character "A" or "B". "A" in case of the 3 first blocks (left) and "B" in case of the last 3 blocks (right)
  • Part 2 is a number that is defined per quadrant (4x4 rectangles) of each block going from left to right increasing by one. First series 1 to 6 (lower half of first row of blocks), second series (upper part of first row of blocks) 7 to 12, followed by 13 to 18 and 19 to 24 for the second row of blocks, 25 to 30 and 31 to 36 for the third row of blocks, 37 to 42 and 43 to 48 for the fourth row of blocks and 49 to 54 and 55 to 60 for the fifth row of blocks.
  • Part 3 is a number that will be assigned per quadrant of the blocks, always in the range of 1 to 8, taking the first column of a quadrant and assigning 1 to 4 (starting in the lower rectangle in the quadrant) and 5 to 8 for the second column.

Are these assumptions correct?