def test_binary_point_coverage(self): binary_coverage_point = arcpy_analysis.generate_binary_coverage( self.demand_point_fl, self.facility_service_areas_fl, "Population", "GEOID10", "ORIG_ID") binary_coverage_point2 = arcpy_analysis.generate_binary_coverage( self.demand_point_fl, self.facility2_service_areas_fl, "Population", "GEOID10", "ORIG_ID") self.assertEqual(self.binary_coverage_point, binary_coverage_point) self.assertEqual(self.binary_coverage_point2, binary_coverage_point2)
# Read the demand polygon layer # Demand polygon shapefile has 212 polygons each where each feature has a demand (population) and unique identifier (GEOID10) demand_polygon_fl = arcpy.MakeFeatureLayer_management( r"../sample_data/demand_polygon.shp").getOutput(0) # Read the facility service area layer # Facility service area polygon layer has 8 polygons, where each feature has a unique identifier (ORIG_ID) facility_service_areas_fl = arcpy.MakeFeatureLayer_management( r"../sample_data/facility_service_areas.shp").getOutput(0) # Create binary coverage (polygon) dictionary structure # Use population of each polygon as demand, # Use GEOID as the unique field # Ue ORIG_ID as the unique id for the facilities binary_coverage_polygon = arcpy_analysis.generate_binary_coverage( demand_polygon_fl, facility_service_areas_fl, "Population", "GEOID10", "ORIG_ID") # Create the mclp model # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities logger.info("Creating MCLP model...") mclp = covering.create_mclp_model(binary_coverage_polygon, {"total": 5}, "mclp.lp") # Solve the model using GLPK logger.info("Solving MCLP...") mclp.solve(pulp.GLPK()) # Get the unique ids of the 5 facilities chosen logger.info("Extracting results") ids = utilities.get_ids(mclp, "facility_service_areas") # Generate a query that could be used as a definition query or selection in arcpy select_query = arcpy_analysis.generate_query(ids,
def mclp_solver(env_path, demand_point, facility_service_area, attr_demand, id_demand_point, id_facility, num_facility, id_facility_as_string=True): """ Solve a MCLP using the given inputs and parameters. This function will overwrite the FeatureClass called mclp_analysis_layer :param env_path: (string) Path of the env :param demand_point: (string) File name of the demand point layer :param facility_service_area: (string) File name of the facility service areas :param attr_demand: (int or float) the attribute of demand :param id_demand_point: (int or string) the ID attribute in demand_point :param id_facility: (int or string) the ID attribute in facility_service_area :param num_facility: (int) Number of facilities to site :param id_facility_as_string: (boolean) whether the ID attribute of facilities is string :return: (A dict of objects) [demand_coverage, n_facility, list_id_facility] """ # demand layer demand_polygon_fl = arcpy.MakeFeatureLayer_management( os.path.join(env_path, demand_point)).getOutput(0) # service layer facility_service_areas_fl = arcpy.MakeFeatureLayer_management( os.path.join(env_path, facility_service_area)).getOutput(0) # Create binary coverage (polygon) dictionary structure # Use "demand" of each polygon as demand, # Use "id" as the unique field # Use "object_id" as the unique id for the facilities print(arcpy.Describe(facility_service_areas_fl).shapeType) binary_coverage_polygon = arcpy_analysis.generate_binary_coverage( demand_polygon_fl, facility_service_areas_fl, attr_demand, id_demand_point, id_facility) # Create the mclp model # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities # logger.info("Creating MCLP model...") mclp = covering.create_mclp_model(binary_coverage_polygon, {"total": num_facility}) # Solve the model using GLPK print("Solving MCLP...") mclp.solve(pulp.GLPK()) # print(mclp.variables()) # get the ids not covered # print('Demand not covered: ') # for var in mclp.variables(): # if var.name.split("$")[0] == "Y": # if var.varValue < 1.0: # print(var.name) # get the ids covered print('Demand covered: ') list_objectid_dem_covered = [] for var in mclp.variables(): if var.name.split("$")[0] == "Y": if var.varValue >= 1.0: list_objectid_dem_covered.append(var.name.split("$")[1]) print list_objectid_dem_covered # get rid of the file postfix: .shp # example: york_facility_sample_buffer_100 facility_layer_name = os.path.splitext(facility_service_area)[0] # print(facility_layer_name) ids = utilities.get_ids(mclp, facility_layer_name) print 'List of selected facilities: ', ids # As the attribute object_id is a string type, the 'wrap_values_in_quotes' should be set as True select_query = arcpy_analysis.generate_query( ids, unique_field_name=id_facility, wrap_values_in_quotes=id_facility_as_string) logger.info( "Output query to use to generate maps is: {}".format(select_query)) # Determine how much demand is covered by the results facility_service_areas_fl.definitionQuery = select_query total_coverage = arcpy_analysis.get_covered_demand( demand_polygon_fl, attr_demand, "binary", facility_service_areas_fl) logger.info(total_coverage) logger.info(binary_coverage_polygon["totalDemand"]) # logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"])) result = {} result["demand_coverage"] = ( total_coverage) / binary_coverage_polygon["totalDemand"] result["n_facility"] = num_facility result["list_id_facility"] = " ".join(str(x) for x in ids) print result["list_id_facility"] return result
def lscp_solver(env_path, demand_point, facility_service_area, attr_demand, id_demand_point, id_facility, id_facility_as_string=True): """ Solve a LSCP using the given inputs and parameters :param env_path: (string) Path of the env :param demand_point: (string) File name of the demand point layer :param facility_service_area: (string) File name of the facility service areas :param id_facility_as_string: (boolean) whether the ID attribute of facilities is string :return: (A dict of objects) [demand_coverage, n_facility, list_id_facility] """ # demand layer demand_polygon_fl = arcpy.MakeFeatureLayer_management( os.path.join(env_path, demand_point)).getOutput(0) # service layer facility_service_areas_fl = arcpy.MakeFeatureLayer_management( os.path.join(env_path, facility_service_area)).getOutput(0) # Create binary coverage (polygon) dictionary structure # Use "demand" of each polygon as demand, # Use "id" as the unique field # Use "object_id" as the unique id for the facilities binary_coverage_polygon = arcpy_analysis.generate_binary_coverage( demand_polygon_fl, facility_service_areas_fl, attr_demand, id_demand_point, id_facility) # Create the mclp model # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities logger.info("Creating LSCP model...") lscp = covering.create_lscp_model(binary_coverage_polygon) # Solve the model using GLPK # logger.info("Solving MCLP...") lscp.solve(pulp.GLPK()) # get rid of the file postfix: .shp # example: york_facility_sample_buffer_100 facility_layer_name = os.path.splitext(facility_service_area)[0] # print(facility_layer_name) ids = utilities.get_ids(lscp, facility_layer_name) # print "List of IDs: ", ids select_query = arcpy_analysis.generate_query( ids, unique_field_name=id_facility, wrap_values_in_quotes=id_facility_as_string) # logger.info("Output query to use to generate maps is: {}".format(select_query)) # Determine how much demand is covered by the results facility_service_areas_fl.definitionQuery = select_query total_coverage = arcpy_analysis.get_covered_demand( demand_polygon_fl, attr_demand, "binary", facility_service_areas_fl) # logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"])) result = {} print "Total demand is: ", binary_coverage_polygon["totalDemand"] result["demand_coverage"] = ( total_coverage) / binary_coverage_polygon["totalDemand"] # number of facilities used result["n_facility"] = len(ids) result["list_id_facility"] = " ".join(str(x) for x in ids) return result
logger.addHandler(sh) # Read the demand polygon layer # Demand polygon shapefile has 212 polygons each where each feature has a demand (population) and unique identifier (GEOID10) demand_polygon_fl = arcpy.MakeFeatureLayer_management(r"../sample_data/demand_polygon.shp").getOutput(0) # Read the facility service area layer # Facility service area polygon layer has 8 polygons, where each feature has a unique identifier (ORIG_ID) facility_service_areas_fl = arcpy.MakeFeatureLayer_management( r"../sample_data/facility_service_areas.shp").getOutput(0) # Create binary coverage (polygon) dictionary structure # Use population of each polygon as demand, # Use GEOID as the unique field # Ue ORIG_ID as the unique id for the facilities binary_coverage_polygon = arcpy_analysis.generate_binary_coverage(demand_polygon_fl, facility_service_areas_fl, "Population", "GEOID10", "ORIG_ID") # Create the mclp model # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities logger.info("Creating MCLP model...") mclp = covering.create_mclp_model(binary_coverage_polygon, {"total": 5}) # Solve the model using GLPK logger.info("Solving MCLP...") mclp.solve(pulp.GLPK()) # Get the unique ids of the 5 facilities chosen logger.info("Extracting results") ids = utilities.get_ids(mclp, "facility_service_areas") # Generate a query that could be used as a definition query or selection in arcpy select_query = arcpy_analysis.generate_query(ids, unique_field_name="ORIG_ID") logger.info("Output query to use to generate maps is: {}".format(select_query))