Select to view content in your preferred language

# Sort grid (text) field sort of like a number!

4104
11
06-23-2015 11:24 AM
by Anonymous User
Not applicable

Hello all,

I'm not sure if python can do something like this. Our brains can do it so maybe we can get an automated way to do this?

I need to give a page number to each of these pages. They need to be in an order like below, based on the grid name. It's like township name, then some of them have a section detail page (11-1), and then some of them further have a subsection detail page (11-1NE - northeast part of section 1 in township 11). I have 275 pages in this set. In the past I have to do it manually. Does anyone have any ideas? Thank you.

1

2

3

4

5

6

7

8

9

10

11

11-1

11-1NE

11-1NW

11-1SE

11-2

11-2NE

11-7

11-8

11-10SW

11-12NE

1 Solution

Accepted Solutions
MVP Honored Contributor

This ended up being more complicated than I expected, but here's what I got. I have doubt there's a more direct route. Also, there be some hidden gotchas in your data. It updates a field called "ord", based on labels in "rnd" (in format "102-65NE"), from a feature class "points":

```>>> from operator import itemgetter # import itergetter function
... myList = [] # make empty list
... fc = "points"
... labelField = "rnd"
... orderField = "ord"
... with arcpy.da.SearchCursor(fc,["OID@",labelField]) as cursor: # loop through your feature class
...    for row in cursor:
...        twp = str(row[1].split("-")[0]) # get township
...        if len(row[1].split("-")) > 1: # if there is more than just TWP
...            sec = ""
...            qtr = ""
...            for x in row[1].split("-")[1]: # loop through characters after hyphen
...                if x.isdigit():
...                    sec += str(x) # add to section if numerical
...                else:
...                    qtr += str(x) # add to quarter if letter
...            if len(qtr) == 0:
...                qtr = 0
...        else:
...            sec = 0
...        print twp
...        myList.append({"OID":row[0],"TWP":int(twp),"SEC":int(sec),"QTR":qtr}) # add to list
... myList = sorted(myList, key=itemgetter("TWP","SEC","QTR")) # sort list in place, by TWP, SEC, QTR
... with arcpy.da.UpdateCursor(fc,["OID@",orderField]) as cursor: # start updating
...    for row in cursor:
...        row[1] = next(index for (index, d) in enumerate(myList) if d["OID"] == row[0]) # enumerate list and match OIDs
...        cursor.updateRow(row) # update row to include a number```

11 Replies
by
Frequent Contributor

You can use the Sort tool, in the General toolbox (data management) to sort on a field. To use it in Python, use the following syntax:

Sort_management (in_dataset, out_dataset, sort_field, {spatial_sort_method})

Regular Contributor III

To add to  Sephe Fox​ said you'll need an advanced license and use the "Shape" as a sort field

by Anonymous User
Not applicable

That sounds great too. I only have a Standard license right now but I'll have to keep that in mind for some day in the future. Thanks!

MVP Honored Contributor

I'm a little confused what step you're at. Do you need to assign the page numbers based on whether or not it's a detail map, or create a sortable field to order your exported data driven pages based on the page number, or both?

by Anonymous User
Not applicable

Well, what I do when I do it manually, is first I sort it as best I can. Then I make a number field and type in one by one, the number of the page. So that when I export data driven pages it has the right page number and it's in the right order.

So if I can sort this grid number field and then assign the page numbers to that sort order, I think I would be done. At one point in time I had some code that would assign a sequential number after I had it sorted how I wanted it.

Does that help explain?

MVP Honored Contributor

Yes, that helps. Do you have a quarter section grid? If so, it would be a matter of

1.) Create one field to store map type in your index layer

2.) Assign values of "TWP", "SEC", or "QTR" to denote whether the page is a township, section or quarter section map. You can likely do this automatically based on the index feature size (township > section > quarter).

3.) Spatial Join (must use the geoprocessing tool, not right-click join dialog) the index layer to the quarter section grid, based on HAVE_THEIR_CENTERS_IN. Now index features will have quarter info.

4.) Using if...then logic in field calculator, calculate the page number (if map type = "QTR", make a page number like "TWP" + "-" + "SEC" + "QTR")

Once you have your page numbers in a field, you must determine their order, which will be my next post.

MVP Honored Contributor

This ended up being more complicated than I expected, but here's what I got. I have doubt there's a more direct route. Also, there be some hidden gotchas in your data. It updates a field called "ord", based on labels in "rnd" (in format "102-65NE"), from a feature class "points":

```>>> from operator import itemgetter # import itergetter function
... myList = [] # make empty list
... fc = "points"
... labelField = "rnd"
... orderField = "ord"
... with arcpy.da.SearchCursor(fc,["OID@",labelField]) as cursor: # loop through your feature class
...    for row in cursor:
...        twp = str(row[1].split("-")[0]) # get township
...        if len(row[1].split("-")) > 1: # if there is more than just TWP
...            sec = ""
...            qtr = ""
...            for x in row[1].split("-")[1]: # loop through characters after hyphen
...                if x.isdigit():
...                    sec += str(x) # add to section if numerical
...                else:
...                    qtr += str(x) # add to quarter if letter
...            if len(qtr) == 0:
...                qtr = 0
...        else:
...            sec = 0
...        print twp
...        myList.append({"OID":row[0],"TWP":int(twp),"SEC":int(sec),"QTR":qtr}) # add to list
... myList = sorted(myList, key=itemgetter("TWP","SEC","QTR")) # sort list in place, by TWP, SEC, QTR
... with arcpy.da.UpdateCursor(fc,["OID@",orderField]) as cursor: # start updating
...    for row in cursor:
...        row[1] = next(index for (index, d) in enumerate(myList) if d["OID"] == row[0]) # enumerate list and match OIDs
...        cursor.updateRow(row) # update row to include a number```

by Anonymous User
Not applicable

So I'm getting Parsing error SyntaxError: invalid syntax (line 😎

`twp = str(row[1].split("-")[0]) # get township  `

What can I do to try and run this?

Thank you for your effort to help! This code will probably help a lot of people.

Thanks,

MVP Honored Contributor

I'm not sure, that looks correct to me. The line says, "Find the value in the current row, in the field specified in the 2nd variable listed in the cursor (the labelField), split it when there is a hyphen, return the portion before the first hyphen (or the entire string if there is no hyphen), convert it to a string, and store the value in a variable called twp".

Have you changed the labelField to match your field name? Also, check the previous line to make sure it's correct (e.g. not missing the colon).