Select to view content in your preferred language

Check if two rows in same table have similar values in same field

4472
5
Jump to solution
05-08-2012 10:08 AM
by Anonymous User
Not applicable
Original User: natogd

I am new to python and have what should be an easy question but I'm not sure where to start.  I want to examine a table to see if adjacent parcels have the same owner name and replace the owner name with an arrow character to emulate the way maps used to look and unclutter them a bit.

I have some code that can already find the table and loop through the rows, but how do I compare the current row with other rows in the same table.  I'm lucky that there are smart id numbers 10 chars long with the first 8 showing if they are adjacent and the second last identifying the quarter section and the last always 0.

I'm attaching three screen shots.  The first shows how the data is layed out.  The second is how I want the arrows to look.  The third is a clip of the old map I'm trying to emulate.

[ATTACH=CONFIG]14168[/ATTACH][ATTACH=CONFIG]14169[/ATTACH][ATTACH=CONFIG]14170[/ATTACH]

# Import standard library modules import win32com.client, sys, os, arcpy, ctypes ## # Create the Geoprocessor object GP = win32com.client.Dispatch("esriGeoprocessing.GpDispatch.1")  # Set the Workspace Location GP.Workspace= sys.argv[1] #"L:/GIS/DATA/2012/Ownership" #GP.Workspace= "L:/GIS/DATA/2012/Ownership"  # Obtain a list of feature classes from the above Workspace fcs = GP.ListFeatureClasses("*","polygon")  # Check to see if a field exists def FieldExists(myFC,myFN):     myDesc = arcpy.Describe(myFC)     for field in myDesc.fields:         if field.name == myFN:             return "true"  # Reset the enumeration to make sure the first object is returned # An Enumeration is a list fcs.reset()  # Get the first feature class name from the fcs enumeration fc = fcs.next()  while fc: # While the feature class name is not None (check if it exists)     # do the following, starting with the first feature class      # Get the next feature class name     GP.AddMessage("List of Feature Classes: " + fc)     # Check for a specific feature class name     if (fc == "QTRTEST.shp"):          if (not FieldExists (fc,"ShortRoll") == "true"):             GP.AddMessage ("Adding Field: ShortRoll")             arcpy.AddField_management(fc, "ShortRoll", "TEXT", "", "", 10)         else:             arcpy.DeleteField_management(fc, "ShortRoll")             arcpy.AddField_management(fc, "ShortRoll", "TEXT", "", "", 10)         # Use a SearchCursor to obtain access to all the rows of data         # in the above feature class         rows = arcpy.UpdateCursor(fc,"","","ROLL_NUMBE; test; ShortRoll","")         # Iterate through all the rows in the cursor         for row in rows:                 myString = str(row.ROLL_NUMBE)                 myLen = len(myString)                 myString = myString[(myLen-4):]                 row.test = myString[:2]                 row.ShortRoll = "1234abcd"                 rows.updateRow(row)      # this command returns to the beginning of the while loop     # to see if there is another feature class         del row         del rows     fc = fcs.next() 
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor
Hi Nathan,

I'm not sure if you can add the arrows using python, but you can determine which adjacent parcels have the same owner.  Here is an example below.  I'm searching a parcels feature class based off of a PIN field that is identical to your 'smart id' where each will end with either 10, 20, 30, or 40.  10 will be the bottom right, 20 the bottom left, 30 the top left, and 40 the top right.  The code updates a field called 'Direction' with a value (east, west, north, south) corresponding to the parcel that has the same owner.

fc = "Parcels"  list = []  rows = arcpy.SearchCursor(fc) for row in rows:     PIN = str(row.PIN)[0:5]     list.append(PIN)  del row, rows  pinList = []  for item in list:     if item not in pinList:         pinList.append(item)  def updateDirection(value1, value2, direction):     for item in pinList:         item1 = item + value1         rows = arcpy.SearchCursor(fc, "PIN = " + item1)         for row in rows:             Name = row.Name             item2 = item + value2             rows2 = arcpy.UpdateCursor(fc, "PIN = " + item2)             for row2 in rows2:                 if row2.Name == Name:                     row2.Direction = direction                     rows2.updateRow(row2)     del row, rows, row2, rows2  updateDirection('20', '10', 'west') updateDirection('30', '20', 'north') updateDirection('40', '30', 'east') updateDirection('10', '40', 'south')

View solution in original post

0 Kudos
5 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Nathan,

I'm not sure if you can add the arrows using python, but you can determine which adjacent parcels have the same owner.  Here is an example below.  I'm searching a parcels feature class based off of a PIN field that is identical to your 'smart id' where each will end with either 10, 20, 30, or 40.  10 will be the bottom right, 20 the bottom left, 30 the top left, and 40 the top right.  The code updates a field called 'Direction' with a value (east, west, north, south) corresponding to the parcel that has the same owner.

