<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Reording of OBJECTID in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510773#M71131</link>
    <description>&lt;P&gt;Yes, I did know that, which is why I am trying to populate the new filed "NewIDField". I am still having issue with the sort.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 26 Jul 2024 18:08:10 GMT</pubDate>
    <dc:creator>2Quiker</dc:creator>
    <dc:date>2024-07-26T18:08:10Z</dc:date>
    <item>
      <title>Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510702#M71127</link>
      <description>&lt;P&gt;I am need to reorder the objectID, but I am having difficulties getting the code correct.&lt;/P&gt;&lt;P&gt;The OriginalOrder.png is what it currently is and the ReOrder.png is what I want. see pictures.&lt;/P&gt;&lt;P&gt;I need the reorder to match the ReOrder picture.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;code,&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy

# Define paths
input_fc = r"C:\Temp\Grid.gdb\Clipped_Grid_Polygons"

# Add fields for Max_Longitude and Min_Latitude if they don't already exist
fields = [f.name for f in arcpy.ListFields(input_fc)]
if "Max_Longitude" not in fields:
    arcpy.AddField_management(input_fc, "Max_Longitude", "DOUBLE")
if "Min_Latitude" not in fields:
    arcpy.AddField_management(input_fc, "Min_Latitude", "DOUBLE")
if "NewIDField" not in fields:
    arcpy.AddField_management(input_fc, "NewIDField", "LONG")

# Calculate Max_Longitude and Min_Latitude for each feature
with arcpy.da.UpdateCursor(input_fc, ["OBJECTID", "SHAPE@", "Max_Longitude", "Min_Latitude"]) as cursor:
    for row in cursor:
        polygon = row[1]
        max_longitude = max(point.X for part in polygon for point in part)
        min_latitude = min(point.Y for part in polygon for point in part)
        row[2] = max_longitude
        row[3] = min_latitude
        cursor.updateRow(row)

print("Max_Longitude and Min_Latitude fields calculated and updated.")

# Extract the features into a list
features = []
with arcpy.da.SearchCursor(input_fc, ["OBJECTID", "Max_Longitude", "Min_Latitude"]) as cursor:
    for row in cursor:
        features.append((row[0], row[1], row[2]))

# Sort the list based on Min_Latitude (ascending) and Max_Longitude (descending)
features.sort(key=lambda x: (x[2], -x[1]))

# Create a dictionary to map the new OID values
new_oid_mapping = {oid_tuple[0]: index + 1 for index, oid_tuple in enumerate(features)}

# Update the original feature class with the new NewIDField values based on the sorted order
with arcpy.da.UpdateCursor(input_fc, ["OBJECTID", "NewIDField"]) as cursor:
    for row in cursor:
        current_oid = row[0]
        if current_oid in new_oid_mapping:
            row[1] = new_oid_mapping[current_oid]
            cursor.updateRow(row)

print("NewIDField values reordered based on Min_Latitude and Max_Longitude sorting.")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jul 2024 16:38:20 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510702#M71127</guid>
      <dc:creator>2Quiker</dc:creator>
      <dc:date>2024-07-26T16:38:20Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510750#M71128</link>
      <description>&lt;P&gt;Relying on feature order based on OID is kindof iffy.&lt;/P&gt;&lt;P&gt;The only way to change OID is to create a new feature class in the order you desire, so this isn't an UpdateCursor task, but an InsertCursor one.&lt;/P&gt;&lt;P&gt;Getting the "back-and-forth" numbering is a matter of assigning bands (by Y value), then using modulus-2 of band-number to assign left-to-right or right-to-left order.&lt;/P&gt;&lt;P&gt;- V&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jul 2024 17:37:05 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510750#M71128</guid>
      <dc:creator>VinceAngelo</dc:creator>
      <dc:date>2024-07-26T17:37:05Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510773#M71131</link>
      <description>&lt;P&gt;Yes, I did know that, which is why I am trying to populate the new filed "NewIDField". I am still having issue with the sort.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jul 2024 18:08:10 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510773#M71131</guid>
      <dc:creator>2Quiker</dc:creator>
      <dc:date>2024-07-26T18:08:10Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510821#M71134</link>
      <description>&lt;P data-unlink="true"&gt;As a SQL query, it's &lt;A href="https://gis.stackexchange.com/questions/73978/numbering-polygons-according-to-their-spatial-relationships/73995#73995" target="_self"&gt;pretty basic&lt;/A&gt;&amp;nbsp;but doing this in Python is a bit trickier, since you have to do the inner query in memory. The key is to chunk the features into rows by Y, so you can order by X. Then you need to flip the listed X values on alternate rows. I'm on a deadline, so I can't offer even a rough untested code block.&lt;/P&gt;&lt;P data-unlink="true"&gt;- V&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jul 2024 19:32:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510821#M71134</guid>
      <dc:creator>VinceAngelo</dc:creator>
      <dc:date>2024-07-26T19:32:32Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510934#M71138</link>
      <description>&lt;P&gt;arcpy makes this operation really difficult. I need to do it pretty frequently and I usually use a method like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;from arcpy.typing.describe import FeatureClass
