4

I have two shapefiles. One contains many points across a state. The other is all the counties within the state. I would like to do two things:

  1. use a cursor to count how many points are in each county and then populate a new field with those data; and
    1. create a true/false field in which true = the county contains more than two points.

I started the first one but was unsuccessful, so the second I'm not sure how to accomplish. This is what I have so far...

import arcpy

points = r"C:\Users\points"
counties = r"C:\Users\counties"
#create new fields
arcpy.AddField_management(counties, "numOfPoints", "LONG", field_length = 10)
arcpy.AddField_management(counties, "hasTwoPoints", "LONG", field_length = 10)

points_lyr = arcpy.MakeFeatureLayer_management(points,r'in_memory\points_lyr')
counties_lyr = arcpy.MakeFeatureLayer_management(counties,r'in_memory\counties_lyr')
# Create an update cursor to access and update states features
#NAME has names of counties and numPoints will be populated with number of points 
fields = ['NAME','numOfPoints','hasTwoPoints']

with arcpy.da.UpdateCursor(counties_lyr,fields) as cur:
    for row in cur:
        county = row[0]
        where = '"NAME" = \'{}\''.format(county)
        arcpy.SelectLayerByAttribute_management(counties_lyr,'NEW_SELECTION',where)
        arcpy.SelectLayerByLocation_management(points_lyr,'INTERSECT',counties_lyr)
        number_of_points = int(arcpy.GetCount_management(counties_lyr).getOutput(0))
        row[1] = number_of_points
        cur.updateRow(row)
print('Operation complete.')

The current script works, but it populates the field 'numOfPoints' with all 1 values which is not correct.

then at the end to add the true/false based on the output to be a stand alone script,

fields2 = ['numOfPoints','hasTwoPoints']

with arcpy.da.UpdateCursor(counties_lyr,fields2) as cur:
   for row in cur:
       if row[0] > 1: row[1] = 'TRUE'
   else: row[1] = 'FALSE'
   cur.updateRow(row)

I get this error: StopIteration: iteration not started

2
  • 1
    Can you add a message pop-up or print the contents of your variables where, number_of_points, and row[1]? This may help you troubleshoot the problem. You can delete this message or print command once you've narrowed down and fixed the issue. Also, where you assign number_of_points, it appears you may be getting the count of the number of counties selected, not the count of the rigs_lyr layer. Oct 4, 2016 at 14:33
  • You can use the spatial join tool to create a new shapefile. The resulting shapefile will have a new attribute listing the number of points in each polygon. Then use a select by attribute and a field calculation to identify those records with a count of two or more. If you still want to use the Python approach look at geometry objects which include a method to return point counts in polygons. This approach will work faster than all the selections you have.
    – GBG
    Oct 4, 2016 at 14:44

1 Answer 1

5

You've got one line messed up:

When you calculate number_of_points, you want to GetCount the points_lyr, not the counties_lyr.

with arcpy.da.UpdateCursor(counties_lyr,fields) as cur:
    for row in cur:
        county = row[0]
        where = '"NAME" = \'{}\''.format(county)
        arcpy.SelectLayerByAttribute_management(counties_lyr,'NEW_SELECTION',where)
        arcpy.SelectLayerByLocation_management(points_lyr,'INTERSECT',counties_lyr)
        number_of_points = int(arcpy.GetCount_management(points_lyr).getOutput(0))
        row[1] = number_of_points
        cur.updateRow(row)
print('Operation complete.')

To do the second part of your question, you've got to clear all the selections:

arcpy.SelectLayerByAttribute_management(counties_lyr, "CLEAR_SELECTION")
arcpy.SelectLayerByAttribute_management(points_lyr, "CLEAR_SELECTION")

fields2 = ['numofpoints','has2points']

with arcpy.da.UpdateCursor(counties_lyr,fields2) as cur:
    for row in cur:
        if row[0] > 1:
            row[1] = 1
        else:
            row[1] = 0
        cur.updateRow(row)
4
  • You were right. Thanks. And how would I populate a new field if the previous calculation was greater than or equal to 2? Meaning the county has more than 1 point in it...
    – dand
    Oct 4, 2016 at 15:03
  • Below the cur.updateRow(row), I would add: if row[1] > 1: row[2] = 1 else: row[2] = 0 cur.updateRow(row)
    – Jvhowube
    Oct 4, 2016 at 15:10
  • With this code, it only populates the last row in the table. But above is another set of stand alone code but it's giving an error message.
    – dand
    Oct 4, 2016 at 15:32
  • Check out the edits above - it works now.
    – Jvhowube
    Oct 4, 2016 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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