Python, Arc10 - copy shape field contents from one table to another.

2455
14
11-17-2010 04:39 AM
JohnSanders
Emerging Contributor
This is just a read from one table (shapefile) and a write to another table (shapefile).
This would work in 9.3.1 (SP1, SP2) but no longer in 10, with or without SP1:

>>> copyShape = Arow.shape
>>> arrayShape = copyShape.getPart( )
>>> Crow.setValue( 'Shape', arrayShape )     # or Crow.shape = arrayShape

error is:
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\arcobjects.py", line 941, in setValue
    return convertArcObjectToPythonObject(self._arc_object.SetValue(*gp_fixargs(args)))
RuntimeError: ERROR 999999: Error executing function.

This is a polyline shape.  Arow is a searchCursor, Crow is an insertCursor.
type(arrayShape) gives: <class 'arcpy.arcobjects.arcobjects.Array'>, and it looks to be populated OK.

I also have a point copy I'm getting ready to test, so if there is a separate fix for that you might know of, I'd appreciate mention of that, too.

Thanks.
0 Kudos
14 Replies
ChrisSnyder
Honored Contributor
I can't speak to 10 (too many bugs yet to move over), but I can verify that this sort of thing did work in v9.3. Here's some v93 code.
0 Kudos
ChrisSnyder
Honored Contributor
I can't help you with v10, but if it ain't working there (in v10) it sounds like a bug. You should report it to esri. On a side: Pretty quickly I figuered out that due to a variety of bugs, v10 was not stable/compatible for much of my existing v9.3 and v9.2 Python code (this issue being yet another great example), so I guess that's why I haven't moved over there yet. I'll have to eventually though, and it won't be pretty...

Excerpt of a v9.3 script that, among other things, gets a shapefield value (searchcursor) and inserts it into a new sorted table (insertcursor) - Works great in v9.3
#Process: Now write the sorted records to the new FC
message = "Sorting fields..."; showPyMessage()
searchRows = gp.searchcursor(inputLayer, "", "", "", fieldSortString[:-1])
searchRow = searchRows.next()
message = "Writing sorted records! Please wait..."; showPyMessage()
insertRows = gp.insertcursor(outputLayer)
recordCount = 0
inputLayerOidFieldName = dsc.oidfieldname
origOidPopulateSuccessFlag = True
while searchRow:
    #Process: Every 1000 rows give a message about the progress of the cursors            
    recordCount = recordCount + 1
    if divmod(recordCount,1000)[1] == 0:
        message = "Writing row = " + str(i) + "..."; showPyMessage()
    #Now read the old table and populate the new one
    insertRow = insertRows.newrow()
    for fieldName in inputLayerFieldList:
        try: #you can't write the OID, length, area, etc. fields
            if outShpDbfFlag == False:
                insertRow.setvalue(fieldName, searchRow.getvalue(fieldName))
                if originalOidFieldName not in ["","#"," "]:
                    try:
                        insertRow.setvalue(originalOidFieldName, searchRow.getvalue(inputLayerOidFieldName))
                    except:
                        origOidPopulateSuccessFlag = False
                        pass
            else:
                insertRow.setvalue(fieldName[0:10], searchRow.getvalue(fieldName))
                if originalOidFieldName not in ["","#"," "]:
                    try:
                        insertRow.setvalue(originalOidFieldName[0:10], searchRow.getvalue(inputLayerOidFieldName))
                    except:
                        origOidPopulateSuccessFlag = False
                        pass
        except:
            pass
    insertRows.insertrow(insertRow)        
    searchRow = searchRows.next()
0 Kudos
ChrisSnyder
Honored Contributor
Also, in your code, why not just:

Crow.setValue( 'Shape', Arow.shape)

Why do the getpart() step?

Also, are you sure that your Shape field is actually called shape?

#v10 code? (not sure if it'll work)
shapeFieldName = arcpy.describe(myFC).shapefieldname
Crow.setValue(shapeFieldName, Arow.shape)
0 Kudos
JohnSanders
Emerging Contributor
Thanks for the reply.