from typing import Generator

# Use field names in cursor with this function
def as_dict(cursor: arcpy.da.SearchCursor) -&amp;gt; Generator[dict, None, None]:
    with cursor as cur:
        yield from ( dict(zip( cur.fields, row) for row in cursor ) )

input_fc = r"C:\Temp\Grid.gdb\Clipped_Grid_Polygons"
input_desc: FeatureClass = arcpy.Describe(input_fc)
fields = [f.name for f in input_desc.fields]

# Remove the generic shape and insert the full shape token
# This is neccesary for inserting a real shape back into the table
# after the re-ordering
fields.remove(input_desc.shapeFieldName)
fields.insert(0, "SHAPE@")

if "Max_Longitude" not in fields:
    arcpy.AddField_management(input_fc, "Max_Longitude", "DOUBLE")
if "Min_Latitude" not in fields:
    arcpy.AddField_management(input_fc, "Min_Latitude", "DOUBLE")
if "NewIDField" not in fields:
    arcpy.AddField_management(input_fc, "NewIDField", "LONG")

# Update the fields after adding the new fields
# you can probably just apppend them to the fields list
# but this will make sure that nothing funky happens
input_desc: FeatureClass = arcpy.Describe(input_fc)
fields = [f.name for f in input_desc.fields]

# Calculate Max_Longitude and Min_Latitude for each feature
with arcpy.da.UpdateCursor(input_fc, ["OBJECTID", "SHAPE@", "Max_Longitude", "Min_Latitude"]) as cursor:
    for row in as_dict(cursor):
        polygon: arcpy.Polygon = row["SHAPE@"]
        max_longitude = max(point.X for part in polygon for point in part)
        min_latitude = min(point.Y for part in polygon for point in part)
        row["Max_Longitude"] = max_longitude
        row["Min_Latitude"] = min_latitude
        
        # Because the row is now a dictionary, we need to pull the values out
        # and convert them to a regular list or tuple.
        # This only works because Python 3.7+ guarantees dictionary order
        # Don't do this in Python 2 because the default dict object is not ordered
        cursor.updateRow(list(row.values())) 

print("Max_Longitude and Min_Latitude fields calculated and updated.")

# Make sure we use the same field order for all cursors (all_fields)
# We're also using the as_dict function again to disambiguate what we're doing
features: list[dict[str, any]] = [row for row in as_dict(arcpy.da.SearchCursor(input_fc, all_fields))]
features.sort(key=lambda x: (x["Min_Latitude"], -x["Max_Latitude"]))