fc = "Parcels"  list = []  rows = arcpy.SearchCursor(fc) for row in rows:     PIN = str(row.PIN)[0:5]     list.append(PIN)  del row, rows  pinList = []  for item in list:     if item not in pinList:         pinList.append(item)  def updateDirection(value1, value2, direction):     for item in pinList:         item1 = item + value1         rows = arcpy.SearchCursor(fc, "PIN = " + item1)         for row in rows:             Name = row.Name             item2 = item + value2             rows2 = arcpy.UpdateCursor(fc, "PIN = " + item2)             for row2 in rows2:                 if row2.Name == Name:                     row2.Direction = direction                     rows2.updateRow(row2)     del row, rows, row2, rows2  updateDirection('20', '10', 'west') updateDirection('30', '20', 'north') updateDirection('40', '30', 'east') updateDirection('10', '40', 'south')
0 Kudos
by Anonymous User
Not applicable
Original User: dkwiens

Following Jake S's suggestion, I think it should be possible to symbolize the arrows. Add one column for labels and another for arrow rotation. Then, loop through each feature, assign the first in the pair a value for the label field, and the second an appropriate rotation for the arrow (0, 90, 180, 270). Label the features from the label field. Finally, export the values with a rotation angle to a centroid point file and symbolize with a rotated arrow, with the arrow point anchored at the centroid.

If your parcels are not always at cardinal directions to each other, it would still be possible, but more complicated, to draw new line segments attaching pairs of centroid points with Python. Then, symbolize with an arrow line.
0 Kudos
NathanOgden
Occasional Contributor
Thank you to you both.  I could only credit one.
0 Kudos
by Anonymous User
Not applicable
Original User: natogd

If you are still following this thread, I've updated my code and am getting an error.  Maybe you can spot what I'm doing wrong.

I've enclosed a screen shot of part of my table.
[ATTACH=CONFIG]14183[/ATTACH]
The error I'm receiving is:

<type 'exceptions.TypeError'>: descriptor 'append' requires a 'list' object but received a 'str'
Failed to execute (Arrows).

# Import standard library modules
import win32com.client, sys, os, arcpy, ctypes
##
# Create the Geoprocessor object
GP = win32com.client.Dispatch("esriGeoprocessing.GpDispatch.1")

# Set the Workspace Location
GP.Workspace= sys.argv[1] #"L:/GIS/DATA/2012/Ownership"
#GP.Workspace= "L:/GIS/DATA/2012/Ownership"

# Obtain a list of feature classes from the above Workspace
fcs = GP.ListFeatureClasses("*","polygon")

# Check to see if a field exists
def FieldExists(myFC,myFN):
    myDesc = arcpy.Describe(myFC)
    for field in myDesc.fields:
        if field.name == myFN:
            return "true"

def updateDirection(value1, value2, direction):
    for item in pinList:
        item1 = item + value1
        rows = arcpy.SearchCursor(fc, "ROLL_NUMBE = " + item1)
        for row in rows:
            Name = row.Name
            item2 = item + value2
            rows2 = arcpy.UpdateCursor(fc, "ROLL_NUMBE = " + item2)
            for row2 in rows2:
                if row2.Name == Name:
                    row2.myNewField = direction
                    rows2.updateRow(row2)
    del row, rows, row2, rows2

myNewField = "Direction"

# Reset the enumeration to make sure the first object is returned
# An Enumeration is a list
fcs.reset()

# Get the first feature class name from the fcs enumeration
fc = fcs.next()

while fc:   ##  While the feature class name is not None (check if it exists)
            ##  do the following, starting with the first feature class

    GP.AddMessage("List of Feature Classes: " + fc)
    
##      Check for a specific feature class name
    if (fc == "QTRTEST.shp"):
        lockTest = arcpy.TestSchemaLock (fc)
        if lockTest:
            GP.AddMessage("If Loop: " + fc)
        else:
            print "Unable to aquire Schema Lock"
        if (not FieldExists (fc,myNewField) == "true"):
            GP.AddMessage ("Adding Field: " + myNewField)
            arcpy.AddField_management(fc, myNewField, "TEXT", "", "", 10)
        else:
            arcpy.DeleteField_management(fc, myNewField)
            arcpy.AddField_management(fc, myNewField, "TEXT", "", "", 10)

        List = []
        rows = arcpy.SearchCursor(fc)
        
        for row in rows:
##            myString = str(row.ROLL_NUMBE)
##            myLen = len(myString)
##            myString = myString[(myLen-4):]
##            list.append(myString)
            myString = str(row.ROLL_NUMBE)[((len(str(row.ROLL_NUMBE)))-4):]
            list.append(myString)
            print myString
        del row, rows
        
        for item in list:
            if item not in pinList:
                pinList.append(item)

        updateDirection('20', '10', 'west')
        updateDirection('30', '20', 'north')
        updateDirection('40', '30', 'east')
        updateDirection('10', '40', 'south')

    fc = fcs.next()
    
arcpy.RefreshActiveView()
print "complete"
0 Kudos
by Anonymous User
Not applicable
Original User: JSkinn3

Change list.append(myString) to List.append(myString)
0 Kudos