Exemplo n.º 1
0
    def test_reset(self):
        self.r.compute_path(dest, origin)
        self.r.reset()

        self.assertEqual(self.r.path, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.path_nodes, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.path_link_directions, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.milepost, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.predecessors.max(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.predecessors.min(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.connectors.max(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.connectors.min(), -1,
                         "Fail to reset the Path computation object")
        if self.r.skims is not None:
            self.assertEqual(self.r.skims.max(), np.inf,
                             "Fail to reset the Path computation object")
            self.assertEqual(self.r.skims.min(), np.inf,
                             "Fail to reset the Path computation object")

        new_r = PathResults()
        with self.assertRaises(ValueError):
            new_r.reset()
    def __init__(self, iface, project: Project, link_layer: QgsVectorLayer,
                 node_layer: QgsVectorLayer) -> None:
        # QtWidgets.QDialog.__init__(self)
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.project = project
        self.setupUi(self)
        self.field_types = {}
        self.centroids = None
        self.node_layer = node_layer
        self.line_layer = link_layer
        self.node_keys = {}
        self.node_fields = None
        self.index = None
        self.matrix = None
        self.path = standard_path()
        self.node_id = None

        self.res = PathResults()
        self.link_features = None

        self.do_dist_matrix.setEnabled(False)
        self.from_but.setEnabled(False)
        self.to_but.setEnabled(False)
        self.load_graph_from_file.clicked.connect(
            self.prepare_graph_and_network)
        self.from_but.clicked.connect(self.search_for_point_from)
        self.to_but.clicked.connect(self.search_for_point_to)
        self.do_dist_matrix.clicked.connect(self.produces_path)
Exemplo n.º 3
0
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)

        self.result = PathResults()
        self.validtypes = integer_types + float_types
        self.tot_skims = 0
        self.name_skims = 0
        self.skimmeable_fields = []
        self.skim_fields = []
        # FIRST, we connect slot signals

        #For loading a new graph
        self.load_graph_from_file.clicked.connect(
            self.loaded_new_graph_from_file)

        # For adding skims
        self.bt_add_skim.clicked.connect(self.add_to_skim_list)
        self.skim_list.doubleClicked.connect(self.slotDoubleClicked)

        # RUN skims
        self.select_result.clicked.connect(self.browse_outfile)

        self.do_dist_matrix.clicked.connect(self.run_skimming)

        # SECOND, we set visibility for sections that should not be shown when the form opens (overlapping items)
        #        and re-dimension the items that need re-dimensioning
        self.HideAllProgressBars()
        self.skim_list.setColumnWidth(0, 567)

        # loads default path from parameters
        self.path = standard_path()
    def __init__(self, iface):
        QDialog.__init__(self)
        QtGui.QDialog.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
        self.iface = iface
        self.setupUi(self)
        self.field_types = {}
        self.centroids = None
        self.node_layer = None
        self.line_layer = None
        self.node_keys = None
        self.node_fields = None
        self.index = None
        self.matrix = None
        self.clickTool = PointTool(self.iface.mapCanvas())
        self.path = standard_path()
        self.node_id = None

        self.res = PathResults()
        self.link_features = None

        self.do_dist_matrix.setEnabled(False)
        self.load_graph_from_file.clicked.connect(
            self.prepare_graph_and_network)
        self.from_but.clicked.connect(self.search_for_point_from)
        self.to_but.clicked.connect(self.search_for_point_to)
        self.do_dist_matrix.clicked.connect(self.produces_path)
Exemplo n.º 5
0
    def setUp(self) -> None:
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field="distance")

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except Exception as err:
            self.fail("Path result preparation failed - {}".format(err.__str__()))
Exemplo n.º 6
0
    def test_prepare(self):
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field='distance', skim_fields=None)

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except:
            self.fail('Path result preparation failed')
Exemplo n.º 7
0
    def setUp(self) -> None:
        self.project = create_example(join(gettempdir(), "test_set_pce_" + uuid4().hex))
        self.project.network.build_graphs()
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(False)

        self.matrix = self.project.matrices.get_matrix("demand_omx")
        self.matrix.computational_view()

        self.r = PathResults()
        self.r.prepare(self.g)
    def test_path_disconnected_delete_link(self):
        self.project.conn.executemany('delete from Links where link_id=?', [[2], [4], [5], [14]])
        self.project.conn.commit()

        self.project.network.build_graphs()
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(False)
        self.r = PathResults()
        self.r.prepare(self.g)
        self.r.compute_path(1, 5)
        self.assertEqual(None, self.r.path, 'Failed to return None for disconnected')
        self.r.compute_path(1, 2)
        self.assertEqual(len(self.r.path), 1, 'Returned the wrong thing for existing path on disconnected network')
Exemplo n.º 9
0
    def setUp(self) -> None:
        os.environ['PATH'] = os.path.join(
            gettempdir(), 'temp_data') + ';' + os.environ['PATH']
        self.proj_dir = os.path.join(gettempdir(), uuid.uuid4().hex)
        copytree(triangle_graph_blocking, self.proj_dir)
        self.project = Project()
        self.project.open(self.proj_dir)
        self.project.network.build_graphs(modes=["c"])
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(True)

        self.r = PathResults()
        self.r.prepare(self.g)
Exemplo n.º 10
0
    def __init__(self, iface, project: Project, link_layer, node_layer):
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)
        self.project = project
        self.link_layer = link_layer
        self.node_layer = node_layer
        self.all_modes = {}
        self.worker_thread: TSPProcedure = None
        self.but_run.clicked.connect(self.run)
        self.res = PathResults()

        self.rdo_selected.clicked.connect(self.populate_node_source)
        self.rdo_centroids.clicked.connect(self.populate_node_source)
        self.populate()
        self.populate_node_source()
Exemplo n.º 11
0
    def test_prepare(self):
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field='distance', skim_fields=None)

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except:
            self.fail('Path result preparation failed')
    def test_path_disconnected_penalize_link_in_memory(self):
        links = [2, 4, 5, 14]

        self.project.network.build_graphs()
        g = self.project.network.graphs["c"]  # type: Graph
        g.exclude_links(links)
        g.set_graph("free_flow_time")
        g.set_blocked_centroid_flows(False)
        r = PathResults()
        r.prepare(g)
        r.compute_path(1, 5)
        self.assertEqual(None, r.path, 'Failed to return None for disconnected')
        r.compute_path(1, 2)
        self.assertEqual(len(r.path), 1, 'Returned the wrong thing for existing path on disconnected network')
