def run(self):
        layer = self.iface.mapCanvas().currentLayer()
        if layer is None:
            QMessageBox.information(None, "Chinese Postman",
                                    "Please select a layer.")
            return

        features = layer.selectedFeatures()
        if len(features) == 0:
            QMessageBox.information(
                None, "Chinese Postman",
                "Please select an area. The 'Select Features by Polygon' tool "
                + "works well for this.")
            return

        graph = build_graph(features)
        components = postman.graph_components(graph)
        if len(components) > 1:
            QMessageBox.information(
                None, "Chinese Postman",
                "Warning: the selected area contains multiple disconnected " +
                "components - only the largest one will be used.")

        if len(components) == 0:
            QMessageBox.information(
                None, "Chinese Postman",
                "Error: Could not find any components. Try selecting different features."
            )
            return

        component = components[0]

        eulerian_graph, nodes = postman.single_chinese_postman_path(component)

        in_length = postman.edge_sum(component) / 1000.0
        path_length = postman.edge_sum(eulerian_graph) / 1000.0
        duplicate_length = path_length - in_length

        newlayer = build_layer(eulerian_graph, nodes, layer.crs())
        symbol = build_symbol(newlayer)
        newlayer.setRendererV2(QgsSingleSymbolRendererV2(symbol))
        QgsMapLayerRegistry.instance().addMapLayer(newlayer)

        info = ""
        info += "Total length of roads: %.3f km\n" % in_length
        info += "Total length of path: %.3f km\n" % path_length
        info += "Length of sections visited twice: %.3f km\n" % duplicate_length
        info += "\n"
        info += "(If the above values do not make sense, consider changing CRS.)\n"

        QMessageBox.information(None, "Chinese Postman", info)
Exemple #2
0
    def test_postman(self):
        """
        Test the end result.
        """
        graph = postman.import_csv_graph(open('test_graph.csv', 'r'))
        components = postman.graph_components(graph)

        # Only use the largest component
        component = components[0]

        eulerian_graph, nodes = postman.single_chinese_postman_path(component)

        in_length = postman.edge_sum(graph) / 1000.0
        path_length = postman.edge_sum(eulerian_graph) / 1000.0
        duplicate_length = path_length - in_length

        self.assertAlmostEqual(in_length, 14.889)
        self.assertAlmostEqual(path_length, 20.316)
        self.assertAlmostEqual(duplicate_length, 5.427)
    def test_postman(self):
        """
        Test the end result.
        """
        graph = postman.import_csv_graph(open('test_graph.csv', 'r'))
        components = postman.graph_components(graph)

        # Only use the largest component
        component = components[0]

        eulerian_graph, nodes = postman.single_chinese_postman_path(component)

        in_length = postman.edge_sum(graph) / 1000.0
        path_length = postman.edge_sum(eulerian_graph) / 1000.0
        duplicate_length = path_length - in_length

        self.assertAlmostEqual(in_length, 14.889)
        self.assertAlmostEqual(path_length, 20.316)
        self.assertAlmostEqual(duplicate_length, 5.427)
    def run(self):
        layer = self.iface.mapCanvas().currentLayer()
        if layer is None:
            QMessageBox.information(None, "Chinese Postman", "Please select a layer.")
            return

        features = layer.selectedFeatures()
        if len(features) == 0:
            QMessageBox.information(None, "Chinese Postman", "Please select an area. The 'Select Features by Polygon' tool " +
                                                            "works well for this.")
            return

        graph = build_graph(features)
        components = postman.graph_components(graph)
        if len(components) > 1:
            QMessageBox.information(None, "Chinese Postman", "Warning: the selected area contains multiple disconnected " +
                                                             "components - only the largest one will be used.")

        if len(components) == 0:
            QMessageBox.information(None, "Chinese Postman", "Error: Could not find any components. Try selecting different features.")
            return

        component = components[0]

        eulerian_graph, nodes = postman.single_chinese_postman_path(component)

        in_length = postman.edge_sum(component)/1000.0
        path_length = postman.edge_sum(eulerian_graph)/1000.0
        duplicate_length = path_length - in_length

        newlayer = build_layer(eulerian_graph, nodes, layer.crs())
        symbol = build_symbol(newlayer)
        newlayer.setRendererV2(QgsSingleSymbolRendererV2(symbol))
        QgsMapLayerRegistry.instance().addMapLayer(newlayer)

        info = ""
        info += "Total length of roads: %.3f km\n" % in_length
        info += "Total length of path: %.3f km\n" % path_length
        info += "Length of sections visited twice: %.3f km\n" % duplicate_length
        info += "\n"
        info += "(If the above values do not make sense, consider changing CRS.)\n"

        QMessageBox.information(None, "Chinese Postman", info)