def countCategoricalPointTypesWithinPolygons(fcPoint, pointFieldName, fcPolygon, workspace): if arcpy.Exists(workspace): # check for valid workspace arcpy.env.workspace = workspace # sets workspace # Use SummarizeWithin_analysis tool in order to create a new feature class containing information from point feature class and polygon feature class # This tool also creates a new table that includes summary fields for each group of summary features for each input polygon arcpy.SummarizeWithin_analysis(fcPolygon, fcPoint, "Point_Poly", "", "", "", "", pointFieldName, '', '', "Count_Table") # Add field to polygon feature class for Point Count variable arcpy.AddField_management(fcPolygon, "Point_Count", "DOUBLE") # Use a set to get the unique names from the pointFieldName variable for use in later cursors uniqueNames = set([ row[0] for row in arcpy.da.SearchCursor(fcPoint, [pointFieldName]) ]) for Name in uniqueNames: # Iterates through each name # Create a new dictionary that will store values for use in cursors dict = {} # Set count to 0 so that it can be incremented in cursor count = 0 # Run cursor to search through the summarized table to fill dictionary and Point Count values with unique names with arcpy.da.SearchCursor( "Count_Table", ["Join_ID", pointFieldName, "Point_Count"]) as search_cur: for search_row in search_cur: if search_row[1] == Name: dict[search_row[0]] = search_row[2] count += 1 # Run cursor to update new Point Count field with values from summary table, search cursor, dictionary with arcpy.da.UpdateCursor(fcPolygon, ["FIPS", "Point_Count"]) as upd_cur: for upd_row in upd_cur: if upd_row[0] in dict.keys(): upd_row[1] = dict[upd_row[0]] upd_cur.updateRow(upd_row) del row del cursor arcpy.management.CopyFeatures(Point_Poly, fcPolygon) arcpy.management.Delete(Point_Poly, Count_Table) else: print("Invalid workspace")
def countPointsByTypeWithinPolygon(input_geodatabase, fcPoint, pointFieldName, pointFieldValue, fcPolygon): if arcpy.Exists(input_geodatabase): # check for valid workspace arcpy.env.workspace = input_geodatabase # sets workspace # Use SummarizeWithin_analysis tool in order to create a new feature class containing information from point feature class and polygon feature class # This tool also creates a new table that includes summary fields for each group of summary features for each input polygon arcpy.SummarizeWithin_analysis(fcPolygon, fcPoint, "Point_Poly", "", "", "", "", pointFieldName, '', '', "Count_Table") # Add field to polygon feature class for Point Count variable arcpy.AddField_management(fcPolygon, "Point_Count", "DOUBLE") # Create a new dictionary that will store values for use in cursors dict = {} # Set count to 0 so that it can be incremented in cursor count = 0 # Run cursor to search through the summarized table to fill dictionary and Point Count values with arcpy.da.SearchCursor( "Count_Table", ["Join_ID", pointFieldName, "Point_Count"]) as search_cur: for search_row in search_cur: if search_row[1] == pointFieldValue: dict[search_row[0]] = search_row[2] count += 1 # Run cursor to update new Point Count field with values from summary table, search cursor, dictionary with arcpy.da.UpdateCursor(fcPolygon, ["FIPS", "Point_Count"]) as upd_cur: for upd_row in upd_cur: if upd_row[0] in dict.keys(): upd_row[1] = dict[upd_row[0]] upd_cur.updateRow(upd_row) else: print("Invalid workspace")
summarize_within_args = { 'in_polygons': pda_fc, 'in_sum_features': in_sum_features, 'out_feature_class': out_feature_class, 'keep_all_polygons': True, 'sum_fields': None, 'sum_shape': True, 'shape_unit': 'ACRES', 'group_field': group_field, 'add_min_maj': False, 'add_group_percent': True, 'out_group_table': out_group_table } arcpy.SummarizeWithin_analysis(**summarize_within_args) # Rename fields in join table created based on PDA Eligible Areas Designation field names_dict = { 'Join_ID': 'Summary_ID', 'SUM_area_ACRES': 'Acres_Intersect', 'PercentArea': 'Percent_Intersect' } clear_alias = 'TRUE' rename_fields(out_group_table, names_dict, clear_alias) # Join to PDA summary feature class created as result of Sumarize Within step in_layer = 'Draft_Regional_PDA_2019_Eligibility' join_table = 'Draft_Regional_PDA_2019_Eligibility_Designation_Summary_Table'
def countObservationsWithinDistance(fcPoint, distance, distanceUnit, geodatabase="assignment2.gdb"): arcpy.env.workspace = geodatabase #Quick exception handling for file type describePoint = arcpy.Describe(fcPoint) describeWork = arcpy.Describe(geodatabase) distance = float(distance) distanceUnit = distanceUnit.upper().replace(" ", "") Unit_List = ["METERS", "KILOMETERS", "FEET", "YARDS", "MILES"] #see if the distance value can be turned into a float try: distance = float(distance) except: print("The distance needs to be a number") return if describePoint.shapetype != "Point" or describeWork.dataType != "Workspace": print("You did not give me the correct file types.") elif distanceUnit.upper() not in Unit_List: print("{0} is not a feasible distance unit".format(distanceUnit)) else: #create a buffer around the cities fc_buffer = "fcPoint_buffer" #buffer distance buffer = str(distance) + " {0}".format(distanceUnit) # specify the type of buffer analysis based on the SR of fcPoint if describePoint.spatialReference.type == "Projection": method = "PLANER" else: method = "GEODESIC" #execute the buffer arcpy.Buffer_analysis(fcPoint, fc_buffer, buffer, "#", "#", "#", "#", method) #specify new feature class fc_counts = "fc_cities_count" # this counts the number of points inside each buffer, creates # new feature class with the counts. We calculate the counts, put them in a # dictionary, and then merge the counts with the original FC arcpy.SummarizeWithin_analysis(fc_buffer, fcPoint, fc_counts) #go through the new feature class, grab the ID and count of cities # and put into a dictionary d_count = {} with arcpy.da.SearchCursor(fc_counts, ["FID_1", "Point_Count"]) as cursor: for row in cursor: d_count[row[0]] = row[1] del row del cursor #use this dictionary to update the original point feature class #create new field to hold our counts count_field = "Point_Count" arcpy.management.AddField(fcPoint, count_field, "SHORT") with arcpy.da.UpdateCursor(fcPoint, ["FID_1", count_field]) as cursor: for row in cursor: #Check if the geoid is in the dictionary if row[0] in d_count.keys(): #if the id exists, update the field with the value given by the key in the dictionary row[1] = d_count[row[0]] #if the geoid is not in the dictionary, make it equal to zero else: row[1] = 0 cursor.updateRow(row) del row del cursor #delete created feature classes and tables arcpy.management.Delete([fc_counts, fc_buffer])
def countPointsByTypeWithinPolygon(input_geodatabase, fcPoint, pointFieldName, pointFieldValue, fcPolygon): # Set local variables arcpy.env.workspace = input_geodatabase #Quick exception handling for file type describePoint = arcpy.Describe(fcPoint) describePoly = arcpy.Describe(fcPolygon) field_list = [] for field in arcpy.ListFields(fcPoint): field_list.append(field.name) if describePoint.shapetype != "Point" or describePoly.shapetype != "Polygon" or describeWork.dataType != "Workspace": print("You did not give me the correct file types.") elif pointFieldName not in field_list: print("{0} is not a field in {1}".format(pointFieldName, fcPoint)) else: # create variables polys = fcPolygon points = fcPoint fcOut = "points_in_polygon" fcOutTable = "points_per_group" #count the number of points in each polygon arcpy.SummarizeWithin_analysis(polys, points, fcOut, '', '', '', '', pointFieldName, '', '', fcOutTable) #Create dictionary of pointFieldName values dict_pointFieldValue = {} #Put number of points (of specific type) in dictionary for each block group #In this case, we will use the join id in the table for the key, and then #index the output feature class from summarize within #another exception handling: making sure pointValueName is in pointFieldname #at least once count = 0 #create dictionary with keys = join ids and values = how many facilities # of that type are in the block group with arcpy.da.SearchCursor(fcOutTable, ["Join_ID", pointFieldName, "Point_Count"]) as cursor: for row in cursor: #check if the facility is the type we want if row[1] == pointFieldValue: count += 1 dict_pointFieldValue[row[0]] = row[2] del row del cursor #if the type we want does not show up at all, stop what we are doing if count == 0: return "{0} is not a value in {1}".format(pointValueName, pointFieldName) #now use update cursor to update the output feature class from summarize within # using the join_id value created as an index #create the field without white spaces that will hold the values fcOut_pointFieldValue = pointFieldValue.replace(" ", "_") arcpy.management.AddField(fcOut, fcOut_pointFieldValue, "SHORT") #using the dictionary we created, check each join_id and if it is in the dictionary #update the field we just created with the count in that block group with arcpy.da.UpdateCursor(fcOut, ["Join_ID", fcOut_pointFieldValue]) as cursor: for row in cursor: #Check if the geoid is in the dictionary if row[0] in dict_pointFieldValue.keys(): #if the id exists, update the field with the value given by the key in the dictionary row[1] = dict_pointFieldValue[row[0]] #if the geoid is not in the dictionary, make it equal to zero else: row[1] = 0 cursor.updateRow(row) del row del cursor #set the new feature class equal to the original feature class arcpy.management.CopyFeatures(fcOut, fcPolygon) #delete created feature classes and tables arcpy.management.Delete([fcOut, fcOutTable]) #delete unnecessary fields that were created in the fcPolygon file arcpy.management.DeleteField(fcPolygon, ["Point_Count", "Join_ID"])
def countCategoricalPointTypesWithinPolygons(fcPoint, pointFieldName, fcPolygon, workspace): arcpy.env.workspace = workspace #Quick exception handling for file type describePoint = arcpy.Describe(fcPoint) describePoly = arcpy.Describe(fcPolygon) describeWork = arcpy.Describe(workspace) field_list = [] for field in arcpy.ListFields(fcPoint): field_list.append(field.name) if describePoint.shapetype != "Point" or describePoly.shapetype != "Polygon" or describeWork.dataType != "Workspace": print("You did not give me the correct file types.") elif pointFieldName not in field_list: print("{0} is not a field in {1}".format(pointFieldName, fcPoint)) else: #set up variables polys = fcPolygon points = fcPoint fcOut = "points_in_polygon" fcOutTable = "points_per_group" #count the number of points in each polygon, in specific groups of facilities arcpy.SummarizeWithin_analysis(polys, points, fcOut, '', '', '', '', pointFieldName, '', '', fcOutTable) #Similar to before, create a dictionary with counts #We will use a nested dictionary that will take {ID:{facility type:count, facility type:count}} #in case there are more than one type of facility in a block group #Also, create a list of the types of facilities during this loop #so we do not have to loop again in the future d = {} fields = [] with arcpy.da.SearchCursor(fcOutTable, ["Join_ID", pointFieldName, "Point_Count"]) as cursor: for row in cursor: #clean up field name so it has no whitespaces and <14 letters #otherwise, arcpy will make the alias different from the field name field = row[1].replace(" ", "").replace("-","").lower()[:13] #create list of type of facility if field in fields: continue else: fields.append(field) #if the ID is in the output table (i.e. has at least one facility) #create a dictionary key for that ID so we can store the facility type and count if row[0] in d.keys(): continue else: d[row[0]] = {} # store the count of each specific facility type inside the dictionary # for the given ID d[row[0]][field] = row[2] del row del cursor #now use update cursor to update the output feature class from summarize within # using the join_id value created as an index #for each facility type we have, create a field that will hold # the number of that type of facility in each block group for field in fields: arcpy.management.AddField(fcOut, field, "SHORT") #append Join_ID to our fields list so we can use it in the update cursor fields.append("Join_ID") #use update cursor to use the dictionary to create the counts for each # type of facility in each respective block group (ID) #importantly - updating the output feature class from summary analysis #, which has the Join_ID field added with arcpy.da.UpdateCursor(fcOut, fields) as cursor: for row in cursor: #Check if the ID is in the dictionary #Join_ID is the last value of our "fields" list # row seems to have a tough time with row[fields.index("insert field value")], # so instead we create variables in this loop to avoid using # any extra tools ID = row[-1] if ID in d.keys(): #if Join_ID is in the dictionary, go through each type of facility for field in fields[:-1]: index = fields.index(field) #if that type of facility is a key in the nested dictionary # for that particular block group, update the # field for that type of facility in fcOut with the count #otherwise, update the field for that type of facility as zero if field in d[ID].keys(): row[index] = d[ID][field] else: row[index] = 0 else: #if the join_id is not in the dictionary, then the block group did # not have any points. Go through each of the created fields # for each type of facility and enter zero. for field in fields[:-1]: index = fields.index(field) row[index] = 0 cursor.updateRow(row) del row del cursor #set the new feature class equal to the original feature class arcpy.management.CopyFeatures(fcOut, fcPolygon) #delete created feature classes and tables arcpy.management.Delete([fcOut, fcOutTable]) #delete unnecessary fields that were created in the fcPolygon file arcpy.management.DeleteField(fcPolygon, ["Join_ID"])
if model_year == 2015: # current transit_features = ['trn_cur_cat5'] elif model_year == 2050: # no plan and blueprint transit_features = ['trn_np_cat5', 'trn_fp_cat5'] for transit_feature in transit_features: logger.info('Summarizing {} parcel data proximity to {}'.format(model_year, transit_feature)) log_workspace_contents(logger) try: logger.info("feature classes no paths") arcpy.SummarizeWithin_analysis(transit_feature, 'parcel_fc', 'prox', keep_all_polygons="KEEP_ALL", sum_fields=[['tothh','SUM'], ['hhq1','SUM'],['totemp','SUM'],['RETEMPN','SUM'],['MWTEMPN','SUM']]) # hasn't worked, see comments below logger.info("SUCCESS") except: # Get the tool error messages msgs = arcpy.GetMessages(2) logger.error("Exception occured; msgs: {}".format(msgs)) # Get the traceback object tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] # Concatenate information together concerning the error into a message string logger.error("Traceback info:\n{}\nError Info:\n{}".format(tbinfo, str(sys.exc_info()[1]))) logger.error("It's ok though -- we'll do this another way, but still trying the easy way")