TransWikia.com

Creating a snake-like labelling pattern with sequential numbers (ArcPy)

Geographic Information Systems Asked by Mariah.H on June 4, 2021

I am new to Python and ArcPy.

I’ve got rows of points that go up in sequential number starting from the left to right. I need every second row to be flipped so that it goes right to left. Every point has an ID field denoting what row it belongs to (ORIG_FID). I can’t figure out how to select that value in order to flip it. I’ll also need to get the highest value in that particular row and plug it into pStart. Here is what I have:
It will change every time as it is based on the polygon but this is what the data looks like

def unique_values(table, field):
with arcpy.da.SearchCursor(table, [field]) as cursor:
    return sorted([{row[0] for row in cursor}])

values = unique_values(cruise_points, "ORIG_FID")


with arcpy.da.SearchCursor(cruise_points, "ORIG_FID") as cursor:
    for row in cursor:
        if (row[] % 2) != 0:
            select = arcpy.SelectLayerByAttribute_management("cruiselyr", "NEW_SELECTION", ' "ORIG_FID" = unique[]')
            codeblock = ('n'
                         'rec = 0n'
                         'def autoIncrement():n'
                         '    global recn'
                         '    pStart = 12n'  # HIGHEST VALUE IN THE ROW
                         '    pInterval = -1n'
                         '    if (rec == 0):n'
                         '        rec = pStartn'
                         '    else:n'
                         '        rec += pIntervaln'
                         '    return rec ')
            arcpy.CalculateField_management(select, "Label", "autoIncrement()", "PYTHON_9.3", codeblock)

One Answer

I would probably switch to using cursors only instead of using CalculateField, which is generally harder to debug for anything reasonably complex. Sounds like you're on a good track with the logic, though. Kind of an interesting programming exercise.

Here's an approach with a toy example:

  • Step through each value, count how large each row is
  • Step through each value
    • If it's a new row, check if it's an even or odd row
      • If even, new labels will count upwards. Reset the counting position to the end of the previous row
      • If odd, new labels will count downwards. Set the counting position to the end of this current row
from collections import defaultdict

row_ids = [2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7]

row_size = defaultdict(int)
for row_this in row_ids:
    row_size[row_this] += 1


label = 1
row_last = None

for row_this in row_ids:
    if row_this != row_last:
        if (row_this % 2) == 0:
            label_step = 1
            label += row_size[row_last] - 1
        else:
            label_step = -1
            label += row_size[row_this] + 1

    row_last = row_this
    label += label_step

    print(row_this, label)

Will give:

(2, 1)
(2, 2)
(2, 3)
(2, 4)
(2, 5)
(2, 6)
(3, 12)
(3, 11)
(3, 10)
(3, 9)
(3, 8)
(3, 7)
(4, 13)
(4, 14)
(4, 15)
(4, 16)
(4, 17)
(5, 22)
(5, 21)
(5, 20)
(5, 19)
(5, 18)
(6, 23)
(6, 24)
(6, 25)
(6, 26)
(6, 27)
(6, 28)
(6, 29)
(6, 30)
(6, 31)
(6, 32)
(6, 33)
(7, 36)
(7, 35)
(7, 34)

I'll leave the translation to arcpy up to you, but something like that should map well to using cursors.

Correct answer by mikewatt on June 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP