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

  • 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. – Zachary Ordo - GISP Oct 4 '16 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 '16 at 14:44
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)
  • 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 '16 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 '16 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 '16 at 15:32
  • Check out the edits above - it works now. – Jvhowube Oct 4 '16 at 15:54

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.