def test_bclpcc(self):
     merged_dict = covering.merge_coverages([self.partial_coverage, self.partial_coverage2])
     merged_dict = covering.update_serviceable_demand(merged_dict, self.serviceable_demand_polygon)
     bclpcc = covering.create_bclpcc_model(merged_dict, {"total": 3}, 0.2)
     bclpcc.solve(pulp.GUROBI())
     ids = utilities.get_ids(bclpcc, "facility_service_areas")
     ids2 = utilities.get_ids(bclpcc, "facility2_service_areas")
     self.assertEqual(['4'], ids)
     self.assertEqual(['10'], ids2)
 def test_traumah(self):
     traumah = covering.create_traumah_model(self.traumah_coverage, 5, 10)
     traumah_i = covering.create_traumah_model(self.traumah_coverage, 100, 100)
     traumah.solve(pulp.GUROBI())
     traumah_i.solve(pulp.GUROBI())
     ad_ids = utilities.get_ids(traumah, "AirDepot")
     tc_ids = utilities.get_ids(traumah, "TraumaCenter")
     self.assertEqual(['0', '1', '2', '4', '5'], ad_ids)
     self.assertEqual(['10', '12', '15', '16', '18', '19', '21', '22', '7', '9'], tc_ids)
     self.assertEqual(traumah_i.status, pulp.constants.LpStatusInfeasible)
 def test_backup(self):
     merged_dict = covering.merge_coverages([self.binary_coverage_point, self.binary_coverage_point2])
     merged_dict = covering.update_serviceable_demand(merged_dict, self.serviceable_demand_point)
     bclp = covering.create_backup_model(merged_dict, {"total": 30})
     bclp.solve(pulp.GUROBI())
     ids = utilities.get_ids(bclp, "facility_service_areas")
     ids2 = utilities.get_ids(bclp, "facility2_service_areas")
     self.assertEqual(['1', '3', '4', '5', '6', '7'], ids)
     self.assertEqual(
         ['0', '1', '10', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '22', '3', '4', '5', '6', '8',
          '9'], ids2)
Пример #4
0
 def test_bclpcc(self):
     merged_dict = covering.merge_coverages(
         [self.partial_coverage, self.partial_coverage2])
     merged_dict = covering.update_serviceable_demand(
         merged_dict, self.serviceable_demand_polygon)
     bclpcc = covering.create_bclpcc_model(merged_dict, {"total": 3}, 0.2)
     bclpcc.solve(pulp.GLPK())
     ids = utilities.get_ids(bclpcc, "facility_service_areas")
     ids2 = utilities.get_ids(bclpcc, "facility2_service_areas")
     self.assertEqual(['4'], ids)
     self.assertEqual(['10'], ids2)
Пример #5
0
 def test_traumah(self):
     traumah = covering.create_traumah_model(self.traumah_coverage, 5, 10)
     traumah_i = covering.create_traumah_model(self.traumah_coverage, 100,
                                               100)
     traumah.solve(pulp.GLPK())
     traumah_i.solve(pulp.GLPK())
     ad_ids = utilities.get_ids(traumah, "AirDepot")
     tc_ids = utilities.get_ids(traumah, "TraumaCenter")
     self.assertEqual(['0', '1', '2', '3', '5'], ad_ids)
     self.assertEqual(
         ['10', '12', '15', '16', '18', '19', '21', '22', '7', '9'], tc_ids)
     self.assertEqual(traumah_i.status, pulp.constants.LpStatusInfeasible)
 def test_lscp(self):
     merged_dict = covering.merge_coverages([self.binary_coverage_point, self.binary_coverage_point2])
     merged_dict = covering.update_serviceable_demand(merged_dict, self.serviceable_demand_point)
     lscp = covering.create_lscp_model(merged_dict)
     lscp_i = covering.create_lscp_model(self.binary_coverage_point)
     lscp.solve(pulp.GUROBI())
     lscp_i.solve(pulp.GUROBI())
     ids = utilities.get_ids(lscp, "facility_service_areas")
     ids2 = utilities.get_ids(lscp, "facility2_service_areas")
     self.assertEqual(['1', '3', '4', '5', '6', '7'], ids)
     self.assertEqual(
         ['0', '1', '11', '12', '13', '14', '15', '16', '17', '19', '2', '20', '22', '4', '5', '6', '7', '9'], ids2)
     self.assertEqual(lscp_i.status, pulp.constants.LpStatusInfeasible)
