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:
- use a cursor to count how many points are in each county and then populate a new field with those data; and
- 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
-
1Can 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– Zachary Ordo - GISP2016年10月04日 14:33:26 +00:00Commented 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– GBG2016年10月04日 14:44:08 +00:00Commented Oct 4, 2016 at 14:44
1 Answer 1
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– dand2016年10月04日 15:03:43 +00:00Commented 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– Jvhowube2016年10月04日 15:10:05 +00:00Commented 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– dand2016年10月04日 15:32:13 +00:00Commented Oct 4, 2016 at 15:32
-
Check out the edits above - it works now.Jvhowube– Jvhowube2016年10月04日 15:54:47 +00:00Commented Oct 4, 2016 at 15:54