Exemple #1
0
    def test_creation(self):
        test_file = temp_proj_name
        with self.assertRaises(FileNotFoundError):
            p = Project()
            p.load(test_file)

        p = Project()
        p.new(test_file)
        p.conn.close()
Exemple #2
0
    def test_exclude_links(self):
        p = Project()
        p.load(siouxfalls_project)
        p.network.build_graphs()

        g = p.network.graphs['c']  # type: Graph

        # excludes a link before any setting or preparation
        g.exclude_links([12])

        g.set_graph('distance')
        r1 = PathResults()
        r1.prepare(g)
        r1.compute_path(1, 14)
        self.assertEqual(list(r1.path), [2, 6, 10, 34])

        # We exclude one link that we know was part of the last shortest path
        g.exclude_links([10])
        r2 = PathResults()
        r2.prepare(g)
        r2.compute_path(1, 14)
        self.assertEqual(list(r2.path), [2, 7, 36, 34])

        p.conn.close()
Exemple #3
0
class TestTrafficAssignment(TestCase):
    def setUp(self) -> None:
        self.matrix = AequilibraeMatrix()
        self.matrix.load(siouxfalls_demand)
        self.matrix.computational_view()

        self.project = Project()
        self.project.load(siouxfalls_project)
        self.project.network.build_graphs()
        self.car_graph = self.project.network.graphs['c']  # type: Graph
        self.car_graph.set_graph('free_flow_time')
        self.car_graph.set_blocked_centroid_flows(False)

        self.assignment = TrafficAssignment()
        self.assigclass = TrafficClass(self.car_graph, self.matrix)

    def tearDown(self) -> None:
        self.matrix.close()
        self.project.conn.close()

    def test_set_vdf(self):
        with self.assertRaises(ValueError):
            self.assignment.set_vdf('CQS')

        self.assignment.set_vdf('BPR')

    def test_set_classes(self):
        with self.assertRaises(ValueError):
            self.assignment.set_classes([1, 2])

        # The traffic assignment class is unprotected.
        # Should we protect it?
        # self.assigclass = TrafficClass(self.car_graph, self.matrix)
        # self.assigclass.graph = 1
        # with self.assertRaises(ValueError):
        #     self.assignment.set_classes(self.assigclass)

        self.assignment.set_classes(self.assigclass)
        # self.fail()

    def test_algorithms_available(self):
        algs = self.assignment.algorithms_available()
        real = ['all-or-nothing', 'msa', 'frank-wolfe', 'bfw', 'cfw']

        diff = [x for x in real if x not in algs]
        diff2 = [x for x in algs if x not in real]

        if len(diff) + len(diff2) > 0:
            self.fail('list of algorithms raised is wrong')

    def test_set_cores(self):
        with self.assertRaises(Exception):
            self.assignment.set_cores(3)

        self.assignment.set_classes(self.assigclass)
        with self.assertRaises(ValueError):
            self.assignment.set_cores('q')

        self.assignment.set_cores(3)

    def test_set_algorithm(self):
        with self.assertRaises(AttributeError):
            self.assignment.set_algorithm('not an algo')

        self.assignment.set_classes(self.assigclass)

        with self.assertRaises(Exception):
            self.assignment.set_algorithm('msa')

        self.assignment.set_vdf("BPR")
        self.assignment.set_vdf_parameters({"alpha": "b", "beta": "power"})

        self.assignment.set_capacity_field("capacity")
        self.assignment.set_time_field("free_flow_time")

        self.assignment.max_iter = 10
        self.assignment.set_algorithm('bfw')

    def test_set_vdf_parameters(self):
        with self.assertRaises(Exception):
            self.assignment.set_vdf_parameters({"alpha": "b", "beta": "power"})

        self.assignment.set_vdf('bpr')
        self.assignment.set_classes(self.assigclass)
        self.assignment.set_vdf_parameters({"alpha": "b", "beta": "power"})

    def test_set_time_field(self):
        N = random.randint(1, 50)
        val = ''.join(
            random.choices(string.ascii_uppercase + string.digits, k=N))
        self.assignment.set_time_field(val)
        self.assertEqual(self.assignment.time_field, val)

    def test_set_capacity_field(self):
        N = random.randint(1, 50)
        val = ''.join(
            random.choices(string.ascii_uppercase + string.digits, k=N))
        self.assignment.set_capacity_field(val)
        self.assertEqual(self.assignment.capacity_field, val)

    def test_execute(self):

        self.assignment.set_classes(self.assigclass)
        self.assignment.set_vdf("BPR")
        self.assignment.set_vdf_parameters({"alpha": 0.15, "beta": 4.0})
        self.assignment.set_vdf_parameters({"alpha": "b", "beta": "power"})

        self.assignment.set_capacity_field("capacity")
        self.assignment.set_time_field("free_flow_time")

        self.assignment.max_iter = 10
        self.assignment.set_algorithm('msa')
        self.assignment.execute()
        msa10 = self.assignment.assignment.rgap

        self.assigclass.results.total_flows()
        correl = np.corrcoef(self.assigclass.results.total_link_loads,
                             self.assigclass.graph.graph['volume'])[0, 1]
        self.assertLess(0.8, correl)

        self.assignment.max_iter = 30
        self.assignment.set_algorithm('msa')
        self.assignment.execute()
        msa25 = self.assignment.assignment.rgap

        self.assigclass.results.total_flows()
        correl = np.corrcoef(self.assigclass.results.total_link_loads,
                             self.assigclass.graph.graph['volume'])[0, 1]
        self.assertLess(0.95, correl)

        self.assignment.set_algorithm('frank-wolfe')
        self.assignment.execute()
        fw25 = self.assignment.assignment.rgap

        self.assigclass.results.total_flows()
        correl = np.corrcoef(self.assigclass.results.total_link_loads,
                             self.assigclass.graph.graph['volume'])[0, 1]
        self.assertLess(0.97, correl)

        self.assignment.set_algorithm('cfw')
        self.assignment.execute()
        cfw25 = self.assignment.assignment.rgap

        self.assigclass.results.total_flows()
        correl = np.corrcoef(self.assigclass.results.total_link_loads,
                             self.assigclass.graph.graph['volume'])[0, 1]
        self.assertLess(0.98, correl)

        self.assignment.set_algorithm('bfw')
        self.assignment.execute()
        bfw25 = self.assignment.assignment.rgap

        self.assigclass.results.total_flows()
        correl = np.corrcoef(self.assigclass.results.total_link_loads,
                             self.assigclass.graph.graph['volume'])[0, 1]
        self.assertLess(0.99, correl)

        self.assertLess(msa25, msa10)
        self.assertLess(fw25, msa25)
        self.assertLess(cfw25, fw25)
        self.assertLess(bfw25, cfw25)
