I am trying to get a number of points in polygons based on row values, and write them into attribute table of polygons. I have polygon (Zones), and points (Objects with fields such as schools, markets, hotels, shops) which are located in those polygons. I want to select points based on their attributes (for example i want to know how many schools are in my polygon, and write it into a field. and repeat that process for other attributes for how many hotels/markets/shops are there in polygon zones, etc).
There was a similar question and this answer was good to Count number of attributes for unique field values, but only for selection by location. That script returned count from all number of objects in polygon zones, and it was not based on attributes, just on location.
I managed to modify the script, from the given link. This is the code, and I get result, sum of all points and it was written into row:
import arcpy
Objects = r'D:\GIS_Temp\Points.shp'
Zones = r'D:\GIS_Temp\Zones.shp'
Objects_lyr = arcpy.MakeFeatureLayer_management(Objects,r'in_memory\Objects_lyr')
Zones_lyr = arcpy.MakeFeatureLayer_management(Zones,r'in_memory\Zones_lyr')
fields = ['Descrip','Point_Sum']
with arcpy.da.UpdateCursor(Zones_lyr,fields) as cur:
for row in cur:
Zones = row[0]
where = '"Descrip" = \'{}\''.format(Zones)
arcpy.SelectLayerByAttribute_management(Zones_lyr,'NEW_SELECTION',where)
arcpy.SelectLayerByLocation_management(Objects_lyr,'INTERSECT',Zones_lyr)
Point_Sum = int(arcpy.GetCount_management(Objects_lyr).getOutput(0))
row[1] = Point_Sum
cur.updateRow(row)
print('Operation complete.')
And this is the result:
But I want to update Zones, based on intersecting Objects, but based on attributes, and update rows in Zones, with number of intersecting objects (Hotels, Shops, Markets, Schools).
What am I missing i my code. I suppose it has something to with selection by attributes, or with loop as suggested in comments, I should create loop within a loop, but I am not sure where to put it, and how. I understand why, but do not know how.
EDIT:
I tried to modify code, like this, so I made selection by attribute individually and try to put them in their own row, but with no luck. Code ok, there are not any errors, but it does not update anything.
Is there any modification to this, which would speed up my workflow, in case I have more than four values (like in this example; schools, etc)? This is the code:
import arcpy
Objects = r'D:\GIS_Temp\Points.shp'
Zones = r'D:\GIS_Temp\Zones.shp'
ObjectsSCHOOLS_lyr = arcpy.MakeFeatureLayer_management(Objects,r'SCHOOLS', "\"Name\" = 'Schools'")
ObjectsMARKETS_lyr = arcpy.MakeFeatureLayer_management(Objects,r'MARKETS', "\"Name\" = 'Markets'")
ObjectsHOTELS_lyr = arcpy.MakeFeatureLayer_management(Objects,r'HOTELS', "\"Name\" = 'Hotels'")
ObjectsSHOPS_lyr = arcpy.MakeFeatureLayer_management(Objects,r'SHOPS', "\"Name\" = 'Shops'")
Zones_lyr = arcpy.MakeFeatureLayer_management(Zones,r'in_memory\Zones_lyr')
fields = ['Descrip','Schools_Nr', 'Markets_Nr', 'Hotels_Nr', 'Shops_Nr']
with arcpy.da.UpdateCursor(Zones_lyr,fields) as cur:
for row in cur:
state = row[0]
where = '"Descrip" = \'{}\''.format(Zones)
arcpy.SelectLayerByAttribute_management(Zones_lyr,'NEW_SELECTION',where)
arcpy.SelectLayerByLocation_management(ObjectsSCHOOLS_lyr,'INTERSECT',Zones_lyr)
Schools_Nr = int(arcpy.GetCount_management(ObjectsSCHOOLS_lyr).getOutput(0))
row[1] = Schools_Nr
cur.updateRow(row)
for row in cur:
state = row[0]
where = '"Descrip" = \'{}\''.format(Zones)
arcpy.SelectLayerByAttribute_management(Zones_lyr,'NEW_SELECTION',where)
arcpy.SelectLayerByLocation_management(ObjectsMARKETS_lyr,'INTERSECT',Zones_lyr)
Markets_Nr = int(arcpy.GetCount_management(ObjectsMARKETS_lyr).getOutput(0))
row[1] = Markets_Nr
cur.updateRow(row)
for row in cur:
state = row[0]
where = '"Descrip" = \'{}\''.format(Zones)
arcpy.SelectLayerByAttribute_management(Zones_lyr,'NEW_SELECTION',where)
arcpy.SelectLayerByLocation_management(ObjectsHOTELS_lyr,'INTERSECT',Zones_lyr)
Hotels_Nr = int(arcpy.GetCount_management(ObjectsHOTELS_lyr).getOutput(0))
row[1] = Hotels_Nr
cur.updateRow(row)
for row in cur:
state = row[0]
where = '"Descrip" = \'{}\''.format(Zones)
arcpy.SelectLayerByAttribute_management(Zones_lyr,'NEW_SELECTION',where)
arcpy.SelectLayerByLocation_management(ObjectsSHOPS_lyr,'INTERSECT',Zones_lyr)
Shops_Nr = int(arcpy.GetCount_management(ObjectsSHOPS_lyr).getOutput(0))
row[1] = Shops_Nr
cur.updateRow(row)
print('Operation complete.')