# Use an editor context when editing the feauture class because we need to delete all rows
# If you do that in an edit context, you can rollback the changes if something goes wrong
with arcpy.da.Editor(input_desc.workspace):
    # Delete all rows in the feature class
    # Here be dragons, make sure you have a backup of the data
    arcpy.management.DeleteRows(input_fc)
    
    # If you need the OIDs to start at zero, you need to "Compress" the feature class
    
    # Uncomment below reset the OID values to start at 1
    # arcpy.management.Compress(input_fc)
    
    # Re-Insert the rows in the sorted order
    with arcpy.da.InsertCursor(input_fc, fields) as cursor:
        for row in features:
            # Use the same list conversion as before
            cursor.insertRow(list(row.values()))
    print("NewIDField values reordered based on Min_Latitude and Max_Longitude sorting.")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've also been working on a more "logical" interface for operations with filedatabase features like this in my &lt;A href="https://github.com/hwelch-fle/pytframe2/" target="_self"&gt;pytframe2&lt;/A&gt; project. Here's an example of the same code written using my FeatureClass interface:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
from arcpy.typing.describe import FeatureClass
from typing import Generator

from utils.datamodel.models import FeatureClass, as_dict

def main():
    input_fc = r"C:\Temp\Grid.gdb\Clipped_Grid_Polygons"
    clipped_grid = FeatureClass(input_fc)
    
    for field in ["Max_Longitude", "Min_Latitude", "NewIDField"]:
        if field not in clipped_grid.fields:
            clipped_grid.add_field(field, "DOUBLE" if field != "NewIDField" else "LONG")
            
    with clipped_grid.update_cursor() as cursor:
        for row in as_dict(cursor):
            polygon = row["SHAPE@"]
            max_longitude = max(point.X for part in polygon for point in part)
            min_latitude = min(point.Y for part in polygon for point in part)
            row["Max_Longitude"] = max_longitude
            row["Min_Latitude"] = min_latitude
            cursor.updateRow(list(row.values()))

    print("Max_Longitude and Min_Latitude fields calculated and updated.")
    
    sort_by_coords = lambda x: (x["Min_Latitude"], -x["Max_Latitude"])
    sorted_features = sorted(sort_by_coords, list(clipped_grid))
    
    # Start an edit session
    with clipped_grid.editor:
        # Delete all rows
        with clipped_grid.update_cursor(["OID@"]) as cursor:
            for row in sorted_features:
                cursor.deleteRow()
                
        # Re-insert the rows in the sorted order
        with clipped_grid.insert_cursor() as cursor:
            for row in sorted_features:
                cursor.insertRow(list(row.values()))
        print("NewIDField values reordered based on Min_Latitude and Max_Longitude sorting.")

if __name__ == "__main__":
    main()&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As a warning, all the code above is untested. I would definitely use it on a copy of your data and let me know if there are any bugs.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Edit: immediately found one in my pytframe example, in shadowing the typing.describe.FeatureClass with the utils.datamodel.FeatureClass.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This won't break the script because the typing one is just being used so the editor can lint the code, but if you want to fix it you just need to change the import name with an `import as` statement on one of them.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Will probably end up renaming the data model class to FeatureClassModel to avoid this, or extend the typing class so you don't need it.&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jul 2024 02:30:18 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1510934#M71138</guid>
      <dc:creator>HaydenWelch</dc:creator>
      <dc:date>2024-07-27T02:30:18Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1513620#M71179</link>
      <description>&lt;P&gt;I am on 3.7, but I was not able to get past the ,from arcpy.typing.describe import FeatureClass. The issue ended up being the Shape@ and Legnth fields. For some reason they were not calculated correctly in the File Geodatabase. So my code did work by updating the NewIDField.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 01 Aug 2024 14:19:39 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1513620#M71179</guid>
      <dc:creator>2Quiker</dc:creator>
      <dc:date>2024-08-01T14:19:39Z</dc:date>
    </item>
    <item>
      <title>Re: Reording of OBJECTID</title>
      <link>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1513877#M71191</link>
      <description>&lt;P&gt;You can skip that, or just remove it from your code. I use it to get intellisense for describe objects while I'm programming&lt;/P&gt;</description>
      <pubDate>Thu, 01 Aug 2024 20:33:50 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/reording-of-objectid/m-p/1513877#M71191</guid>
      <dc:creator>HaydenWelch</dc:creator>
      <dc:date>2024-08-01T20:33:50Z</dc:date>
    </item>
  </channel>
</rss>

