PipeRapidの情報をQGISに表示させる(3)選択したスパンに流入する全スパンの探索

過去に投稿した「PipeRapidの情報をQGISに表示させる(2)最長ルートの探索」のスクリプトを応用して、選択スパンに流入する上流側の全スパンを探索することが出来ます。

最長ルートの探索はnetworkx.bellman_ford_pathを使いましたが、上流側の全スパンを探索するにはnetworkx.single_source_shortest_pathを使います。なおグラフも最長ルート探索のときとは逆順で登録する必要があります。ソースコードをご参照ください(説明が手抜きですみません)。

また、関数の詳細については、networkxのドキュメントに記載されています。https://networkx.github.io/documentation/stable/reference/algorithms/shortest_paths.html

最長ルート探索との違いはソースコードだけです。準備すべきモジュールやQGISの操作に関しては変わりありませんので、冒頭に示した過去記事をご参照ください。

# -*- coding: utf-8 -*-
from qgis.utils import iface
from qgis.core import *
import networkx as nx

pr_graph = nx.DiGraph()
pr_list = []  # 全スパンリストを初期化
pr_top = []  # 起点スパンリストを初期化

# 選択したレイヤのフィーチャーを取得(Linkレイヤを事前選択すること)
layer = iface.activeLayer()

# 全部のフィーチャーを取得
features = []
features = [f for f in layer.getFeatures()]

# 選択したフィーチャーを取得(複数選択した場合は、1本のみ取得)
selectfeatures = []
selectfeatures = [sf for sf in layer.selectedFeatures()]
try:
    selectfeature = selectfeatures[0]
    print(selectfeature['URouteNo'], 'を選択しました。')

    # 取得した全フィーチャーのスパン番号とスパン長を有向グラフに登録
    for feature in features:
        # 探索のため流向きと逆向きに登録する
        pr_list.extend([(feature['LNodeNo'], feature['UNodeNo'], \
            {'RouteNO': feature['RouteNo'], 'Length': float(feature['Length'])})])
    pr_graph.add_edges_from(pr_list)

    for pr_span in pr_graph:
        try:
            allroute = nx.single_source_shortest_path(pr_graph, selectfeature['UNodeNo'])
        except:
            pass

    for pr_num in allroute:
        # QGISフィーチャーからの検索
        exp = QgsFeatureRequest().setFilterExpression("UNodeNo ILIKE \'" + pr_num + '\'')
        serchfeatures = layer.getFeatures(exp)
        # 検索されたフィーチャーを選択状態にする
        for feature in serchfeatures:
            layer.selectByIds([feature.id()],QgsVectorLayer.AddToSelection)
            print(feature['URouteNo'] + ' ' + feature['Length'])

except:
    selectfeature = None
    print('選択したフィーチャーはありませんでした。')

Follow me!