I may tried your alternate, shortcut one-liner -- same error in 10.  I don't recall if I tried it or not in my 9.3 code.  That code has been working well for a long time.  (Do you ever revisit your older stuff and say, "What the #^$% was this guy thinking?").  I'll give your code a try a little later and let you know.  Thanks for it!

I'm finding that tools/functions in 10 are case sensitive now, and that setting .workspace and .toolbox don't necessarily mean anything (depends on the tool you're using!).

PS.  My point writes that I mentioned above, worked.  Yeah, ESRI!

PPS. In the OP I meant to say that Arow came from a SearchCursor.next( ) and Crow came from an InsertCursor.newRow( ).
0 Kudos
JohnSanders
Emerging Contributor
Chris,

    I have tried all of your suggestions with no good result.  I do not see that you do anything special for 'Shape' writes in your code example.  I can't really explain my use of .getPart( )!  Maybe it makes no difference?  I'm going to have to experiment on a 9.3.1 machine around here.

    Thank you for your input, though -- much appreciated.
0 Kudos
ChrisSnyder
Honored Contributor
Not sure about the Spatial Adjustment toolbar (I think an automated method is probably required here), but I should ask:

Why do you need to copy the spatial data. I am guessing there is a good reason, but why not just use CopyFeatures() or something?

Also, I'll point out that v10 does support

import arcgisscripting
gp = arcgisscripting.create()

so you could use arcpy and gp functionality together in the same script...

Do you ever revisit your older stuff and say, "What the #^$% was this guy thinking?


Ha! Always, but I have found that ~80% of the time when this happens, I will start rewriting the code in a "better" way only to find that yes, there was a reason I did it that way in the 1st place, and the last 2 hours I spend "correcting" the code has been totally wasted!

.getpart() is the method to iterate through the 'parts' of multipart shapes (which in my opinion are an abomination! I hate multipart shapes!!!). Maybe it's there for a good reason, but I don't have enough of your code to see.
0 Kudos
JohnSanders
Emerging Contributor
Hey guys,

     What I'm doing is receiving a bunch of road center-line files from a bunch of different agencies.  Their data dictionaries do not match ours (needless to say).  I create a new shapefile from a template that has our data dictionary, read the relevant fields from the agency, convert type, length, etc. if necessary, parse the street name fields and fill in the row.  I need their Shape field, so it's just natural to copy it in along with everything else.  I suppose I could copy their file, save the data, delete their fields (except for Shape), add in our fields, and continue from there.  But just to get around one instruction? ...which hopefully will start working soon?  Easier to go back to 9.3 if you ask me.

     It looks to me like getPart( ) returns the entire array if no argument is given, or a specific part depending upon a numerical argument (where is the documentation on that?).  All I know is it worked in 9.3.1 SP2 but I have not had a chance to revisit it.

     I cannot see what SA will do for me.  Never looked at the python API for it.  I will check it out.

     arcpy & arcgisscripting together?  Ho!  You're kidding me!  How did you ever discover that?  I'm definitely going to try that. 

     And, you are right about reviewing your code.  I'll have to quit doing that or start writing better comments.

     I've only been on 10 for a couple of weeks or so.  It's great to get input from you guys that have been using it for a while.

     Y'all have a great holiday -- and thanks for the help.
0 Kudos
ChrisSnyder
Honored Contributor
How bout just use the Append tool (with the field mapping object) to append their data into your template?
0 Kudos
JohnSanders
Emerging Contributor
Just ran Append on one of my input files.  It only copied 477 out of 2592 features.  The ones it did all look correct.  Is there a log file for this?  It did not hit a bad geometry, this input has been checked for that.  There was no error message.

Setting up the Field Map was tedious.  I have a little GUI that does that where everything is displayed at once and you can copy/paste from a list to text boxes.  It also does pretty good at guessing the matching fields.  At any rate, all the field maps have been pickled, so I just have to look for any changes that the agency might have made since the previous year.

My street name parser is integrated into my conversion script, the Label field is generated, and Zip, County, and City fields are generated from spatial matches on our respective databases.

I just have to pick an agency folder, verify the field map, hit execute, and go do something else while it runs.  I'd be hard pressed to give up my script.

Is there any way to have 2 attribute tables viewable at the same time?  That's a weird change.
0 Kudos