Exemplo n.º 13
0
    def test_compute_with_skimming(self):

        r = PathResults()
        self.g.set_skimming("free_flow_time")
        r.prepare(self.g)
        r.compute_path(origin, dest)
        self.assertEqual(r.milepost[-1], r.skims[dest], "Skims computed wrong when computing path")
Exemplo n.º 14
0
class TestPathResults(TestCase):
    def test_prepare(self):
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field="distance")

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except Exception as err:
            self.fail("Path result preparation failed - {}".format(
                err.__str__()))

    def test_reset(self):
        self.test_prepare()
        try:
            self.r.reset()
        except Exception as err:
            self.fail("Path result resetting failed - {}".format(
                err.__str__()))

    def test_update_trace(self):
        self.test_prepare()
        try:
            self.r.reset()
        except Exception as err:
            self.fail("Path result resetting failed - {}".format(
                err.__str__()))

        path_computation(origin, dest, self.g, self.r)

        if list(self.r.path) != [53, 52, 13]:
            self.fail("Path computation failed. Wrong sequence of links")

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail("Path computation failed. Wrong sequence of path nodes")

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail("Path computation failed. Wrong milepost results")
Exemplo n.º 15
0
class TestPathResults(TestCase):
    def test_prepare(self):
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field='distance', skim_fields=None)

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except:
            self.fail('Path result preparation failed')


    def test_reset(self):
        self.test_prepare()
        try:
            self.r.reset()
        except:
            self.fail('Path result resetting failed')

    def test_update_trace(self):
        self.test_prepare()
        try:
            self.r.reset()
        except:
            self.fail('Path result resetting failed')

        path_computation(origin, dest, self.g, self.r)

        if list(self.r.path) != [53, 52, 13]:
            self.fail('Path computation failed. Wrong sequence of links')

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail('Path computation failed. Wrong sequence of path nodes')

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail('Path computation failed. Wrong milepost results')
Exemplo n.º 16
0
class TestPathResults(TestCase):
    def test_prepare(self):
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field='distance', skim_fields=None)

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except:
            self.fail('Path result preparation failed')


    def test_reset(self):
        self.test_prepare()
        try:
            self.r.reset()
        except:
            self.fail('Path result resetting failed')

    def test_update_trace(self):
        self.test_prepare()
        try:
            self.r.reset()
        except:
            self.fail('Path result resetting failed')

        path_computation(origin, dest, self.g, self.r)

        if list(self.r.path) != [53, 52, 13]:
            self.fail('Path computation failed. Wrong sequence of links')

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail('Path computation failed. Wrong sequence of path nodes')

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail('Path computation failed. Wrong milepost results')
class TestPathResultsDisconnected(TestCase):
    def setUp(self) -> None:
        self.project = create_example(join(gettempdir(), "test_path_disconnected" + uuid4().hex))

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

    def test_path_disconnected_delete_link(self):
        self.project.conn.executemany('delete from Links where link_id=?', [[2], [4], [5], [14]])
        self.project.conn.commit()

        self.project.network.build_graphs()
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(False)
        self.r = PathResults()
        self.r.prepare(self.g)
        self.r.compute_path(1, 5)
        self.assertEqual(None, self.r.path, 'Failed to return None for disconnected')
        self.r.compute_path(1, 2)
        self.assertEqual(len(self.r.path), 1, 'Returned the wrong thing for existing path on disconnected network')

    def test_path_disconnected_penalize_link_in_memory(self):
        links = [2, 4, 5, 14]

        self.project.network.build_graphs()
        g = self.project.network.graphs["c"]  # type: Graph
        g.exclude_links(links)
        g.set_graph("free_flow_time")
        g.set_blocked_centroid_flows(False)
        r = PathResults()
        r.prepare(g)
        r.compute_path(1, 5)
        self.assertEqual(None, r.path, 'Failed to return None for disconnected')
        r.compute_path(1, 2)
        self.assertEqual(len(r.path), 1, 'Returned the wrong thing for existing path on disconnected network')
Exemplo n.º 18
0
# %%
# We set the graph for computation

graph.set_graph('distance')
graph.set_skimming('distance')

# Get the nodes that are part of the car network
missing_nodes = [
    x[0] for x in project.conn.execute(
        f"Select node_id from nodes where instr(modes, '{mode}')").fetchall()
]
missing_nodes = np.array(missing_nodes)

# And prepare the path computation structure
res = PathResults()
res.prepare(graph)

# %%
# Now we can compute all the path islands we have

islands = []
idx_islands = 0
#
while missing_nodes.shape[0] >= 2:
    print(datetime.now().strftime("%H:%M:%S"),
          f' - Computing island: {idx_islands}')
    res.reset()
    res.compute_path(missing_nodes[0], missing_nodes[1])
    res.predecessors[graph.nodes_to_indices[missing_nodes[0]]] = 0
    connected = graph.all_nodes[np.where(res.predecessors >= 0)]
Exemplo n.º 19
0
    def test_exclude_links(self):
        # excludes a link before any setting or preparation
        self.graph.set_blocked_centroid_flows(False)

        self.graph.set_graph("distance")
        r1 = PathResults()
        r1.prepare(self.graph)
        r1.compute_path(20, 21)
        self.assertEqual(list(r1.path), [62])

        r1 = PathResults()
        self.graph.exclude_links([62])
        r1.prepare(self.graph)
        r1.compute_path(20, 21)
        self.assertEqual(list(r1.path), [63, 69])
