da Insert cursor writing empy geometry

3550
17
Jump to solution
09-27-2016 12:03 PM
ZacharyHart
Regular Contributor

I'll preface this by saying I'm pretty weak on cursors but trying to boot camp myself to basic proficiency.

I'm trying to create a simple script that will take a point feature class and create lines from them. These points are the start point of the the line and for sake of demonstration here, the endpoints are defined mathematically from them. Simple 2-point lines.

startingPt = "STARTING_POINTS" #point feature layer in MXD
fields = ['SHAPE@X', 'SHAPE@Y']

point = arcpy.Point()
array = arcpy.Array()

featureList = []
insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])

with arcpy.da.SearchCursor(startingPt, fields) as cursor:
 
    for row in cursor:
       startX = row[0]
       startY = row[1]
       array.add(point)
       endX = startX + 660
       endY = startY + 660
       array.add(point)
       polyline = arcpy.Polyline(array)
       insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])
       insert.insertRow([polyline])

       print "Start: {},{} End: {},{}".format(startX,startY,endX,endY)
del cursor

The script successfully writes rows to the target, but the geometry is empty. I'm sure there is a simple (and stupid) mistake in the code. Any help is appreciated and I'm totally open to suggestions. I'd rather not have a copy features or append operation but just an insert unless my logic is totally flawed here.

Thanks!

0 Kudos
1 Solution

Accepted Solutions
VikramS
Occasional Contributor

Hello, 

In your code you forgot to build the point . Hopefully that should fix your issue

  for row in cursor:
       startX = row[0]
       startY = row[1]

      point = arcpy.Point(startX , startY)
       array.add(point)
       endX = startX + 660
       endY = startY + 660
       array.add(point)
       polyline = arcpy.Polyline(array)
       insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])
       insert.insertRow([polyline])

View solution in original post

17 Replies
VikramS
Occasional Contributor

Hello, 

In your code you forgot to build the point . Hopefully that should fix your issue

  for row in cursor:
       startX = row[0]
       startY = row[1]

      point = arcpy.Point(startX , startY)
       array.add(point)
       endX = startX + 660
       endY = startY + 660
       array.add(point)
       polyline = arcpy.Polyline(array)
       insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])
       insert.insertRow([polyline])

View solution in original post

DanPatterson_Retired
MVP Esteemed Contributor

plus

point = arcpy.Point(endX , endY)
array.add(point)

otherwise the venture is pointless

ZacharyHart
Regular Contributor

Thanks! I just stumbled across another post wherein which someone was recalling words from you Dan Patterson‌ about setting the spatial reference...tried that and it wasn't the issue. I cleaned up the code a bit. Again, I'm totally up to suggestions, but this works!

startingPt = "STARTING_POINTS" #point feature layer in MXD
fields = ['SHAPE@X', 'SHAPE@Y']

#point = arcpy.Point()
array = arcpy.Array()
sr = arcpy.Describe(startingPt).spatialReference  

insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])

with arcpy.da.SearchCursor(startingPt, fields) as cursor:
 
    for row in cursor:
       startX = row[0]
       startY = row[1]
       endX = startX + 660
       endY = startY + 660

       array.add(arcpy.Point(startX, startY))
       array.add(arcpy.Point(endX, endY))

       insert = arcpy.da.InsertCursor(r"D:\Temp\Lines.shp",['SHAPE@'])
       polyline = arcpy.Polyline(array,sr)
       insert.insertRow([polyline])
       array.removeAll()

       print "Start: {},{} End: {},{}".format(startX,startY,endX,endY)

del cursor

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Looks like that should work, now that you have both the start and end points added to the array, you have enough points to form a 1D line, because it is possible to form a line with 1 point if you aren't careful.  The spatial reference is also critical since you will get geometry inaccuracies if not use.  

For commentary,

  • bullet-proof your code for python 3.x by changing all print statements to print functions ie. print(stuff goes in here)
  • although permissable, I would suggest collecting all your geometries that you want to create, then open up a new insertcursor outside of the searchcursor and create your geometries as you go along.

Otherwisey you are good-to-go

ZacharyHart
Regular Contributor

Dan_Patterson‌ Thanks so much for the suggestions! I'm currently in the process of adding rotation to each line with some basic trig. Regarding your suggestions:

  1. I implemented this; was totally unaware of this. Thanks!
  2. Are you suggesting I un-nest the two cursors? Again, I'm a real hack here, so if you had an example or reference that would  be great. Any harsh words/warnings regarding poor practice of the structure of cursors as they are now?
0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

no examples off hand, but Darren Wiens‌ does a lot of cursor work so probably has some examples on hand.

The only reason I suggest, is that you can produce functions (ie def blah( .... ) ) that may do basic search cursor work collecting shapes (for instance) and then a separate insertcursor that does the writing to a new file.

As for geometry, /blogs/dan_patterson/2016/09/01/distance-calculations-using-the-field-calculator has some field calculator expressions that can be stripped to get azimuth of 2 point polylines.  simply  degrees(arctan2(dy,dx)) in pseudocode where dy is difference in y .  Do not use for data in decimal degrees, it is a whole different equation.

DarrenWiens2
MVP Honored Contributor

You've got two identical lines that create an insert cursor. You only need to create it once - the line before you've created the search cursor. So, you may as well delete the line that re-creates the insert cursor within the search cursor.

As far as I'm concerned, it's ok to nest an insert cursor within a search or update cursor. I don't know the inner workings, but insert cursors (which run only when called) are quite different from search and update cursors (which loop through all features or those that meet the where clause criteria). You can run into trouble nesting any combination of search or update cursors, especially with large datasets, because it compounds the looping.

ZacharyHart
Regular Contributor

Darren,

thanks for picking up on my bonehead move there! Thanks for the additional insight regarding the cursors. Much appreciated!

0 Kudos
ZacharyHart
Regular Contributor

Dan, thanks for the insight and what a treasure trove in the article you wrote! Thanks!

0 Kudos