Пример #7
0
 def test_backup(self):
     merged_dict = covering.merge_coverages(
         [self.binary_coverage_point, self.binary_coverage_point2])
     merged_dict = covering.update_serviceable_demand(
         merged_dict, self.serviceable_demand_point)
     bclp = covering.create_backup_model(merged_dict, {"total": 30})
     bclp.solve(pulp.GUROBI())
     ids = utilities.get_ids(bclp, "facility_service_areas")
     ids2 = utilities.get_ids(bclp, "facility2_service_areas")
     self.assertEqual(['1', '3', '4', '5', '6', '7'], ids)
     self.assertEqual([
         '0', '1', '10', '12', '13', '14', '15', '16', '17', '18', '19',
         '2', '20', '22', '3', '4', '5', '6', '8', '9'
     ], ids2)
Пример #8
0
 def test_lscp(self):
     merged_dict = covering.merge_coverages(
         [self.binary_coverage_point, self.binary_coverage_point2])
     merged_dict = covering.update_serviceable_demand(
         merged_dict, self.serviceable_demand_point)
     lscp = covering.create_lscp_model(merged_dict, "lscp.lp")
     lscp.solve(pulp.GLPK())
     ids = utilities.get_ids(lscp, "facility_service_areas")
     ids2 = utilities.get_ids(lscp, "facility2_service_areas")
     self.assertEqual(['3', '4', '5', '6', '7'], ids)
     self.assertEqual([
         '0', '1', '11', '12', '13', '14', '15', '16', '17', '18', '19',
         '2', '20', '21', '22', '4', '5', '6', '9'
     ], ids2)
