I am using ArcGIS Desktop 10.8 Basic. I do not have access to a Standard or Advanced license for this.

I want to use a point from a search cursor as an input for the arcpy.PolyLine() method. A second cursor will provide the point feature to be used as the and point of the polyline. My search cursor is on a point feature layer, and I'm using 'SHAPE@' as one of the fields in the cursor. This is vexing me to no end. In my mind - and this may be my downfall - there's no reason to drill down to the coordinate level.

Isn't it possible to get the geometry for the current cursor's point feature directly?

How do I actually get from two point features in a cursor as inputs for creating a polyline between them?

OR...does the arcpy.Polyline() method demand an array of coordinates?

I didn't think it did, but it's hard finding good examples. Nearly all the samples and examples I've found in my searches begin with a set of coordinate tuples, never a point feature from a cursor.

Here's the part of my script that is supposed to do the heavy lifting but doesn't work. Some variables are assigned earlier in the script, but I think you'll see my problems don't involve them. Both cursors are on point feature layers.

curfldsAP = ['SHAPE@', 'OID@', fldAPID, fldAPadd]
curfldsGP = ['SHAPE@', 'OID@', "Score", fldGPID]
curNewLine = arcpy.da.InsertCursor(lyrGCline, ['SHAPE@', "FULL_ADDRESS", "ADD_ID"])
with arcpy.da.SearchCursor(lyrAP, curfldsAP) as cur:
    for row in cur:
        linepoints = []
        ptSTART = arcpy.Point(row[0])
        id = row[2]
        add = row[3]
        wc = fldGPID + " = " + str(id)      # whereclause
        with arcpy.da.SearchCursor(lyrGP, curfldsGP, wc) as cur2:
            for row2 in cur2:
                if row2[2] >= 80:
                    ptEND = arcpy.Point(row2[0])
                    newLine = arcpy.Polyline(linepoints)
                    curNewLine.insertRow(newLine, add, id)

There's a number of issues here:

  • Both row[0] and row2[0] are already PointGeometry type objects, for which .firstPoint is the Point accessor property.
  • Use the arcpy.Array object to bundle the Points, as in the documentation.
  • Never, never, never use a Geometry constructor (arcpy.Point, arcpy.Polyline, arcpy.Polygon) without the SpatialReference of the target feature class in the spatial_reference parameter (unless you really want to waste time figuring out how your coordinate precision was truncated after insert/update).
  • This task calls for a dictionary cache, not nested cursors.

Manifesting it all looks something like this (not tested):

curfldsAP = ['SHAPE@', 'OID@', fldAPID, fldAPadd]
curfldsGP = ['SHAPE@', 'OID@', "Score", fldGPID]

apCache = {}
with arcpy.da.SearchCursor(lyrAP, curfldsAP) as cursor:
    for row in cursor:
        apCache[row[2]] = { 'point' : row[0].firstPoint, 'oid' : row[1], 'apAdd' :  row[3] }

gpCache = {}
with arcpy.da.SearchCursor(lyrGP, curfldsGP) as cursor:
    for row in cursor:
        gpCache[row[3]] = { 'point' : row[0].firstPoint, 'oid' : row[1], 'score' :  row[2] }

sr = arcpy.Describe(lyrGCline).spatialReference
with arcpy.da.InsertCursor(lyrGCline, ['SHAPE@', "FULL_ADDRESS", "ADD_ID"]) as cursor:
    for apKey in apCache:
        apRec = apCache[apKey]
        gpRec = gpCache[apKey]
        if (gpRec['score'] > 80):
            points = arcpy.Array()
            cursor.insertRow([arcpy.Polyline(points,sr), apRec['apAdd'], apKey])

Note that this makes assumptions about 1:1 relationships with keys. If it's 1,M : 0,1,M, the cache needs a different structure.

  • Yup, I knew there were issues. Is the spatial reference still necessary if the feature class that the insert cursor is acting on is in a feature dataset? Much for me to digest with the rest of this. For the record, I did succeed in making this work last night, although I know it can be better.
    – gkammerer
    Apr 30 at 15:40
  • Yes, applying the SpatialReference is required, because at the time the Geometry is constructed it doesn't know where the resulting shape will exist.
    – Vince
    Apr 30 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.