Exemple #4
0
class AequilibraEMenu:
    def __init__(self, iface):

        self.translator = None
        self.iface = iface
        self.project = None  # type: Project
        self.link_layer = None  # type: QgsVectorLayer
        self.node_layer = None  # type: QgsVectorLayer

        self.dock = QDockWidget(self.trlt('AequilibraE'))
        self.manager = QWidget()

        # The self.toolbar will hold everything
        self.toolbar = QToolBar()
        self.toolbar.setOrientation(2)

        # # ########################################################################
        # # #######################   PROJECT SUB-MENU   ############################

        projectMenu = QMenu()
        self.open_project_action = QAction(self.trlt('Open Project'),
                                           self.manager)
        self.open_project_action.triggered.connect(self.run_load_project)
        projectMenu.addAction(self.open_project_action)

        self.project_from_osm_action = QAction(
            self.trlt('Create project from OSM'), self.manager)
        self.project_from_osm_action.triggered.connect(
            self.run_project_from_osm)
        projectMenu.addAction(self.project_from_osm_action)

        self.create_transponet_action = QAction(
            self.trlt('Create Project from layers'), self.manager)
        self.create_transponet_action.triggered.connect(
            self.run_create_transponet)
        projectMenu.addAction(self.create_transponet_action)

        projectButton = QToolButton()
        projectButton.setText(self.trlt('Project'))
        projectButton.setPopupMode(2)
        projectButton.setMenu(projectMenu)

        self.toolbar.addWidget(projectButton)

        # # ########################################################################
        # # ################# NETWORK MANIPULATION SUB-MENU  #######################

        netMenu = QMenu()
        self.action_netPrep = QAction(self.trlt('Network Preparation'),
                                      self.manager)
        self.action_netPrep.triggered.connect(self.run_net_prep)
        netMenu.addAction(self.action_netPrep)

        self.add_connectors_action = QAction(
            self.trlt('Add centroid connectors'), self.manager)
        self.add_connectors_action.triggered.connect(self.run_add_connectors)
        netMenu.addAction(self.add_connectors_action)

        netbutton = QToolButton()
        netbutton.setText(self.trlt('Network Manipulation'))
        netbutton.setMenu(netMenu)
        netbutton.setPopupMode(2)

        self.toolbar.addWidget(netbutton)
        # # ########################################################################
        # # ####################  DATA UTILITIES SUB-MENU  #########################

        dataMenu = QMenu()
        self.display_custom_formats_action = QAction(
            self.trlt('Display AequilibraE formats'), self.manager)
        self.display_custom_formats_action.triggered.connect(
            self.run_display_aequilibrae_formats)
        dataMenu.addAction(self.display_custom_formats_action)

        self.load_matrix_action = QAction(self.trlt('Import matrices'),
                                          self.manager)
        self.load_matrix_action.triggered.connect(self.run_load_matrices)
        dataMenu.addAction(self.load_matrix_action)

        self.load_database_action = QAction(self.trlt('Import dataset'),
                                            self.manager)
        self.load_database_action.triggered.connect(self.run_load_database)
        dataMenu.addAction(self.load_database_action)

        databutton = QToolButton()
        databutton.setText(self.trlt('Data'))
        databutton.setPopupMode(2)
        databutton.setMenu(dataMenu)

        self.toolbar.addWidget(databutton)

        # # # ########################################################################
        # # # ##################  TRIP DISTRIBUTION SUB-MENU  ########################

        distributionButton = QToolButton()
        distributionButton.setText(self.trlt('Trip Distribution'))
        distributionButton.clicked.connect(self.run_distribution_models)
        self.toolbar.addWidget(distributionButton)

        # # ########################################################################
        # # ###################  PATH COMPUTATION SUB-MENU   #######################
        pathMenu = QMenu()

        self.shortest_path_action = QAction(self.trlt('Shortest path'),
                                            self.manager)
        self.shortest_path_action.triggered.connect(self.run_shortest_path)
        pathMenu.addAction(self.shortest_path_action)

        self.dist_matrix_action = QAction(self.trlt('Impedance matrix'),
                                          self.manager)
        self.dist_matrix_action.triggered.connect(self.run_dist_matrix)
        pathMenu.addAction(self.dist_matrix_action)

        self.traffic_assignment_action = QAction(
            self.trlt('Traffic Assignment'), self.manager)
        self.traffic_assignment_action.triggered.connect(
            self.run_traffic_assig)
        pathMenu.addAction(self.traffic_assignment_action)

        pathButton = QToolButton()
        pathButton.setText(self.trlt('Paths and assignment'))
        pathButton.setPopupMode(2)
        pathButton.setMenu(pathMenu)

        self.toolbar.addWidget(pathButton)

        # # ########################################################################
        # # #######################   ROUTING SUB-MENU   ###########################
        if has_ortools:
            routingMenu = QMenu()
            self.tsp_action = QAction(self.trlt('Travelling Salesman Problem'),
                                      self.manager)
            self.tsp_action.triggered.connect(self.run_tsp)
            routingMenu.addAction(self.tsp_action)

            routingButton = QToolButton()
            routingButton.setText(self.trlt('Routing'))
            routingButton.setPopupMode(2)
            routingButton.setMenu(routingMenu)

            self.toolbar.addWidget(routingButton)

        # # ########################################################################
        # # #######################   TRANSIT SUB-MENU   ###########################
        transitMenu = QMenu()
        self.gtfs_import_action = QAction(
            self.trlt('Convert GTFS to SpatiaLite'), self.manager)
        self.gtfs_import_action.triggered.connect(self.run_import_gtfs)
        transitMenu.addAction(self.gtfs_import_action)

        transitButton = QToolButton()
        transitButton.setText(self.trlt('Public Transport'))
        transitButton.setPopupMode(2)
        transitButton.setMenu(transitMenu)

        self.toolbar.addWidget(transitButton)

        # ########################################################################
        # #################        GIS TOOLS SUB-MENU    #########################

        gisMenu = QMenu()
        self.simple_tag_action = QAction(self.trlt('Simple tag'), self.manager)
        self.simple_tag_action.triggered.connect(self.run_simple_tag)
        gisMenu.addAction(self.simple_tag_action)

        self.lcd_action = QAction(self.trlt('Lowest common denominator'),
                                  self.manager)
        self.lcd_action.triggered.connect(self.run_lcd)
        gisMenu.addAction(self.lcd_action)

        self.dlines_action = QAction(self.trlt('Desire Lines'), self.manager)
        self.dlines_action.triggered.connect(self.run_dlines)
        gisMenu.addAction(self.dlines_action)

        self.bandwidth_action = QAction(self.trlt('Stacked Bandwidth'),
                                        self.manager)
        self.bandwidth_action.triggered.connect(self.run_bandwidth)
        gisMenu.addAction(self.bandwidth_action)

        self.scenario_comparison_action = QAction(
            self.trlt('Scenario Comparison'), self.manager)
        self.scenario_comparison_action.triggered.connect(
            self.run_scenario_comparison)
        gisMenu.addAction(self.scenario_comparison_action)

        gisButton = QToolButton()
        gisButton.setText(self.trlt('GIS'))
        gisButton.setPopupMode(2)
        gisButton.setMenu(gisMenu)

        self.toolbar.addWidget(gisButton)

        # ########################################################################
        # #################          LOOSE STUFF         #########################

        parametersButton = QToolButton()
        parametersButton.setText(self.trlt('Parameters'))
        parametersButton.clicked.connect(self.run_change_parameters)
        self.toolbar.addWidget(parametersButton)

        aboutButton = QToolButton()
        aboutButton.setText(self.trlt('About'))
        aboutButton.clicked.connect(self.run_about)
        self.toolbar.addWidget(aboutButton)

        logButton = QToolButton()
        logButton.setText(self.trlt('logfile'))
        logButton.clicked.connect(self.run_log)
        self.toolbar.addWidget(logButton)

        helpButton = QToolButton()
        helpButton.setText(self.trlt('Help'))
        helpButton.clicked.connect(self.run_help)
        self.toolbar.addWidget(helpButton)

        if no_binary:
            binariesButton = QToolButton()
            binariesButton.setText(self.trlt('Download binaries'))
            binariesButton.clicked.connect(self.run_binary_download)
            self.toolbar.addWidget(binariesButton)

        if not extra_packages:
            xtrapkgButton = QToolButton()
            xtrapkgButton.setText(self.trlt('Install extra packages'))
            xtrapkgButton.clicked.connect(self.install_extra_packages)
            self.toolbar.addWidget(xtrapkgButton)

        # ########################################################################
        # #################        PROJECT MANAGER       #########################

        self.showing = QCheckBox()
        self.showing.setText('Show project info')
        self.showing.setChecked(True)
        self.toolbar.addWidget(self.showing)

        self.showing.toggled.connect(self.hide_info_pannel)
        self.projectManager = QTabWidget()
        self.toolbar.addWidget(self.projectManager)

        # # # ########################################################################
        self.tabContents = []
        self.toolbar.setIconSize(QSize(16, 16))

        p1_vertical = QVBoxLayout()
        p1_vertical.setContentsMargins(0, 0, 0, 0)
        p1_vertical.addWidget(self.toolbar)
        self.manager.setLayout(p1_vertical)

        self.dock.setWidget(self.manager)
        self.dock.setAllowedAreas(Qt.LeftDockWidgetArea
                                  | Qt.RightDockWidgetArea)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

    def run_help(self):
        url = 'http://aequilibrae.com/qgis'
        if sys.platform == 'darwin':  # in case of OS X
            subprocess.Popen(['open', url])
        else:
            webbrowser.open_new_tab(url)

    def run_log(self):
        dlg2 = LogDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def unload(self):
        del self.dock

    def trlt(self, message):
        # In the near future, we will use this function to automatically translate the AequilibraE menu
        # To any language we can get people to translate it to
        # return QCoreApplication.translate('AequilibraE', message)
        return message

    def initGui(self):
        pass

    def removes_temporary_files(self):
        # pass
        # Removes all the temporary files from previous uses
        p = tempfile.gettempdir() + "/aequilibrae_*"
        for f in glob.glob(p):
            try:
                os.unlink(f)
            except:
                pass

    def hide_info_pannel(self):
        if len(self.tabContents) > 0:
            if self.showing.isChecked():
                for v in self.tabContents:
                    self.projectManager.addTab(v[0], v[1])
            else:
                tab_count = 1
                for i in range(tab_count):
                    self.projectManager.removeTab(i)

    def run_load_project(self):
        formats = ["AequilibraE Project(*.sqlite)"]
        path, dtype = GetOutputFileName(
            QtWidgets.QDialog(),
            "AequilibraE Project",
            formats,
            ".sqlite",
            standard_path(),
        )

        # Cleans the project descriptor
        tab_count = 1
        for i in range(tab_count):
            self.projectManager.removeTab(i)

        if dtype is not None:
            self.contents = []
            self.showing.setVisible(True)
            self.project = Project()
            self.project.load(path)
            self.project.conn = qgis.utils.spatialite_connect(path)
            self.project.network.conn = self.project.conn

            uri = QgsDataSourceUri()
            uri.setDatabase(path)
            uri.setDataSource('', 'links', 'geometry')
            self.link_layer = QgsVectorLayer(uri.uri(), 'links', 'spatialite')
            QgsProject.instance().addMapLayer(self.link_layer)

            uri.setDataSource('', 'nodes', 'geometry')
            self.node_layer = QgsVectorLayer(uri.uri(), 'nodes', 'spatialite')
            QgsProject.instance().addMapLayer(self.node_layer)

            descr = QWidget()
            descrlayout = QVBoxLayout()
            # We create a tab with the main description of the project
            p1 = QLabel('Project: {}'.format(path))
            p2 = QLabel('Modes: {}'.format(', '.join(
                self.project.network.modes())))
            p3 = QLabel('Total Links: {:,}'.format(
                self.project.network.count_links()))
            p4 = QLabel('Total Nodes: {:,}'.format(
                self.project.network.count_nodes()))

            for p in [p1, p2, p3, p4]:
                descrlayout.addWidget(p)

            descr.setLayout(descrlayout)
            self.tabContents = [(descr, "Project")]
            self.projectManager.addTab(descr, "Project")

    def run_change_parameters(self):
        dlg2 = ParameterDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_about(self):
        dlg2 = AboutDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_load_matrices(self):
        dlg2 = LoadMatrixDialog(self.iface,
                                sparse=True,
                                multiple=True,
                                single_use=False)
        dlg2.show()
        dlg2.exec_()

    def run_load_database(self):
        dlg2 = LoadDatasetDialog(self.iface, single_use=False)
        dlg2.show()
        dlg2.exec_()

    def run_display_aequilibrae_formats(self):
        dlg2 = DisplayAequilibraEFormatsDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def install_extra_packages(self):
        dlg2 = DownloadExtraPackages(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_binary_download(self):
        dlg2 = BinaryDownloaderDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    # run method that calls the network preparation section of the code
    def run_net_prep(self):
        dlg2 = NetworkPreparationDialog(self.iface)
        dlg2.show()
        dlg2.exec_()
        # If we wanted modal, we would eliminate the dlg2.show()

    # run method that calls the network preparation section of the code
    def run_create_transponet(self):
        if no_binary:
            self.message_binary()
        else:
            dlg2 = CreatesTranspoNetDialog(self.iface)
            dlg2.show()
            dlg2.exec_()
        # If we wanted modal, we would eliminate the dlg2.show()

    def run_add_connectors(self):
        dlg2 = AddConnectorsDialog(self.iface, self.project)
        dlg2.show()
        dlg2.exec_()

    def run_distribution_models(self):
        dlg2 = DistributionModelsDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_shortest_path(self):
        if no_binary:
            self.message_binary()
        else:
            if self.project is None:
                self.show_message_no_project()
            else:
                dlg2 = ShortestPathDialog(self.iface, self.project,
                                          self.link_layer, self.node_layer)
                dlg2.show()
                dlg2.exec_()

    def run_dist_matrix(self):
        if no_binary:
            self.message_binary()
        else:
            if self.project is None:
                self.show_message_no_project()
            else:
                dlg2 = ImpedanceMatrixDialog(self.iface, self.project,
                                             self.link_layer)
                dlg2.show()
                dlg2.exec_()

    def run_traffic_assig(self):
        if no_binary:
            self.message_binary()
        else:
            if self.project is None:
                self.show_message_no_project()
            else:
                dlg2 = TrafficAssignmentDialog(self.iface, self.project,
                                               self.link_layer)
                dlg2.show()
                dlg2.exec_()

    def run_tsp(self):
        if self.project is None:
            self.show_message_no_project()
        else:
            dlg2 = TSPDialog(self.iface, self.project, self.link_layer,
                             self.node_layer)
            dlg2.show()
            dlg2.exec_()

    def run_import_gtfs(self):
        dlg2 = GtfsImportDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_project_from_osm(self):
        dlg2 = ProjectFromOSMDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_simple_tag(self):
        dlg2 = SimpleTagDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_lcd(self):
        dlg2 = LeastCommonDenominatorDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_dlines(self):
        if no_binary:
            self.message_binary()
        else:
            dlg2 = DesireLinesDialog(self.iface)
            dlg2.show()
            dlg2.exec_()

    def run_bandwidth(self):
        dlg2 = CreateBandwidthsDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def run_scenario_comparison(self):
        dlg2 = CompareScenariosDialog(self.iface)
        dlg2.show()
        dlg2.exec_()

    def message_binary(self):
        qgis.utils.iface.messageBar().pushMessage(
            "Binary Error: ",
            "Please download it from the repository using the downloader from the menu",
            level=3)

    def show_message_no_project(self):
        self.iface.messageBar().pushMessage("Error",
                                            "You need to load a project first",
                                            level=3,
                                            duration=10)