Пример #9
0
def run_example():
    providers = QgsProviderRegistry.instance().providerList()
    for provider in providers:
        print(provider)
    print(QgsApplication.showSettings())
    demand_points = QgsVectorLayer("/Users/andrewlaird/Desktop/QGIS Mapping/points_2.shp", "demand_points", "ogr")
    print(demand_points.isValid())
    service_areas = QgsVectorLayer("/Users/andrewlaird/Desktop/QGIS Mapping/zones.shp", "service_areas", "ogr")
    print(service_areas.isValid())

    binary_coverage_polygon = pyqgis_analysis.generate_binary_coverage(demand_points, service_areas,
                                                                       "od_rate", "point_id", "zone_id")

    print(binary_coverage_polygon)
    # 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_threshold_model(binary_coverage_polygon, 100.0)
    # 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, "zones")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = pyqgis_analysis.generate_query(ids, unique_field_name="zone_id")
    logger.info("Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    service_areas.setSubsetString(select_query)
    total_coverage = pyqgis_analysis.get_covered_demand(demand_points, "od_rate", "binary",
                                                        service_areas)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
Пример #10
0
 def test_cc_threshold(self):
     ccthreshold = covering.create_cc_threshold_model(self.partial_coverage2, 80)
     ccthreshold_i = covering.create_cc_threshold_model(self.partial_coverage2, 100)
     ccthreshold.solve(pulp.GUROBI())
     ccthreshold_i.solve(pulp.GUROBI())
     ids = utilities.get_ids(ccthreshold, "facility2_service_areas")
     self.assertEqual(['1', '10', '11', '13', '15', '17', '19', '20', '21', '22', '3', '4', '7', '9'], ids)
     self.assertEqual(ccthreshold_i.status, pulp.constants.LpStatusInfeasible)
Пример #11
0
 def test_lscp(self):
     merged_dict = covering.merge_coverages(
         [self.binary_coverage_point, self.binary_coverage_point2])
     merged_dict = covering.update_serviceable_demand(
         merged_dict, self.serviceable_demand_point)
     lscp = covering.create_lscp_model(merged_dict)
     lscp_i = covering.create_lscp_model(self.binary_coverage_point)
     lscp.solve(pulp.GUROBI())
     lscp_i.solve(pulp.GUROBI())
     ids = utilities.get_ids(lscp, "facility_service_areas")
     ids2 = utilities.get_ids(lscp, "facility2_service_areas")
     self.assertEqual(['1', '3', '4', '5', '6', '7'], ids)
     self.assertEqual([
         '0', '1', '11', '12', '13', '14', '15', '16', '17', '19', '2',
         '20', '22', '4', '5', '6', '7', '9'
     ], ids2)
     self.assertEqual(lscp_i.status, pulp.constants.LpStatusInfeasible)
Пример #12
0
 def test_threshold(self):
     threshold = covering.create_threshold_model(self.binary_coverage_point2, 30)
     threshold_i = covering.create_threshold_model(self.binary_coverage_point2, 100)
     threshold.solve(pulp.GUROBI())
     threshold_i.solve(pulp.GUROBI())
     ids = utilities.get_ids(threshold, "facility2_service_areas")
     self.assertEqual(['10', '20', '4'], ids)
     self.assertEqual(threshold_i.status, pulp.constants.LpStatusInfeasible)
Пример #13
0
 def test_cc_threshold(self):
     ccthreshold = covering.create_cc_threshold_model(
         self.partial_coverage2, 80, "ccthreshold.lp")
     ccthreshold.solve(pulp.GLPK())
     ids = utilities.get_ids(ccthreshold, "facility2_service_areas")
     self.assertEqual([
         '1', '11', '13', '15', '17', '19', '20', '21', '22', '3', '4', '5',
         '7', '9'
     ], ids)
Пример #14
0
 def test_threshold(self):
     threshold = covering.create_threshold_model(
         self.binary_coverage_point2, 30)
     threshold_i = covering.create_threshold_model(
         self.binary_coverage_point2, 100)
     threshold.solve(pulp.GLPK())
     threshold_i.solve(pulp.GLPK())
     ids = utilities.get_ids(threshold, "facility2_service_areas")
     self.assertEqual(['10', '17', '4'], ids)
     self.assertEqual(threshold_i.status, pulp.constants.LpStatusInfeasible)
Пример #15
0
 def test_cc_threshold(self):
     ccthreshold = covering.create_cc_threshold_model(
         self.partial_coverage2, 80)
     ccthreshold_i = covering.create_cc_threshold_model(
         self.partial_coverage2, 100)
     ccthreshold.solve(pulp.GLPK())
     ccthreshold_i.solve(pulp.GLPK())
     ids = utilities.get_ids(ccthreshold, "facility2_service_areas")
     self.assertEqual([
         '1', '11', '13', '15', '17', '19', '20', '21', '22', '3', '4', '5',
         '7', '9'
     ], ids)
     self.assertEqual(ccthreshold_i.status,
                      pulp.constants.LpStatusInfeasible)
Пример #16
0
 def test_threshold(self):
     threshold = covering.create_threshold_model(
         self.binary_coverage_point2, 30, "threshold.lp")
     threshold.solve(pulp.GLPK())
     ids = utilities.get_ids(threshold, "facility2_service_areas")
     self.assertEqual(['10', '17', '4'], ids)
Пример #17
0
 def test_mclpcc(self):
     mclpcc = covering.create_mclp_cc_model(self.partial_coverage,
                                            {"total": 5}, "mclpcc.lp")
     mclpcc.solve(pulp.GLPK())
     ids = utilities.get_ids(mclpcc, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], ids)
Пример #18
0
 def test_mclp(self):
     mclp = covering.create_mclp_model(self.binary_coverage_polygon,
                                       {"total": 5}, "mclp.lp")
     mclp.solve(pulp.GLPK())
     ids = utilities.get_ids(mclp, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], ids)
