Esempio n. 1
0
 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)
Esempio n. 2
0
    # 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))