arcpy.da.InsertCursor SHAPE_length and SHAPE_Area fields are shown as zero

2125
11
08-04-2016 01:47 PM
JoseSanchez
Occasional Contributor III

Hello everyone,

The goal is to find all the records that were deleted  comparing yesterday and today versions of the same feature class.

I am running a python script that uses cursors. With the curosr I am able to identigy the record that was deleted because it was in the featuer class yesterday but not today.

When I insert a new record using "arcpy.da.InsertCursor", "curAppend.insertRow( rowYesterday)",  two fields SHAPE_length and SHAPE_Area are equal to 0. ArcCatalog does not show any shape information in the preview, but shows only attributes in the Table view. It looks like features were created witout spatial data,  only attributes.

dsc = arcpy.Describe(Layer_DEFAULT)
    fields = dsc.fields
    #
    # List all field names except the OID field
    #
    fieldnames = [field.name for field in fields if field.name != dsc.OIDFieldName]


    curYesterday = arcpy.da.SearchCursor(Layer_DEFAULT, fieldnames)
    curToday = arcpy.da.SearchCursor(Layer_PREPROD, fieldnames)
    curAppend = arcpy.da.InsertCursor(Layer_D,fieldnames)


    for  rowYesterday in curYesterday:
        #
        # layerID  = layerID
        # datetimeVal  = CRTDATE
        #
        layerID = rowYesterday[0]
        datetimeVal = rowYesterday[4]


        #print rowYesterday[1]
        #print rowYesterday[2]
        #print rowYesterday[3]
        #print rowYesterday[4]
        #print rowYesterday[5]
        #print rowYesterday[0]






        if datetimeVal is not None:


            whereClause = '"AGMID" = %s' % (layerID)


            srcToday = arcpy.da.SearchCursor(Layer_PREPROD, fieldnames, whereClause)


            count = 0


            for  rowToday in srcToday:


                if  rowToday[4] == rowYesterday[4]:
                    count = count + 1


            if count == 0:
                print "Record for Delete :", layerID
                logging.info('Delete ' + whereClause)
                curAppend.insertRow( rowYesterday)
0 Kudos
11 Replies
DarrenWiens2
MVP Honored Contributor

The thing that jumps out to me is that you start several cursors, never use one of them, and never delete them. You should use 'with' syntax, which cleans up your cursors even if they error out, and avoid seemingly random errors - which you seem to be experiencing.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

get the shapefieldName explicitly from the featureclass describe object

FeatureClass properties—Help | ArcGIS for Desktop

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

You are running into a couple different issues:

  • Your list comprehension for building a list of field names excludes the OID field, but it still includes the SHAPE_Length and SHAPE_Area fields.  The user doesn't directly populate these fields, they are automatically calculated on the backend, except with in-memory workspaces.  It is fine to retrieve the fields and use the values, but you should not try to populate the values for new records.
  • Although the shape field's name may be, "SHAPE," passing "SHAPE" to a cursor doesn't actually retrieve the geometry, it retrieves a tuple of the feature's centroid.  Passing "SHAPE" is the same as passing "SHAPE@XY".   When you pass "SHAPE" to the insert cursor, you are creating a point, which has no area nor length.
DanPatterson_Retired
MVP Esteemed Contributor

Joshua you can use Shape@ to return the shape, then get its area/perimeter/length for poly* features. The advantage of retrieving the shape field directly, is that it works wih shapefile which have no auto-calculated shape properties.

JoshuaBixby
MVP Esteemed Contributor

Dan, I agree.  My comments to the OP were to point out that he is likely not retrieving what he thinks he is in terms of geometry.  The OP used arcpy.Describe to retrieve the name of the shape field, but he did not add the @ symbol.  I may be incorrect, but the code and description of the problem made me think he wanted to retrieve the actual geometry and not a tuple of a feature's centroid.

0 Kudos
JoseSanchez
Occasional Contributor III

Hi dkwiens,  this is a piece of the code not the whole script. I delete the cursors at the end.

0 Kudos
JoseSanchez
Occasional Contributor III

Hi Dan, if I understand correctly I need to use "Shape@" to populate all shape fields when creating a polygon.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

writing geometries

InsertCursor—Help | ArcGIS for Desktop

Writing geometries—Help | ArcGIS for Desktop

require special attention.  The area and length (for polygons) will be populated once the geometry is created and the editing is done.  If you want a point representation of the polygon, then use the appropriate option in the first link.

0 Kudos
JoseSanchez
Occasional Contributor III

Hi all,

I just harcoded the list of fields:

fieldnames = ['AGMID', 'MODBY', 'MODDATE', 'CRTBY', 'CRTDATE', 'SHAPE@']

and it works