Пример #19
0
    def model(self):
        # Run a threshold model on a provided demand and response_area layer

        self._create_run_dirs()

        # TODO: Figure out why it is necessary to reload here rather than just using the layer.
        block_layer = QgsVectorLayer(self.paths['block_shp_output'], "block_layer", "ogr")
        response_area_layer = QgsVectorLayer(self.paths['responder_shp_output'], "response_area_layer", "ogr")
        if self.logger:
            self.logger.info("Reloaded layers from file. Found {} blocks and {} response areas."
                             .format(len(list(block_layer.getFeatures())),
                              len(list(response_area_layer.getFeatures()))))

        binary_coverage_polygon = pyqgis_analysis.generate_partial_coverage(block_layer, response_area_layer,
                                                                            "demand", "point_id", "area_id")
        # TODO: Build a handler which selects the proper model based on config
        # TODO: Move this code into a function (class?) for partial_coverage_threshold
        # Create the mclp model
        if self.logger:
            self.logger.info("Creating MCLP model...")
        mclp = covering.create_cc_threshold_model(binary_coverage_polygon, self.model_run_config['thresholds'])
        # Solve the model using GLPK
        if self.logger:
            self.logger.info("Solving MCLP...")

        mclp.solve(solvers.PULP_CBC_CMD())
        self.problem = mclp
        if pulp.LpStatus[mclp.status] == "Infeasible":
            print(pulp.LpStatus[mclp.status])
            print("Model run {} deemed infeasible. Skipping...".format(self.model_run_config['run_name']))
            self.status = pulp.LpStatus[mclp.status]
            self.results.parse_model_output(self)
            return

        # TODO: Move result extraction into it's own function (or tie to partial_coverage_model object)
        if self.logger:
            self.logger.info("Extracting results")
        ids = utilities.get_ids(mclp, "responder_layer")
        self.area_ids = ids
        point_ids = [str(ft['from_point']) for ft in list(response_area_layer.getFeatures()) if str(ft['area_id']) in ids]
        self.point_ids = point_ids
        # Generate a query that could be used as a definition query or selection in arcpy
        select_query = pyqgis_analysis.generate_query(ids, unique_field_name="area_id")
        point_select_query = pyqgis_analysis.generate_query(point_ids, unique_field_name="point_id")
        if self.logger:
            self.logger.info("Output query to use to generate response area maps is: {}".format(select_query))
            self.logger.info("Output query to use to generate response point maps is: {}".format(point_select_query))
        # Determine how much demand is covered by the results
        self.selected_points = SelectedPointsLayer().copy(RoadPointLayer(layer=self.road_points))
        self.selected_points.layer.setSubsetString(point_select_query)
        self.selected_areas = SelectedAreasLayer().copy(ResponderLayer(layer=self.response_areas))
        self.selected_areas.layer.setSubsetString(select_query)
        self.results.parse_model_output(self)
        # TODO: Fix calculation of covered demand and add to output
        #total_coverage = pyqgis_analysis.get_covered_demand(block_layer, "demand", "partial",
        #                                                    response_area_layer)
        if self.logger:
            # self.logger.info(
            # "{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
            self.logger.info("{} responders".format(len(ids)))
        _write_shp_file(self.selected_areas.layer, self.paths['model_result_shp_output'])
        _write_shp_file(self.selected_points.layer, self.paths['selected_points_shp_output'])
        self._write_qgs_project()

        return self
    ad_layer = arcpy.MakeFeatureLayer_management(
        r"../sample_data/facility.shp").getOutput(0)
    # The Trauma Center points
    tc_layer = arcpy.MakeFeatureLayer_management(
        r"../sample_data/facility2.shp").getOutput(0)

    # Generate the trauma coverage dictionary
    coverage = arcpy_analysis.generate_traumah_coverage(dl,dl_service_area,tc_layer,ad_layer,"Population",
                                                        5000,dl_id_field="GEOID10",tc_layer_id_field="ID",
                                                        ad_layer_id_field="ID")

    # Create the trauma Pulp linear programming problem
    # Use 5 Air Depot (Helicopter launch pads) and 10 Trauma Centers
    traumah = covering.create_traumah_model(coverage,5,10)

    # Solve the model using GLPK
    logger.info("Solving TRAUMAH...")
    traumah.solve(pulp.GLPK())

    # Get the unique ids of the 5 facilities chosen
    logger.info("Extracting results")
    ad_ids = utilities.get_ids(traumah, "AirDepot")
    tc_ids = utilities.get_ids(traumah, "TraumaCenter")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = arcpy_analysis.generate_query(ad_ids, unique_field_name="ID")
    select_query2 = arcpy_analysis.generate_query(tc_ids, unique_field_name="ID")
    # Print the important results
    logger.info("Output query to use to generate maps (showing selected Air Depots) is: {}".format(select_query))
    logger.info("Output query to use to generate maps (showing selected Trauma Centers) is: {}".format(select_query2))
    logger.info("Total Population Covered: {}".format(pulp.value(traumah.objective)))
