Trying to calculate fields from paired points in a shapefile

1543
4
11-10-2011 11:26 AM
DavidHarlan
New Contributor
I have pairs of points that share a common id "COMID".  I would like to calculate an empty field with an equation that uses values from both points in the pair.  I am trying to use UpdateCursor and a for loop and then accessing the next row with row.next() but I don't think this is right.  What I want to say is-  for each row: if id1 = id2 then perform this calculation with values from row1 and row 2.
Anyway here is what I have and it does not work.
upcur = gp.UpdateCursor(sin_pt)
for row in upcur:
        id1 = row.COMID
        id2 = row.next().COMID
        if id1 == id2:
            yval1 = row.NORTH
            yval2 = row.next().NORTH
            xval1 = row.EAST
            xval2 = row.next().EAST
            distval = math.sqrt(((xval1 - xval2)**2) + ((yval1-yval2)**2))
            length = row.LENGTHKM * 1000
            row.DIST = length / distval
            upcur.updateRow(row)

#No error messages but the field is still empty
#thanks
Tags (2)
0 Kudos
4 Replies
DavidHarlan
New Contributor
Here is the code with formatting
upcur = gp.UpdateCursor(sin_pt)
for row in upcur:
        id1 = row.COMID
        id2 = row.next().COMID
        if id1 == id2:
            yval1 = row.NORTH
            yval2 = row.next().NORTH
            xval1 = row.EAST
            xval2 = row.next().EAST
            distval = math.sqrt(((xval1 - xval2)**2) + ((yval1-yval2)**2))
            length = row.LENGTHKM * 1000
            row.DIST = length / distval
            upcur.updateRow(row)
0 Kudos
markdenil
Occasional Contributor III
A cursor can really only access one row at a time. All that jumping-to-the-next-row stuff is just going to make a mess of things.

try breaking the operation into steps:
first, run a search cursor all the way through to build a list of unique COMID values (we can call the list comidList).

next, itterate through that list making a new search cursor with a query string for that COMID for each itteration. This gets you a set of rows with just that COMID (that pair of points).

Each point has two values you want, eh? (NORTH and EAST)
Run through the two points, making a list of the NORTH and EAST values of point 1 (lets call it pnt1List)
[north_val1, east_val1]
and another list of the NORTH and EAST values of point 2 (pnt2List).  [north_val2, east_val2]


append these lists to a new list (pntValList). the first entry will look like this:
[[north_val1, east_val1],[north_val2, east_val2]]

Now append that comIdList to a new list (the bigList):
[[[north_val1, east_val1],[north_val2, east_val2]]]

set all the lists EXCEPT bigList and comidList
that is: pnt1List, pnt2List, and pntValList, to [] (we will reuse these lists in the next itteration)

move your cursor to the next COMID in comidList, and do it all again.

You are building bigList to be a set of nested lists of pairs of NORTH and EAST values for each COMID in the same order as your list of COMID values:
([pnt1List] and [pnt2List] inside [pntValList], inside [bigList]
for example:
[
[[north_val1, east_val1],[north_val2, east_val2]],
[[north_val1, east_val1],[north_val2, east_val2]],
[[north_val1, east_val1],[north_val2, east_val2]],
[[north_val1, east_val1],[north_val2, east_val2]]
]

NOW you can itterate through the COMIDs in the comidList list again, this time with an Update cursor.
the indivdual NORTH and EAST values will be paired in the same order as your COMIDs.

yval1 = bigList[0][0][0]
xval1 = bigList[0][0][1]
yval2 = bigList[0][1][0]
xval2 = bigList[0][1][1]

map of indexes -> bigList[bigList index][nested pntValList index][nested pnt?List index]

gives you the y and x values for the first point pairs
perform your calculations and set your new item values.
use variables for the index numbers inside the square brackets so they incremant properly.
0 Kudos
markdenil
Occasional Contributor III
Oops.

Now append that comIdList to a new list (the bigList):
[[[north_val1, east_val1],[north_val2, east_val2]]]

should be:

Now append that pntValList to a new list (the bigList):
[[[north_val1, east_val1],[north_val2, east_val2]]]

... pntValList is the list of N & E values for the pair of points, and is what you want in bigList

my mistake...
0 Kudos
DavidHarlan
New Contributor
It took me awhile to understand your suggestion (my fault not yours).  But once I figured it out it worked like a charm.  Still took me about another day to get the script working but it works great now.  Thanks a lot mdenil! 

Don't know if my script is the most elegant thing but it functions correctly and I learned a whole lot writing it.

check it out if you like...I think I attached it to the post
0 Kudos