class ShortestPathDialog(QtWidgets.QDialog, FORM_CLASS):
    clickTool = PointTool(iface.mapCanvas())

    def __init__(self, iface, project: Project, link_layer: QgsVectorLayer,
                 node_layer: QgsVectorLayer) -> None:
        # QtWidgets.QDialog.__init__(self)
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.project = project
        self.setupUi(self)
        self.field_types = {}
        self.centroids = None
        self.node_layer = node_layer
        self.line_layer = link_layer
        self.node_keys = {}
        self.node_fields = None
        self.index = None
        self.matrix = None
        self.path = standard_path()
        self.node_id = None

        self.res = PathResults()
        self.link_features = None

        self.do_dist_matrix.setEnabled(False)
        self.from_but.setEnabled(False)
        self.to_but.setEnabled(False)
        self.load_graph_from_file.clicked.connect(
            self.prepare_graph_and_network)
        self.from_but.clicked.connect(self.search_for_point_from)
        self.to_but.clicked.connect(self.search_for_point_to)
        self.do_dist_matrix.clicked.connect(self.produces_path)

    def prepare_graph_and_network(self):
        self.do_dist_matrix.setText('Loading data')
        self.from_but.setEnabled(False)
        self.to_but.setEnabled(False)
        dlg2 = LoadGraphLayerSettingDialog(self.iface, self.project)
        dlg2.show()
        dlg2.exec_()
        if len(dlg2.error) < 1 and len(dlg2.mode) > 0:
            self.mode = dlg2.mode
            self.minimize_field = dlg2.minimize_field

            if not self.mode in self.project.network.graphs:
                self.project.network.build_graphs()

            if dlg2.remove_chosen_links:
                self.graph = self.project.network.graphs.pop(self.mode)
            else:
                self.graph = self.project.network.graphs[self.mode]
            self.graph.set_graph(self.minimize_field)
            self.graph.set_skimming(self.minimize_field)
            self.graph.set_blocked_centroid_flows(dlg2.block_connector)

            if dlg2.remove_chosen_links:
                idx = self.line_layer.dataProvider().fieldNameIndex('link_id')
                remove = [
                    feat.attributes()[idx]
                    for feat in self.line_layer.selectedFeatures()
                ]
                self.graph.exclude_links(remove)

            self.res.prepare(self.graph)

            self.node_fields = [
                field.name()
                for field in self.node_layer.dataProvider().fields().toList()
            ]
            self.index = QgsSpatialIndex()
            for feature in self.node_layer.getFeatures():
                self.index.addFeature(feature)
                self.node_keys[feature.id()] = feature.attributes()

            idx = self.line_layer.dataProvider().fieldNameIndex('link_id')
            self.link_features = {}
            for feat in self.line_layer.getFeatures():
                link_id = feat.attributes()[idx]
                self.link_features[link_id] = feat

            self.do_dist_matrix.setText('Display')
            self.do_dist_matrix.setEnabled(True)
            self.from_but.setEnabled(True)
            self.to_but.setEnabled(True)

    def clear_memory_layer(self):
        self.link_features = None

    def search_for_point_from(self):
        self.clickTool.clicked.connect(self.fill_path_from)
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.from_but.setEnabled(False)

    def search_for_point_to(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.clickTool.clicked.connect(self.fill_path_to)
        self.to_but.setEnabled(False)

    def search_for_point_to_after_from(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.clickTool.clicked.connect(self.fill_path_to)

    def fill_path_to(self):
        self.to_node = self.find_point()
        self.path_to.setText(str(self.to_node))
        self.to_but.setEnabled(True)

    @QtCore.pyqtSlot()
    def fill_path_from(self):
        self.from_node = self.find_point()
        self.path_from.setText(str(self.from_node))
        self.from_but.setEnabled(True)
        self.search_for_point_to_after_from()

    def find_point(self):
        try:
            point = self.clickTool.point
            nearest = self.index.nearestNeighbor(point, 1)
            self.iface.mapCanvas().setMapTool(None)
            self.clickTool = PointTool(self.iface.mapCanvas())
            node_id = self.node_keys[nearest[0]]

            index_field = self.node_fields.index('node_id')
            node_actual_id = node_id[index_field]
            return node_actual_id
        except:
            pass

    def produces_path(self):
        self.to_but.setEnabled(True)
        if self.path_from.text().isdigit() and self.path_to.text().isdigit():
            self.res.reset()
            path_computation(int(self.path_from.text()),
                             int(self.path_to.text()), self.graph, self.res)

            if self.res.path is not None:
                # If you want to do selections instead of new layers
                if self.rdo_selection.isChecked():
                    self.create_path_with_selection()

                # If you want to create new layers
                else:
                    self.create_path_with_scratch_layer()

            else:
                qgis.utils.iface.messageBar().pushMessage(
                    "No path between " + self.path_from.text() + " and " +
                    self.path_to.text(),
                    "",
                    level=3)

    def create_path_with_selection(self):
        f = 'link_id'
        t = " or ".join([f"{f}={k}" for k in self.res.path])
        self.line_layer.selectByExpression(t)

    def create_path_with_scratch_layer(self):
        crs = self.line_layer.dataProvider().crs().authid()
        vl = QgsVectorLayer(
            "LineString?crs={}".format(crs),
            self.path_from.text() + " to " + self.path_to.text(), "memory")
        pr = vl.dataProvider()

        # add fields
        pr.addAttributes(self.line_layer.dataProvider().fields())
        vl.updateFields(
        )  # tell the vector layer to fetch changes from the provider

        # add a feature
        all_links = []
        for k in self.res.path:
            fet = self.link_features[k]
            all_links.append(fet)

        # add all links to the temp layer
        pr.addFeatures(all_links)

        # add layer to the map
        QgsProject.instance().addMapLayer(vl)

        symbol = vl.renderer().symbol()
        symbol.setWidth(1)
        qgis.utils.iface.mapCanvas().refresh()

    def exit_procedure(self):
        self.close()
Exemplo n.º 21
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()
Exemplo n.º 22
0
class TestPathResults(TestCase):
    def setUp(self) -> None:
        self.project = create_example(
            join(gettempdir(), "test_set_pce_" + uuid4().hex))
        self.project.network.build_graphs()
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(False)

        self.matrix = self.project.matrices.get_matrix("demand_omx")
        self.matrix.computational_view()

        self.r = PathResults()
        self.r.prepare(self.g)

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

    def test_reset(self):
        self.r.compute_path(dest, origin)
        self.r.reset()

        self.assertEqual(self.r.path, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.path_nodes, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.path_link_directions, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.milepost, None,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.predecessors.max(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.predecessors.min(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.connectors.max(), -1,
                         "Fail to reset the Path computation object")
        self.assertEqual(self.r.connectors.min(), -1,
                         "Fail to reset the Path computation object")
        if self.r.skims is not None:
            self.assertEqual(self.r.skims.max(), np.inf,
                             "Fail to reset the Path computation object")
            self.assertEqual(self.r.skims.min(), np.inf,
                             "Fail to reset the Path computation object")

        new_r = PathResults()
        with self.assertRaises(ValueError):
            new_r.reset()

    def test_compute_paths(self):

        path_computation(5, 2, self.g, self.r)

        self.assertEqual(list(self.r.path), [12, 14],
                         "Path computation failed. Wrong sequence of links")
        self.assertEqual(list(self.r.path_link_directions), [1, 1],
                         "Path computation failed. Wrong link directions")
        self.assertEqual(
            list(self.r.path_nodes), [5, 6, 2],
            "Path computation failed. Wrong sequence of path nodes")
        self.assertEqual(list(self.r.milepost), [0, 4, 9],
                         "Path computation failed. Wrong milepost results")

    def test_compute_with_skimming(self):

        r = PathResults()
        self.g.set_skimming("free_flow_time")
        r.prepare(self.g)
        r.compute_path(origin, dest)
        self.assertEqual(r.milepost[-1], r.skims[dest],
                         "Skims computed wrong when computing path")

    def test_update_trace(self):
        self.r.compute_path(origin, 2)

        self.r.update_trace(10)
        self.assertEqual(list(self.r.path), [13, 25],
                         "Path update failed. Wrong sequence of links")
        self.assertEqual(list(self.r.path_link_directions), [1, 1],
                         "Path update failed. Wrong link directions")
        self.assertEqual(list(self.r.path_nodes), [5, 9, 10],
                         "Path update failed. Wrong sequence of path nodes")
        self.assertEqual(list(self.r.milepost), [0, 5, 8],
                         "Path update failed. Wrong milepost results")
Exemplo n.º 23
0
class TestBlockingTrianglePathResults(TestCase):
    def setUp(self) -> None:
        os.environ['PATH'] = os.path.join(
            gettempdir(), 'temp_data') + ';' + os.environ['PATH']
        self.proj_dir = os.path.join(gettempdir(), uuid.uuid4().hex)
        copytree(triangle_graph_blocking, self.proj_dir)
        self.project = Project()
        self.project.open(self.proj_dir)
        self.project.network.build_graphs(modes=["c"])
        self.g = self.project.network.graphs["c"]  # type: Graph
        self.g.set_graph("free_flow_time")
        self.g.set_blocked_centroid_flows(True)

        self.r = PathResults()
        self.r.prepare(self.g)

    def tearDown(self) -> None:
        self.project.close()
        del self.r

    def test_compute_paths(self):
        self.r.compute_path(1, 2)
        self.assertEqual(list(self.r.path_nodes), [1, 3, 2])
        self.assertEqual(list(self.r.path), [1, 2])

        self.r.compute_path(2, 1)
        self.assertEqual(list(self.r.path_nodes), [2, 1])
        self.assertEqual(list(self.r.path), [3])

        self.r.compute_path(3, 1)
        self.assertEqual(list(self.r.path_nodes), [3, 2, 1])
        self.assertEqual(list(self.r.path), [2, 3])

        self.r.compute_path(3, 2)
        self.assertEqual(list(self.r.path_nodes), [3, 2])
        self.assertEqual(list(self.r.path), [2])

        self.r.compute_path(1, 3)
        self.assertEqual(list(self.r.path_nodes), [1, 3])
        self.assertEqual(list(self.r.path), [1])

        self.r.compute_path(2, 3)
        self.assertEqual(list(self.r.path_nodes), [2, 1, 3])
        self.assertEqual(list(self.r.path), [3, 1])

    def test_compute_blocking_paths(self):
        self.r.compute_path(4, 5)
        self.assertEqual(list(self.r.path_nodes), [4, 1, 3, 2, 5])
        self.assertEqual(list(self.r.path), [4, 1, 2, 5])

        self.r.compute_path(5, 4)
        self.assertEqual(list(self.r.path_nodes), [5, 2, 1, 4])
        self.assertEqual(list(self.r.path), [5, 3, 4])

        self.r.compute_path(6, 4)
        self.assertEqual(list(self.r.path_nodes), [6, 3, 2, 1, 4])
        self.assertEqual(list(self.r.path), [6, 2, 3, 4])

        self.r.compute_path(6, 5)
        self.assertEqual(list(self.r.path_nodes), [6, 3, 2, 5])
        self.assertEqual(list(self.r.path), [6, 2, 5])

        self.r.compute_path(4, 6)
        self.assertEqual(list(self.r.path_nodes), [4, 1, 3, 6])
        self.assertEqual(list(self.r.path), [4, 1, 6])

        self.r.compute_path(5, 6)
        self.assertEqual(list(self.r.path_nodes), [5, 2, 1, 3, 6])
        self.assertEqual(list(self.r.path), [5, 3, 1, 6])

    def test_update_trace(self):
        self.r.compute_path(1, 2)
        self.assertEqual(list(self.r.path_nodes), [1, 3, 2])
        self.assertEqual(list(self.r.path), [1, 2])

        self.r.update_trace(3)
        self.assertEqual(list(self.r.path_nodes), [1, 3])
        self.assertEqual(list(self.r.path), [1])

    def test_update_blocking_trace(self):
        self.r.compute_path(4, 5)
        self.assertEqual(list(self.r.path_nodes), [4, 1, 3, 2, 5])
        self.assertEqual(list(self.r.path), [4, 1, 2, 5])

        self.r.update_trace(6)
        self.assertEqual(list(self.r.path_nodes), [4, 1, 3, 6])
        self.assertEqual(list(self.r.path), [4, 1, 6])
class ShortestPathDialog(QtWidgets.QDialog, FORM_CLASS):
    clickTool = PointTool(iface.mapCanvas())

    def __init__(self, iface):
        # QtWidgets.QDialog.__init__(self)
        QtWidgets.QDialog.__init__(self, None, Qt.WindowStaysOnTopHint)
        self.iface = iface
        self.setupUi(self)
        self.field_types = {}
        self.centroids = None
        self.node_layer = None
        self.line_layer = None
        self.node_keys = None
        self.node_fields = None
        self.index = None
        self.matrix = None
        self.path = standard_path()
        self.node_id = None

        self.res = PathResults()
        self.link_features = None

        self.do_dist_matrix.setEnabled(False)
        self.load_graph_from_file.clicked.connect(
            self.prepare_graph_and_network)
        self.from_but.clicked.connect(self.search_for_point_from)
        self.to_but.clicked.connect(self.search_for_point_to)
        self.do_dist_matrix.clicked.connect(self.produces_path)

    def prepare_graph_and_network(self):
        dlg2 = LoadGraphLayerSettingDialog(self.iface)
        dlg2.show()
        dlg2.exec_()
        if dlg2.error is None and dlg2.graph_ok:
            self.link_features = dlg2.link_features
            self.line_layer = dlg2.line_layer
            self.node_layer = dlg2.node_layer
            self.node_keys = dlg2.node_keys
            self.node_id = dlg2.node_id
            self.node_fields = dlg2.node_fields
            self.index = dlg2.index
            self.graph = dlg2.graph
            self.res.prepare(self.graph)
            self.do_dist_matrix.setEnabled(True)

    def clear_memory_layer(self):
        self.link_features = None

    def search_for_point_from(self):
        self.clickTool.clicked.connect(self.fill_path_from)
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.from_but.setEnabled(False)

    def search_for_point_to(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.clickTool.clicked.connect(self.fill_path_to)
        self.to_but.setEnabled(False)

    def search_for_point_to_after_from(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        self.clickTool.clicked.connect(self.fill_path_to)

    def fill_path_to(self):
        self.to_node = self.find_point()
        self.path_to.setText(str(self.to_node))
        self.to_but.setEnabled(True)

    @QtCore.pyqtSlot()
    def fill_path_from(self):
        self.from_node = self.find_point()
        self.path_from.setText(str(self.from_node))
        self.from_but.setEnabled(True)
        self.search_for_point_to_after_from()

    def find_point(self):
        try:
            point = self.clickTool.point
            nearest = self.index.nearestNeighbor(point, 1)
            self.iface.mapCanvas().setMapTool(None)
            self.clickTool = PointTool(self.iface.mapCanvas())
            node_id = self.node_keys[nearest[0]]

            index_field = self.node_fields.index(self.node_id)
            node_actual_id = node_id[index_field]
            return node_actual_id
        except:
            pass

    def produces_path(self):
        self.to_but.setEnabled(True)
        if self.path_from.text().isdigit() and self.path_to.text().isdigit():
            self.res.reset()
            path_computation(int(self.path_from.text()),
                             int(self.path_to.text()), self.graph, self.res)

            if self.res.path is not None:
                ## If you want to do selections instead of new layers, this is how to do it

                # f = self.cb_link_id_field.currentText()
                # t = ''
                # for k in self.res.path[:-1]:
                #     t = t + f + "=" + str(k) + ' or '
                # t = t + f + "=" + str(self.res.path[-1])
                # expr = QgsExpression(t)
                # it = self.line_layer.getFeatures(QgsFeatureRequest(expr))
                #
                # ids = [i.id() for i in it]
                # self.line_layer.setSelectedFeatures(ids)

                # If you want to create new layers
                # This way is MUCH faster

                crs = self.line_layer.dataProvider().crs().authid()
                vl = QgsVectorLayer(
                    "LineString?crs={}".format(crs),
                    self.path_from.text() + " to " + self.path_to.text(),
                    "memory")
                pr = vl.dataProvider()

                # add fields
                pr.addAttributes(self.line_layer.dataProvider().fields())
                vl.updateFields(
                )  # tell the vector layer to fetch changes from the provider

                # add a feature
                all_links = []
                for k in self.res.path:
                    fet = self.link_features[k]
                    all_links.append(fet)

                # add all links to the temp layer
                pr.addFeatures(all_links)

                # add layer to the map
                QgsProject.instance().addMapLayer(vl)

                symbol = vl.renderer().symbol()
                symbol.setWidth(1)
                qgis.utils.iface.mapCanvas().refresh()

            else:
                qgis.utils.iface.messageBar().pushMessage(
                    "No path between " + self.path_from.text() + ' and ' +
                    self.path_to.text(),
                    '',
                    level=3)

    def exit_procedure(self):
        self.close()
Exemplo n.º 25
0
class TestPathResults(TestCase):
    def setUp(self) -> None:
        # graph
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field="distance")

        self.r = PathResults()
        try:
            self.r.prepare(self.g)
        except Exception as err:
            self.fail("Path result preparation failed - {}".format(err.__str__()))

    def test_reset(self):
        self.r.compute_path(dest, origin)
        self.r.reset()

        self.assertEqual(self.r.path, None, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.path_nodes, None, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.path_link_directions, None, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.milepost, None, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.predecessors.max(), -1, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.predecessors.min(), -1, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.connectors.max(), -1, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.connectors.min(), -1, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.skims.max(), np.inf, 'Fail to reset the Path computation object')
        self.assertEqual(self.r.skims.min(), np.inf, 'Fail to reset the Path computation object')

        new_r = PathResults()
        with self.assertRaises(ValueError):
            new_r.reset()

    def test_compute_paths(self):

        path_computation(origin, dest, self.g, self.r)

        if list(self.r.path) != [53, 52, 13]:
            self.fail("Path computation failed. Wrong sequence of links")

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail("Path computation failed. Wrong sequence of path nodes")

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail("Path computation failed. Wrong milepost results")

        self.r.compute_path(origin, dest)

        if list(self.r.path) != [53, 52, 13]:
            self.fail("Path computation failed. Wrong sequence of links")

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail("Path computation failed. Wrong sequence of path nodes")

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail("Path computation failed. Wrong milepost results")

        if list(self.r.path_link_directions) != [-1, -1, -1]:
            self.fail("Path computation failed. Wrong link directions")

        self.r.compute_path(dest, origin)
        if list(self.r.path_link_directions) != [1, 1, 1]:
            self.fail("Path computation failed. Wrong link directions")

    def test_update_trace(self):
        self.r.compute_path(origin, dest - 1)

        self.r.update_trace(dest)

        if list(self.r.path) != [53, 52, 13]:
            self.fail("Path computation failed. Wrong sequence of links")

        if list(self.r.path_nodes) != [5, 168, 166, 27]:
            self.fail("Path computation failed. Wrong sequence of path nodes")

        if list(self.r.milepost) != [0, 341, 1398, 2162]:
            self.fail("Path computation failed. Wrong milepost results")

        if list(self.r.path_link_directions) != [-1, -1, -1]:
            self.fail("Path computation failed. Wrong link directions")
class ShortestPathDialog(QtGui.QDialog, Ui_compute_path):
    def __init__(self, iface):
        QDialog.__init__(self)
        QtGui.QDialog.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
        self.iface = iface
        self.setupUi(self)
        self.field_types = {}
        self.centroids = None
        self.node_layer = None
        self.line_layer = None
        self.node_keys = None
        self.node_fields = None
        self.index = None
        self.matrix = None
        self.clickTool = PointTool(self.iface.mapCanvas())
        self.path = standard_path()
        self.node_id = None

        self.res = PathResults()
        self.link_features = None

        self.do_dist_matrix.setEnabled(False)
        self.load_graph_from_file.clicked.connect(
            self.prepare_graph_and_network)
        self.from_but.clicked.connect(self.search_for_point_from)
        self.to_but.clicked.connect(self.search_for_point_to)
        self.do_dist_matrix.clicked.connect(self.produces_path)

    def prepare_graph_and_network(self):
        dlg2 = LoadGraphLayerSettingDialog(self.iface)
        dlg2.show()
        dlg2.exec_()
        if dlg2.error is None and dlg2.graph_ok:
            self.link_features = dlg2.link_features
            self.line_layer = dlg2.line_layer
            self.node_layer = dlg2.node_layer
            self.node_keys = dlg2.node_keys
            self.node_id = dlg2.node_id
            self.node_fields = dlg2.node_fields
            self.index = dlg2.index
            self.graph = dlg2.graph
            self.res.prepare(self.graph)
            self.do_dist_matrix.setEnabled(True)

    def clear_memory_layer(self):
        self.link_features = None

    def search_for_point_from(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        QObject.connect(self.clickTool, SIGNAL("clicked"), self.fill_path_from)
        self.from_but.setEnabled(False)

    def search_for_point_to(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        QObject.connect(self.clickTool, SIGNAL("clicked"), self.fill_path_to)
        self.to_but.setEnabled(False)

    def search_for_point_to_after_from(self):
        self.iface.mapCanvas().setMapTool(self.clickTool)
        QObject.connect(self.clickTool, SIGNAL("clicked"), self.fill_path_to)

    def fill_path_to(self):
        self.to_node = self.find_point()
        self.path_to.setText(str(self.to_node))
        self.to_but.setEnabled(True)

    def fill_path_from(self):
        self.from_node = self.find_point()
        self.path_from.setText(str(self.from_node))
        self.from_but.setEnabled(True)
        self.search_for_point_to_after_from()

    def find_point(self):
        try:
            point = self.clickTool.point
            nearest = self.index.nearestNeighbor(point, 1)
            self.iface.mapCanvas().setMapTool(None)
            self.clickTool = PointTool(self.iface.mapCanvas())
            node_id = self.node_keys[nearest[0]]

            index_field = self.node_fields.index(self.node_id)
            node_actual_id = node_id[index_field]
            return node_actual_id
        except:
            pass

    def produces_path(self):
        self.to_but.setEnabled(True)
        if self.path_from.text().isdigit() and self.path_to.text().isdigit():
            self.res.reset()
            path_computation(int(self.path_from.text()),
                             int(self.path_to.text()), self.graph, self.res)

            if self.res.path is not None:
                ## If you want to do selections instead of new layers, this is how to do it

                # f = self.cb_link_id_field.currentText()
                # t = ''
                # for k in self.res.path[:-1]:
                #     t = t + f + "=" + str(k) + ' or '
                # t = t + f + "=" + str(self.res.path[-1])
                # expr = QgsExpression(t)
                # it = self.line_layer.getFeatures(QgsFeatureRequest(expr))
                #
                # ids = [i.id() for i in it]
                # self.line_layer.setSelectedFeatures(ids)

                # If you want to create new layers
                # This way is MUCH faster

                crs = self.line_layer.dataProvider().crs().authid()
                vl = QgsVectorLayer(
                    "LineString?crs={}".format(crs),
                    self.path_from.text() + " to " + self.path_to.text(),
                    "memory")
                pr = vl.dataProvider()

                # add fields
                pr.addAttributes(self.line_layer.dataProvider().fields())
                vl.updateFields(
                )  # tell the vector layer to fetch changes from the provider

                # add a feature
                all_links = []
                for k in self.res.path:
                    fet = self.link_features[k]
                    all_links.append(fet)

                # add all links to the temp layer
                pr.addFeatures(all_links)

                # add layer to the map
                QgsMapLayerRegistry.instance().addMapLayer(vl)

                # format the layer with a thick line
                registry = QgsSymbolLayerV2Registry.instance()
                lineMeta = registry.symbolLayerMetadata("SimpleLine")
                symbol = QgsLineSymbolV2()
                lineLayer = lineMeta.createSymbolLayer({
                    'width':
                    '1',
                    'color':
                    self.random_rgb(),
                    'offset':
                    '0',
                    'penstyle':
                    'solid',
                    'use_custom_dash':
                    '0',
                    'joinstyle':
                    'bevel',
                    'capstyle':
                    'square'
                })
                symbol.deleteSymbolLayer(0)
                symbol.appendSymbolLayer(lineLayer)
                renderer = QgsSingleSymbolRendererV2(symbol)
                vl.setRendererV2(renderer)
                qgis.utils.iface.mapCanvas().refresh()

            else:
                qgis.utils.iface.messageBar().pushMessage(
                    "No path between " + self.path_from.text() + ' and ' +
                    self.path_to.text(),
                    '',
                    level=3)

    def random_rgb(self):
        rgb = ''
        for i in range(3):
            rgb = rgb + str(randint(0, 255)) + ','
        return rgb[:-1]

    def exit_procedure(self):
        self.close()
Exemplo n.º 27
0
class TSPDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, iface, project: Project, link_layer, node_layer):
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)
        self.project = project
        self.link_layer = link_layer
        self.node_layer = node_layer
        self.all_modes = {}
        self.worker_thread: TSPProcedure = None
        self.but_run.clicked.connect(self.run)
        self.res = PathResults()

        self.rdo_selected.clicked.connect(self.populate_node_source)
        self.rdo_centroids.clicked.connect(self.populate_node_source)
        self.populate()
        self.populate_node_source()

    def populate_node_source(self):
        self.cob_start.clear()
        if self.rdo_selected.isChecked():
            centroids = self.selected_nodes()
        else:
            curr = self.project.network.conn.cursor()
            curr.execute('select node_id from nodes where is_centroid=1;')
            centroids = [i[0] for i in curr.fetchall()]
        for i in centroids:
            self.cob_start.addItem(str(i))

    def populate(self):
        curr = self.project.network.conn.cursor()
        curr.execute("""select mode_name, mode_id from modes""")
        for x in curr.fetchall():
            self.cob_mode.addItem(f'{x[0]} ({x[1]})')
            self.all_modes[f'{x[0]} ({x[1]})'] = x[1]

        for f in self.project.network.skimmable_fields():
            self.cob_minimize.addItem(f)

    def selected_nodes(self) -> list:
        idx = self.node_layer.dataProvider().fieldNameIndex('node_id')
        c = [
            int(feat.attributes()[idx])
            for feat in self.node_layer.selectedFeatures()
        ]
        return sorted(c)

    def run(self):
        error = None
        md = self.all_modes[self.cob_mode.currentText()]

        self.project.network.build_graphs()
        self.graph = self.project.network.graphs[md]

        if self.rdo_selected.isChecked():
            centroids = self.selected_nodes()
            if len(centroids) < 3:
                qgis.utils.iface.messageBar().pushMessage(
                    "You need at least three selected nodes. ", '', level=3)
                return
            centroids = np.array(centroids).astype(np.int64)
            self.graph.prepare_graph(centroids=centroids)
        else:
            if self.project.network.count_centroids() < 3:
                qgis.utils.iface.messageBar().pushMessage(
                    "You need at least three centroids. ", '', level=3)
                return

        self.graph.set_graph(self.cob_minimize.currentText()
                             )  # let's say we want to minimize time
        self.graph.set_blocked_centroid_flows(self.chb_block.isChecked())
        self.graph.set_skimming([self.cob_minimize.currentText()
                                 ])  # And will skim time and distance
        depot = int(self.cob_start.currentText())
        vehicles = 1
        self.res.prepare(self.graph)
        self.worker_thread = TSPProcedure(qgis.utils.iface.mainWindow(),
                                          self.graph, depot, vehicles)
        self.run_thread()

    def run_thread(self):
        self.worker_thread.ProgressValue.connect(
            self.progress_value_from_thread)
        self.worker_thread.ProgressMaxValue.connect(
            self.progress_range_from_thread)
        self.worker_thread.ProgressText.connect(self.progress_text_from_thread)

        self.worker_thread.finished_threaded_procedure.connect(self.finished)
        self.worker_thread.start()
        self.exec_()

    def progress_range_from_thread(self, value):
        self.progressbar.setRange(0, value)

    def progress_text_from_thread(self, value):
        self.progress_label.setText(value)

    def progress_value_from_thread(self, value):
        self.progressbar.setValue(value)

    def finished(self, procedure):
        ns = self.worker_thread.node_sequence

        if len(ns) < 2:
            return

        all_links = []
        for i in range(1, len(ns)):
            self.res.reset()
            path_computation(ns[i - 1], ns[i], self.graph, self.res)
            all_links.extend(list(self.res.path))

        if self.rdo_new_layer.isChecked():
            self.create_path_with_scratch_layer(all_links)
        else:
            self.create_path_with_selection(all_links)
        self.close()

        if self.worker_thread.report is not None:
            dlg2 = ReportDialog(self.iface, self.worker_thread.report)
            dlg2.show()
            dlg2.exec_()

    def create_path_with_selection(self, all_links):
        f = 'link_id'
        t = " or ".join([f"{f}={k}" for k in all_links])
        self.link_layer.selectByExpression(t)

    def create_path_with_scratch_layer(self, path_links):
        # Create TSP route
        crs = self.link_layer.dataProvider().crs().authid()
        vl = QgsVectorLayer(f"LineString?crs={crs}", 'TSP Solution', "memory")
        pr = vl.dataProvider()

        # add fields
        pr.addAttributes(self.link_layer.dataProvider().fields())
        vl.updateFields(
        )  # tell the vector layer to fetch changes from the provider

        idx = self.link_layer.dataProvider().fieldNameIndex('link_id')
        self.link_features = {}
        for feat in self.link_layer.getFeatures():
            link_id = feat.attributes()[idx]
            self.link_features[link_id] = feat

        # add a feature
        all_links = []
        for k in path_links:
            fet = self.link_features[k]
            all_links.append(fet)

        # add all links to the temp layer
        pr.addFeatures(all_links)

        # add layer to the map
        QgsProject.instance().addMapLayer(vl)

        symbol = vl.renderer().symbol()
        symbol.setWidth(1.6)
        qgis.utils.iface.mapCanvas().refresh()

        # Create TSP stops
        crs = self.node_layer.dataProvider().crs().authid()
        nl = QgsVectorLayer(f"Point?crs={crs}", 'TSP Stops', "memory")
        pn = nl.dataProvider()

        # add fields
        pn.addAttributes(self.node_layer.dataProvider().fields())
        nl.updateFields(
        )  # tell the vector layer to fetch changes from the provider

        idx = self.node_layer.dataProvider().fieldNameIndex('node_id')
        self.node_features = {}
        for feat in self.node_layer.getFeatures():
            node_id = feat.attributes()[idx]
            self.node_features[node_id] = feat

        # add the feature
        stop_nodes = []
        seq = {}
        for i, k in enumerate(self.worker_thread.node_sequence[:-1]):
            fet = self.node_features[k]
            stop_nodes.append(fet)
            seq[k] = i + 1

        # add all links to the temp layer
        pn.addFeatures(stop_nodes)

        # Goes back and adds the order of visitation for each node
        pn.addAttributes([QgsField('sequence', QVariant.Int)])
        nl.updateFields()
        sdx = nl.dataProvider().fieldNameIndex('sequence')

        nl.startEditing()
        for feat in nl.getFeatures():
            node_id = feat.attributes()[idx]
            nl.changeAttributeValue(feat.id(), sdx, seq[node_id])

        nl.commitChanges()

        # add layer to the map
        QgsProject.instance().addMapLayer(nl)
        symbol = QgsMarkerSymbol.createSimple({'name': 'star', 'color': 'red'})
        symbol.setSize(6)
        nl.renderer().setSymbol(symbol)

        qgis.utils.iface.mapCanvas().refresh()
Exemplo n.º 28
0
class ImpedanceMatrixDialog(QtGui.QDialog, Ui_Impedance_Matrix):
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)

        self.result = PathResults()
        self.validtypes = integer_types + float_types
        self.tot_skims = 0
        self.name_skims = 0
        self.skimmeable_fields = []
        self.skim_fields = []
        # FIRST, we connect slot signals

        #For loading a new graph
        self.load_graph_from_file.clicked.connect(
            self.loaded_new_graph_from_file)

        # For adding skims
        self.bt_add_skim.clicked.connect(self.add_to_skim_list)
        self.skim_list.doubleClicked.connect(self.slotDoubleClicked)

        # RUN skims
        self.select_result.clicked.connect(self.browse_outfile)

        self.do_dist_matrix.clicked.connect(self.run_skimming)

        # SECOND, we set visibility for sections that should not be shown when the form opens (overlapping items)
        #        and re-dimension the items that need re-dimensioning
        self.HideAllProgressBars()
        self.skim_list.setColumnWidth(0, 567)

        # loads default path from parameters
        self.path = standard_path()

    def HideAllProgressBars(self):
        self.progressbar.setVisible(False)
        self.progress_label.setVisible(False)
        self.progressbar.setValue(0)
        self.progress_label.setText('')

    def loaded_new_graph_from_file(self):
        file_types = "AequilibraE graph(*.aeg)"
        if len(self.graph_file_name.text()) > 0:
            newname = QFileDialog.getOpenFileName(None, 'Result file',
                                                  self.graph_file_name.text(),
                                                  file_types)
        else:
            newname = QFileDialog.getOpenFileName(None, 'Result file',
                                                  self.path, file_types)

        self.cb_minimizing.clear()
        self.cb_skims.clear()
        self.all_centroids.setText('')
        self.block_paths.setChecked(False)
        if newname is not None:
            self.graph_file_name.setText(newname)
            self.graph = Graph()
            self.graph.load_from_disk(newname)

            self.all_centroids.setText(str(self.graph.centroids))
            if self.graph.block_centroid_flows:
                self.block_paths.setChecked(True)
            graph_fields = list(self.graph.graph.dtype.names)
            self.skimmeable_fields = [
                x for x in graph_fields if x not in [
                    'link_id',
                    'a_node',
                    'b_node',
                    'direction',
                    'id',
                ]
            ]

            for q in self.skimmeable_fields:
                self.cb_minimizing.addItem(q)
                self.cb_skims.addItem(q)

    def add_to_skim_list(self):
        if self.cb_skims.currentIndex() >= 0:
            self.tot_skims += 1
            self.skim_list.setRowCount(self.tot_skims)
            self.skim_list.setItem(
                self.tot_skims - 1, 0,
                QtGui.QTableWidgetItem((self.cb_skims.currentText())))
            self.skim_fields.append(self.cb_skims.currentText())
            self.cb_skims.removeItem(self.cb_skims.currentIndex())

    def slotDoubleClicked(self, mi):
        row = mi.row()
        if row > -1:
            self.cb_skims.addItem(self.skim_list.item(row, 0).text())
            self.skim_fields.pop(row)
            self.skim_list.removeRow(row)
            self.tot_skims -= 1

    def browse_outfile(self):
        file_types = "Comma-Separated files(*.csv)"
        if self.npy_res.isChecked():
            file_types = "Numpy Binnary Array(*.npy)"

        if len(self.imped_results.text()) > 0:
            newname = QFileDialog.getSaveFileName(None, 'Result file',
                                                  self.imped_results.text(),
                                                  file_types)
        else:
            newname = QFileDialog.getSaveFileName(None, 'Result file',
                                                  self.path, file_types)

        self.imped_results.setText('')
        if newname != None:
            self.imped_results.setText(newname)

    def runThread(self):

        QObject.connect(self.workerThread,
                        SIGNAL("ProgressValue( PyQt_PyObject )"),
                        self.ProgressValueFromThread)
        QObject.connect(self.workerThread,
                        SIGNAL("ProgressText( PyQt_PyObject )"),
                        self.ProgressTextFromThread)
        QObject.connect(self.workerThread,
                        SIGNAL("ProgressMaxValue( PyQt_PyObject )"),
                        self.ProgressRangeFromThread)

        QObject.connect(self.workerThread,
                        SIGNAL("FinishedThreadedProcedure( PyQt_PyObject )"),
                        self.FinishedThreadedProcedure)

        self.workerThread.start()
        self.exec_()

    # VAL and VALUE have the following structure: (bar/text ID, value)
    def ProgressRangeFromThread(self, val):
        self.progressbar.setRange(0, val[1])

    def ProgressValueFromThread(self, val):
        self.progressbar.setValue(val[1])

    def ProgressTextFromThread(self, val):
        self.progress_label.setText(val[1])

    def FinishedThreadedProcedure(self, val):
        if self.workerThread.error is not None:
            qgis.utils.iface.messageBar().pushMessage(
                "Assignment did NOT run correctly",
                self.workerThread.error,
                level=3)
        else:
            mat = self.workerThread.skim_matrices
            mat[mat >
                1e308] = np.inf  # We treat the "infinity" that should have been treated within the Cython code

            if self.npy_res.isChecked():
                np.save(self.imped_results.text(), mat)
                q = open(self.imped_results.text() + '.csv', 'w')
                for l in self.skim_fields:
                    print >> q, l
                q.flush()
                q.close()
            if self.csv_res.isChecked():
                q = open(self.imped_results.text(), 'w')
                text = 'Origin,Destination,' + self.cb_minimizing.currentText()
                for l in self.skim_fields:
                    text = text + ',' + l
                print >> q, text
                for i in range(mat.shape[0]):
                    if np.sum(mat[i, :, :]) > 0:
                        for j in range(mat.shape[1]):
                            if np.sum(mat[i, j, :]) > 0:
                                text = str(i) + ',' + str(j)
                                s = 0
                                for k in range(mat.shape[2]):
                                    if mat[i, j, k] != np.inf:
                                        s += mat[i, j, k]
                                        text = text + ',' + str(mat[i, j, k])
                                    else:
                                        text += ','
                                if s > 0:
                                    print >> q, text
                    q.flush()
                q.close()
        self.close()

    def run_skimming(self):  # Saving results
        centroids = int(self.all_centroids.text())
        cost_field = self.cb_minimizing.currentText()
        block_paths = False
        if self.block_paths.isChecked():
            block_paths = True

        if centroids > 0:
            self.graph.set_graph(centroids, cost_field, self.skim_fields,
                                 block_paths)
            self.result.prepare(self.graph)
        else:
            qgis.utils.iface.messageBar().pushMessage(
                "Nothing to run.", 'Number of centroids set to zero', level=3)

        if len(self.imped_results.text()) == 0:
            qgis.utils.iface.messageBar().pushMessage(
                "Cannot run.", 'No output file provided', level=3)
        else:
            self.funding1.setVisible(False)
            self.funding2.setVisible(False)
            self.progressbar.setVisible(True)
            self.progress_label.setVisible(True)
            self.workerThread = ComputeDistMatrix(
                qgis.utils.iface.mainWindow(), self.graph, self.result)
            self.runThread()