Пример #21
0
    demand_polygon_fl = qgis.core.QgsVectorLayer(
        r"../sample_data/demand_polygon.shp", "demand_polygon_fl", "ogr")
    facility2_service_areas_fl = qgis.core.QgsVectorLayer(
        r"../sample_data/facility2_service_areas.shp",
        "facility2_service_areas_fl", "ogr")

    # Test partial coverage generation
    partial_coverage2 = pyqgis_analysis.generate_partial_coverage(
        demand_polygon_fl, facility2_service_areas_fl, "Population", "GEOID10",
        "ORIG_ID")

    # Create the model, minimize the number of facilities that still results in 80 percent coverage
    logger.info("Creating complemenatary coverage threshold model...")
    ccthreshold = covering.create_cc_threshold_model(partial_coverage2, 80)
    # Solve the model
    logger.info("Solving CC threshold model...")
    ccthreshold.solve(pulp.GLPK())
    # Extract the ids
    logger.info("Extracting results")
    ids = utilities.get_ids(ccthreshold, "facility2_service_areas")
    select_query = pyqgis_analysis.generate_query(ids,
                                                  unique_field_name="ORIG_ID")
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    facility2_service_areas_fl.setSubsetString(select_query)
    total_coverage = pyqgis_analysis.get_covered_demand(
        demand_polygon_fl, "Population", "partial", facility2_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format(
        (100 * total_coverage) / partial_coverage2["totalDemand"]))
Пример #22
0
    # 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))
    # 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, "Population", "binary",
                                                       facility_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
Пример #23
0
    #make a service area layer
    service_area_layer = make_service_area_layer(grid_layer)
    print(len(list(service_area_layer.getFeatures())))
    QgsVectorFileWriter.writeAsVectorFormat(service_area_layer, SERVICE_AREA_SHP, "System", service_area_layer.crs(), "ESRI Shapefile")

    run_example()
    grid_layer = QgsVectorLayer(GRID_LAYER_SHP, "grid_layer", "ogr")
    service_area_layer = QgsVectorLayer(SERVICE_AREA_SHP, "service_area_layer", "ogr")

    binary_coverage_polygon = pyqgis_analysis.generate_binary_coverage(grid_layer, service_area_layer,
                                                                       "demand", "point_id", "area_id")
    
    print(binary_coverage_polygon)
    # Create the mclp model
    logger.info("Creating MCLP model...")
    mclp = covering.create_threshold_model(binary_coverage_polygon, 100.0)
    # Solve the model using GLPK
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK())
    logger.info("Extracting results")
    ids = utilities.get_ids(mclp, "areas")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = pyqgis_analysis.generate_query(ids, unique_field_name="area_id")
    logger.info("Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    service_area_layer.setSubsetString(select_query)
    total_coverage = pyqgis_analysis.get_covered_demand(grid_layer, "demand", "binary",
                                                        service_area_layer)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))

    QgsApplication.exitQgis()
