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"]))
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
dl = qgis.core.QgsVectorLayer(r"../sample_data/demand_point.shp", "demand_point_fl", "ogr") ad_layer = qgis.core.QgsVectorLayer(r"../sample_data/facility.shp", "facility_point_fl", "ogr") tc_layer = qgis.core.QgsVectorLayer(r"../sample_data/facility2.shp", "facility2_point_fl", "ogr") coverage = pyqgis_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 = pyqgis_analysis.generate_query(ad_ids, unique_field_name="ID") select_query2 = pyqgis_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)))
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"]))
#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()
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"]))
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 = pyqgis_analysis.generate_query(ad_ids, unique_field_name="ID") select_query2 = pyqgis_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)))