def lscp_solver_coverage_dict(dict_coverage,
                              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 dict_coverage: (dictionary) Dictionay of coverage
    :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: (string) Field name of demand weight. Not used now
    :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 = dict_coverage

    # 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"]

    result["demand_coverage"] = 1.0
    # number of facilities used
    result["n_facility"] = len(ids)

    result["list_id_facility"] = " ".join(str(x) for x in ids)

    return result
Пример #25
0
                                                        5000,
                                                        dl_id_field="GEOID10",
                                                        tc_layer_id_field="ID",
                                                        ad_layer_id_field="ID")

    # Create the trauma Pulp linear programming problem
    # Use 5 Air Depot (Helicopter launch pads) and 10 Trauma Centers
    traumah = covering.create_traumah_model(coverage, 5, 10)

    # Solve the model using GLPK
    logger.info("Solving TRAUMAH...")
    traumah.solve(pulp.GLPK())

    # Get the unique ids of the 5 facilities chosen
    logger.info("Extracting results")
    ad_ids = utilities.get_ids(traumah, "AirDepot")
    tc_ids = utilities.get_ids(traumah, "TraumaCenter")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = arcpy_analysis.generate_query(ad_ids,
                                                 unique_field_name="ID")
    select_query2 = arcpy_analysis.generate_query(tc_ids,
                                                  unique_field_name="ID")
    # Print the important results
    logger.info(
        "Output query to use to generate maps (showing selected Air Depots) is: {}"
        .format(select_query))
    logger.info(
        "Output query to use to generate maps (showing selected Trauma Centers) is: {}"
        .format(select_query2))
    logger.info("Total Population Covered: {}".format(
        pulp.value(traumah.objective)))
Пример #26
0
        demand_point_fl, facility2_service_areas_fl, "Population", "GEOID10",
        "ORIG_ID")
    # Merge the binary coverages together, serviceable area is auto-updated for binary coverage
    total_binary_coverage = covering.merge_coverages(
        [binary_coverage_point1, binary_coverage_point2])

    # Create the mclp model
    # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities
    logger.info("Creating MCLP model...")
    lscp = covering.create_lscp_model(total_binary_coverage, "lscp.lp")
    # Solve the model using GLPK
    logger.info("Solving LSCP...")
    lscp.solve(pulp.GLPK())
    # Get the unique ids of the facilities chosen
    logger.info("Extracting results")
    ids = utilities.get_ids(lscp, "facility_service_areas")
    ids2 = utilities.get_ids(lscp, "facility2_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")
    # Generate a second query for the other layer
    select_query2 = arcpy_analysis.generate_query(ids2,
                                                  unique_field_name="ORIG_ID")
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query))
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query2))
    # Determine how much demand is covered by the results
    facility_service_areas_fl.definitionQuery = select_query
    facility2_service_areas_fl.defintionQuery = select_query2
    total_coverage = arcpy_analysis.get_covered_demand(
Пример #27
0
    sh = logging.StreamHandler(sys.stdout)
    sh.setFormatter(formatter)
    logger.addHandler(sh)

    # Read the layers
    demand_polygon_fl = qgis.core.QgsVectorLayer(r"../sample_data/demand_polygon.shp", "demand_polygon_fl", "ogr")
    facility2_service_areas_fl = qgis.core.QgsVectorLayer(r"../sample_data/facility2_service_areas.shp",
                                                          "facility2_service_areas_fl", "ogr")

    # Test partial coverage generation
    partial_coverage2 = pyqgis_analysis.generate_partial_coverage(demand_polygon_fl, facility2_service_areas_fl,
                                                                  "Population",
                                                                  "GEOID10", "ORIG_ID")

    # Create the model, minimize the number of facilities that still results in 80 percent coverage
    logger.info("Creating complemenatary coverage threshold model...")
    ccthreshold = covering.create_cc_threshold_model(partial_coverage2, 80)
    # Solve the model
    logger.info("Solving CC threshold model...")
    ccthreshold.solve(pulp.GLPK())
    # Extract the ids
    logger.info("Extracting results")
    ids = utilities.get_ids(ccthreshold, "facility2_service_areas")
    select_query = pyqgis_analysis.generate_query(ids, unique_field_name="ORIG_ID")
    logger.info("Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    facility2_service_areas_fl.setSubsetString(select_query)
    total_coverage = pyqgis_analysis.get_covered_demand(demand_polygon_fl, "Population", "partial",
                                                        facility2_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / partial_coverage2["totalDemand"]))
Пример #28
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,
                                                 unique_field_name="ORIG_ID")
    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, "Population", "binary", facility_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format(
        (100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
Пример #29
0
 def test_mclpcc(self):
     mclpcc = covering.create_mclp_cc_model(self.partial_coverage, {"total": 5})
     mclpcc.solve(pulp.GUROBI())
     ids = utilities.get_ids(mclpcc, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], ids)
Пример #30
0
 def test_mclp(self):
     mclp = covering.create_mclp_model(self.binary_coverage_polygon, {"total": 5})
     mclp.solve(pulp.GUROBI())
     ids = utilities.get_ids(mclp, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], 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
Пример #32
0
    block_layer = QgsVectorLayer(BLOCK_OUTLINE_SHP, "block_layer", "ogr")
    response_area_layer = QgsVectorLayer(RESPONSE_AREA_LAYER_SHP,
                                         "response_area_layer", "ogr")

    binary_coverage_polygon = pyqgis_analysis.generate_partial_coverage(
        block_layer, response_area_layer, "demand", "point_id", "area_id")

    print(binary_coverage_polygon)
    # Create the mclp model
    logger.info("Creating MCLP model...")
    mclp = covering.create_cc_threshold_model(binary_coverage_polygon, 80)
    # Solve the model using GLPK
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK(options=['--mipgap', '.1']))
    logger.info("Extracting results")
    ids = utilities.get_ids(mclp,
                            "{}_response_area_layer".format(SELECTION_VALUE))
    print(ids)
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = pyqgis_analysis.generate_query(ids,
                                                  unique_field_name="area_id")
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    response_area_layer.setSubsetString(select_query)
    total_coverage = pyqgis_analysis.get_covered_demand(
        block_layer, "demand", "partial", response_area_layer)
    logger.info("{0:.2f}% of demand is covered".format(
        (100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
    logger.info("{} responders".format(len(ids)))
    QgsVectorFileWriter.writeAsVectorFormat(response_area_layer,
                                            MODEL_RESULT_PATH, "System",
Пример #33
0
        fl_variable_name=facility_variable_name)

    # formulate model
    logger.info("Creating MCLP model...")
    mclp = covering.create_mclp_model(dict_coverage, {"total": num_facility})

    # solve
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK())

    # Get the unique ids of the facilities chosen
    logger.info("Extracting results")

    # Get the id set of facilities chosen
    set_facility_id_chosen = set(
        utilities.get_ids(mclp, facility_variable_name))

    logger.info("Set of facility ids: {}".format(set_facility_id_chosen))
    logger.info("Number of facilities selected: {}".format(
        len(set_facility_id_chosen)))

    # Query the demand covered from the dict_coverage
    total_demand_covered = 0.0

    for demand_id, demand_obj in dict_coverage["demand"].items():
        # if this demand_id is covered by any facility in ids
        if not set_facility_id_chosen.isdisjoint(
                demand_obj["coverage"]["facility"].keys()):
            total_demand_covered += demand_obj["demand"]

    logger.info("{0:.2f}% of demand is covered".format(
Пример #34
0
                                                                     "Population", "GEOID10", "ORIG_ID")
    binary_coverage_point2 = arcpy_analysis.generate_binary_coverage(demand_point_fl, facility2_service_areas_fl,
                                                                     "Population",
                                                                     "GEOID10", "ORIG_ID")
    # Merge the binary coverages together, serviceable area is auto-updated for binary coverage
    total_binary_coverage = covering.merge_coverages([binary_coverage_point1, binary_coverage_point2])

    # Create the mclp model
    # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities
    logger.info("Creating MCLP model...")
    lscp = covering.create_lscp_model(total_binary_coverage)
    # Solve the model using GLPK
    logger.info("Solving LSCP...")
    lscp.solve(pulp.GLPK())
    # Get the unique ids of the facilities chosen
    logger.info("Extracting results")
    ids = utilities.get_ids(lscp, "facility_service_areas")
    ids2 = utilities.get_ids(lscp, "facility2_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")
    # Generate a second query for the other layer
    select_query2 = arcpy_analysis.generate_query(ids2, unique_field_name="ORIG_ID")
    logger.info("Output query to use to generate maps is: {}".format(select_query))
    logger.info("Output query to use to generate maps is: {}".format(select_query2))
    # Determine how much demand is covered by the results
    facility_service_areas_fl.definitionQuery = select_query
    facility2_service_areas_fl.defintionQuery = select_query2
    total_coverage = arcpy_analysis.get_covered_demand(demand_point_fl, "Population", "binary",
                                                       facility_service_areas_fl, facility2_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / total_binary_coverage["totalDemand"]))