2023,江端さんの技術メモ

QGISでノード番号のある場所を見つける方法が分からなくて困っていましたが、ようやく方法を見つけましたので、メモを残します。

この場合、180以下のノード番号が表示されていますが、特定の番号を指定したければ、(例えば、id=3)と入力すれば、そのノードだけが表示されます。

以上

2023,江端さんの技術メモ

SELECT seq, node, edge, b.cost
FROM pgr_dijkstra(
    'SELECT gid as id, source, target, cost, reverse_cost FROM ways WHERE source NOT BETWEEN 10 AND 20 AND target NOT BETWEEN 10 AND 20',
    1, 50, directed := false
) a
INNER JOIN ways b ON (a.edge = b.gid)
ORDER BY seq;

出力結果
seq | node | edge | cost
-----+------+------+------------------------
1 | 1 | 2 | 8.518550262944416e-06
2 | 2 | 3 | 9.420518456308501e-05
3 | 3 | 4 | 2.6662995399998606e-05
4 | 4 | 6 | 2.1389117484400878e-05
5 | 5 | 7 | 4.6563628817813256e-06
6 | 6 | 1313 | 7.188606587820858e-06
7 | 863 | 126 | 1.0007051975223507e-05
8 | 99 | 127 | 1.450451593740212e-05
9 | 100 | 129 | 7.160567611289415e-06
10 | 101 | 131 | 4.109420419283505e-05
11 | 102 | 133 | 2.934679929904221e-05
12 | 103 | 135 | 1.5514200871555155e-05
13 | 104 | 137 | 1.2955240951715268e-05
14 | 105 | 139 | 3.932409601088787e-05
15 | 106 | 141 | 3.756326743314803e-05
16 | 107 | 143 | 6.437495269868342e-05
17 | 108 | 145 | 3.580138401404371e-05
18 | 109 | 147 | 5.81727588604755e-05
19 | 110 | 148 | 4.310761927462597e-05
20 | 651 | 1196 | 0.00021148735186994806
21 | 780 | 995 | 0.00017553851429442523
22 | 653 | 997 | 5.381635439655622e-05
23 | 654 | 996 | 3.9727662820583996e-05
24 | 21 | 24 | 6.931684268013142e-06
25 | 22 | 25 | 7.70969814835397e-06
26 | 23 | 26 | 1.2029326750062135e-05
27 | 24 | 27 | 3.163056561909417e-05
28 | 25 | 28 | 3.715561627508799e-05
29 | 26 | 29 | 1.6759949788587843e-05
30 | 27 | 30 | 1.3935943447597369e-05
31 | 28 | 31 | 7.276956035534738e-06
32 | 29 | 32 | 1.2096545992840006e-05
33 | 30 | 33 | 4.534133154905821e-05
34 | 31 | 34 | 1.8836761764769703e-05
35 | 32 | 35 | 8.806681794688408e-06
36 | 33 | 36 | 7.526055852520615e-06
37 | 34 | 37 | 1.0243676427727028e-05
38 | 35 | 38 | 1.5622874238716658e-05
39 | 36 | 39 | 6.894091782961944e-06
40 | 37 | 40 | 1.786596350373829e-05
41 | 38 | 41 | 1.796453895498639e-05
42 | 39 | 42 | 6.566793603978039e-05
43 | 40 | 43 | 4.0144224056584715e-05
44 | 41 | 44 | 2.037304658526977e-05
45 | 42 | 45 | 1.643518634972223e-05
46 | 43 | 46 | 1.1916705412252495e-05
47 | 44 | 47 | 1.0031152210412222e-05
48 | 45 | 48 | 1.1949163674231717e-05
49 | 46 | 49 | 1.7529822253810993e-05
50 | 47 | 50 | 1.9115799546536715e-05
51 | 48 | 51 | 5.101757589403705e-05
52 | 49 | 53 | 2.8187114581170035e-05

2023,江端さんの技術メモ

送信プログラム(send_data.c):

#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    uint32_t data = 0x12345678; // 4バイトのデータ(0x12345678)

    // ソケットの作成
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        return 1;
    }

    // 送信先サーバの情報を設定
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(12345); // 送信先ポート番号
    server_addr.sin_addr.s_addr = INADDR_LOOPBACK; // ループバックアドレス (127.0.0.1)
    # INADDR_LOOPBACK で動かなければ、INADDR_ANY を使う

    // データを送信
    if (sendto(sockfd, &data, sizeof(uint32_t), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("sendto");
        close(sockfd);
        return 1;
    }

    printf("Data sent: 0x%X\n", data);

    close(sockfd);

    return 0;
}

受信プログラム(receive_data.c):

#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    socklen_t client_addr_size = sizeof(client_addr);
    uint32_t received_data;

    // ソケットの作成
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        return 1;
    }

    // サーバの情報を設定
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(12345); // 受信ポート番号
    server_addr.sin_addr.s_addr = INADDR_ANY;

    // ソケットとポートを結びつける
    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        close(sockfd);
        return 1;
    }

    printf("UDP Server is waiting for messages...\n");

    while (1) {
        // データを受信
        if (recvfrom(sockfd, &received_data, sizeof(uint32_t), 0, (struct sockaddr *)&client_addr, &client_addr_size) == -1) {
            perror("recvfrom");
            close(sockfd);
            return 1;
        }

        printf("Received Data: 0x%X\n", received_data);
    }

    close(sockfd);

    return 0;
}

2023,江端さんの技術メモ

■ダイクストラ計算を使った方法(一般的なやりかた)
tomioka_db_b=# SELECT seq, node, edge, b.cost FROM pgr_dijkstra('SELECT gid as id, source, target, cost, reverse_cost FROM ways',1, 11) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
seq | node | edge | cost
-----+------+------+------------------------
1 | 1 | 2 | 8.518550262944416e-06
2 | 2 | 3 | 9.420518456308501e-05
3 | 3 | 4 | 2.6662995399998606e-05
4 | 4 | 6 | 2.1389117484400878e-05
5 | 5 | 7 | 4.6563628817813256e-06
6 | 6 | 8 | 1.3184236987589488e-05
7 | 7 | 9 | 6.438782425766514e-06
8 | 8 | 10 | 3.92599380897713e-05
9 | 9 | 11 | 3.1320245670872654e-05
10 | 10 | 12 | 1.7193010226696205e-05

■ところが、こうすると、2番目の最短距離が算出できます。

tomioka_db_b=# SELECT seq, node, edge, b.cost FROM pgr_ksp('SELECT gid as id, source, target, cost, reverse_cost FROM ways',1, 11, 2) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
seq | node | edge | cost
-----+------+------+------------------------
1 | 1 | 2 | 8.518550262944416e-06
2 | 2 | 3 | 9.420518456308501e-05
3 | 3 | 4 | 2.6662995399998606e-05
4 | 4 | 6 | 2.1389117484400878e-05
5 | 5 | 7 | 4.6563628817813256e-06
6 | 6 | 8 | 1.3184236987589488e-05
7 | 7 | 9 | 6.438782425766514e-06
8 | 8 | 10 | 3.92599380897713e-05
9 | 9 | 11 | 3.1320245670872654e-05
10 | 10 | 12 | 1.7193010226696205e-05
12 | 1 | 2 | 8.518550262944416e-06
13 | 2 | 1214 | 7.368115779153013e-06
14 | 792 | 118 | 8.976775615866592e-06
15 | 95 | 119 | 9.423341104506603e-05
16 | 96 | 121 | 2.578196166482512e-05
17 | 97 | 123 | 2.35136729002621e-05
18 | 98 | 125 | 6.587696385101331e-06
19 | 99 | 126 | 1.0007051975223507e-05
20 | 863 | 1313 | 7.188606587820858e-06
21 | 6 | 8 | 1.3184236987589488e-05
22 | 7 | 9 | 6.438782425766514e-06
23 | 8 | 10 | 3.92599380897713e-05
24 | 9 | 11 | 3.1320245670872654e-05
25 | 10 | 12 | 1.7193010226696205e-05

10番目までを出したかったら、上記の"2"を、"10"にすれば出てきます。
綺麗に直す方法については、がんばって下さい。

 

 

 

2023,江端さんの忘備録

メンタルヘルスに対する研究や理解は、日々進んでいると思います。

I believe that research and understanding of mental health is advancing every day.

もちろん、まだまだ十分ではないことは分かっています。

Of course, I know that it is still not enough.

メンタル疾患が誰にでも簡単に発生することは、「自分」で理解しています。

I understand that mental illness can quickly occur in anyone.

加えて、私は、メンタル疾患の被害者でもありますが、加害者でもあったという自覚もあります。

In addition, I am aware that I have been both a victim and a perpetrator of mental illness.

私なら、『今でも報復を諦めていない』くらいのことは言うと思う。

現在のメンタルヘルス研究は、『加害者としての自己』という観点がスッポリ抜けているような気がします。

I feel that current mental health research is missing the perspective of 'self as perpetrator.'

-----

私、最近、

I recently, want someone to try

―― 歴史上の人物(特に日本史)における、特に戦国武将のメンタル疾患についての研究

"Research on mental illness in historical figures (especially Japanese history), especially warlords of the Warring States period"

を、誰かにやってもらいたいと思っています。

一応、Google Scholarで調べてみたのですが、ドンピシャと思われる研究論文は見つけられませんでした。

In the meantime, I checked Google Scholar but could not find any research papers that seemed to be downloadable.

-----

YouTubeで、大河ドラマのビデオクリップを見ているのですが、戦国武将の日常は、殺戮と裏切りと身内の粛清のオンパレードです。

I have been watching video clips of the Taiga drama on YouTube, and the daily life of the warlords was a parade of carnage, betrayal, and purges of their team.

そんな状態で、「武士道」だの「武人の誉れ」などと、綺麗ごとを言えるメンタルが、全然理解できません。

In such a state, I cannot understand the mentality of having said beautiful words such as "bushido" and "honor of the warrior."

ダブルスタンダードもいいところです。

That was typical double standards.

戦国武将は、多重人格障害をデフォルトで持っているとしか思えないです。

I can only assume that warlords have dissociative identity disorder by default.

私は、日本でもっとも著名な戦国武将について『双極性障害』であったと決めつけていますが、他の戦国武将はどうだったのかなぁ、と興味があります。

I have determined that the most famous warlord in Japan was "bipolar," but I am curious to know what other warlords were like.

―― 何やってんだろうなあ、桶狭間合戦場跡は

-----

限られた歴史文献だけを使って、戦国武将たちのメンタルを推定する、というのは、相当難しい研究だとは思います。

I think it is quite a problematic study to estimate the mentality of warlords using only limited historical documents.

しかし、その研究は、現在の私たちのメンタル疾患の治療法に寄与する、と思っています。

However, I believe the research contributes to treating our mental illnesses.

2023,江端さんの技術メモ

package main
/*

f:\しゅらばしゅう\有吉先生データ\Transfer(2018)\N07-11_14_GML>go run nearest_node3.go 

golangで、以下のbus_stop_modified.csvというファイル名から読み取った位置情報ごとに、
以下のtsuzuki_bus.osmファイルのnodeに記載された位置情報と50メートル以内のnodeと
その距離を算出するプログラムを作って下さい。

[bus_stop_modified.csv]
35.522547,139.590950
35.522547,139.590950
35.564881,139.580736
35.566768,139.583192
35.569075,139.584080

[tsuzuki_bus.osm]
<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='200000' visible='true' version='1' lat='35.568239' lon='139.552822' />
<node id='200001' visible='true' version='1' lat='35.568164' lon='139.5528' />
<node id='200002' visible='true' version='1' lat='35.568321' lon='139.551491' />
<node id='200003' visible='true' version='1' lat='35.568338' lon='139.55136' />
<node id='200004' visible='true' version='1' lat='35.568355' lon='139.551264' />
</osm>

*/
import (
"encoding/csv"
"encoding/xml"
"fmt"
"math"
"os"
"strconv"
)


type Node struct {
XMLName xml.Name `xml:"node"`
ID      string   `xml:"id,attr"`
Lat     string   `xml:"lat,attr"`
Lon     string   `xml:"lon,attr"`
}


func haversine(lat1, lon1, lat2, lon2 float64) float64 {
radius := 6371.0 // Earth's radius in kilometers
latRad1 := lat1 * (math.Pi / 180)
latRad2 := lat2 * (math.Pi / 180)
deltaLat := (lat2 - lat1) * (math.Pi / 180)
deltaLon := (lon2 - lon1) * (math.Pi / 180)


a := math.Sin(deltaLat/2)*math.Sin(deltaLat/2) +
math.Cos(latRad1)*math.Cos(latRad2)*
math.Sin(deltaLon/2)*math.Sin(deltaLon/2)
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))


distance := radius * c
return distance
}


func main() {
// Read CSV file
csvFile, err := os.Open("bus_stop_modified.csv")
if err != nil {
fmt.Println("Error opening CSV file:", err)
return
}
defer csvFile.Close()


csvReader := csv.NewReader(csvFile)
positions, err := csvReader.ReadAll()
if err != nil {
fmt.Println("Error reading CSV:", err)
return
}


// Read OSM file
xmlFile, err := os.Open("tsuzuki_bus.osm")
if err != nil {
fmt.Println("Error opening OSM file:", err)
return
}
defer xmlFile.Close()


var nodes struct {
XMLName xml.Name `xml:"osm"`
Nodes   []Node   `xml:"node"`
}


// Parse OSM XML
decoder := xml.NewDecoder(xmlFile)
err = decoder.Decode(&nodes)
if err != nil {
fmt.Println("Error decoding OSM XML:", err)
return
}


// Find nodes within 50 meters for each position
for _, position := range positions {
lat, _ := strconv.ParseFloat(position[0], 64)
lon, _ := strconv.ParseFloat(position[1], 64)


fmt.Printf("For Position (%s, %s):\n", position[0], position[1])


for _, node := range nodes.Nodes {
nodeLat, _ := strconv.ParseFloat(node.Lat, 64)
nodeLon, _ := strconv.ParseFloat(node.Lon, 64)


dist := haversine(lat, lon, nodeLat, nodeLon)
if dist <= 0.05 { // 50 meters in kilometers
fmt.Printf("Node ID: %s\n", node.ID)
fmt.Printf("Node Coordinates: %s, %s\n", node.Lat, node.Lon)
fmt.Printf("Distance to Node: %.2f km\n", dist)
}
}
fmt.Println("--------------------------")
}
}

出力結果

go run nearest_node3.go
For Position (35.522547, 139.590950):
Node ID: 216067
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 216068
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 253004
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 253005
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 287056
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 287057
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 335005
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 335006
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 350106
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 350107
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 351568
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 351569
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
--------------------------
For Position (35.522547, 139.590950):
Node ID: 216067
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km
Node ID: 216068
Node Coordinates: 35.522885, 139.591253
Distance to Node: 0.05 km
Node ID: 253004
Node Coordinates: 35.522356, 139.591082
Distance to Node: 0.02 km

2023,江端さんの技術メモ

OSMファイルからバスルート情報を取り出して、同じバス停留所の名前が同じの場合、位置情報の平均値を計算して算出する方法

(以下、"私だけが分かればいい"メモ)

/*

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)>go run bus_route_try_10.go

Golangで、以下のXML分の中から、<tag k="route" v="bus"/>を発見した時に、refの要素を参照にして位置情報を取り出すプログラム

そんで、同じ名前の停留所があったら、その座標の平均値として出力する

*/

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Osm struct {
	XMLName   xml.Name   `xml:"osm"`
	Nodes     []Node     `xml:"node"`
	Relations []Relation `xml:"relation"`
}

type Node struct {
	ID   int64   `xml:"id,attr"`
	Lat  float64 `xml:"lat,attr"`
	Lon  float64 `xml:"lon,attr"`
	Tags []Tag   `xml:"tag"`
}

type Relation struct {
	ID      int64    `xml:"id,attr"`
	Members []Member `xml:"member"`
	Tags    []Tag    `xml:"tag"`
}

type Member struct {
	Type string `xml:"type,attr"`
	Ref  string `xml:"ref,attr"`
	Role string `xml:"role,attr"`
}

type Tag struct {
	K string `xml:"k,attr"`
	V string `xml:"v,attr"`
}

func main() {

	// XMLファイルの読み込み
	xmlFile, err := os.Open("tsuzuki.osm") // これがベースとなるosmファイル
	if err != nil {
		log.Fatal(err)
	}
	defer xmlFile.Close()

	// XMLデータの読み込み
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		log.Fatal(err)
	}

	var osmData Osm

	// XMLデータのUnmarshal
	err = xml.Unmarshal(xmlData, &osmData)
	if err != nil {
		log.Fatal(err)
	}

	for _, relation := range osmData.Relations {

		//hasBusRouteTag := false

		for _, tag := range relation.Tags {

			if tag.K == "route" && tag.V == "bus" {

				for _, tag := range relation.Tags { // Tagの中で再度tagを回してnameを取得する(こんなことができるとは知りませんでした)
					if tag.K == "name" {
						fmt.Println("=========================")
						fmt.Printf("Route Name: %s\n", tag.V)
						break
					}
				}

				count := 0
				start_flag := 0
				//end_flag := 0
				pre_node := "ddd"
				sum_Lat := 0.0
				sum_Lon := 0.0

				for i, member := range relation.Members {

					if i == len(relation.Members)-1 { // 最後のノードを検知したら、その時点で纏めて計算して出力する
						//end_flag = 1

						fmt.Printf("Re:Bus Stop: %s\n", pre_node)
						fmt.Printf("Re:Coordinates: Lat %f, Lon %f\n\n", sum_Lat/float64(count), sum_Lon/float64(count))
					}

					if member.Type == "node" {
						node := getNodeByID(member.Ref, osmData.Nodes)
						if node != nil {

							if pre_node == getNodeName(node) || start_flag == 0  { // 停留所名が前回と同じであるなら

								count++
								sum_Lat += node.Lat
								sum_Lon += node.Lon

								start_flag = 1

							} else {

								fmt.Printf("Re:Bus Stop: %s\n", pre_node)
								fmt.Printf("Re:Coordinates: Lat %f, Lon %f\n\n", sum_Lat/float64(count), sum_Lon/float64(count))

								count = 1
								sum_Lat = node.Lat
								sum_Lon = node.Lon
							}

							pre_node = getNodeName(node)

						} 					   
					}
				}

			}
		}
	}
}

func getNodeByID(ref string, nodes []Node) *Node {
	for _, node := range nodes {
		if fmt.Sprintf("%d", node.ID) == ref {
			return &node
		}
	}
	return nil
}

func getNodeName(node *Node) string {
	for _, tag := range node.Tags {
		if tag.K == "name" {
			return tag.V
		}
	}
	return ""
}

出力はこんな感じになります。

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)>go run bus_route_try_10.go
=========================
Route Name: IKEAシャトルバス 新横浜駅前-IKEA前
Re:Bus Stop: IKEAシャトルバス IKEA前
Re:Coordinates: Lat 35.522547, Lon 139.590950

=========================
Route Name: IKEAシャトルバス IKEA前-新横浜駅前
Re:Bus Stop: IKEAシャトルバス IKEA前
Re:Coordinates: Lat 35.522547, Lon 139.590950

=========================
Route Name: すみれが丘線
Re:Bus Stop: すみれが丘
Re:Coordinates: Lat 35.564881, Lon 139.580736

Re:Bus Stop: すみれが丘公園
Re:Coordinates: Lat 35.566768, Lon 139.583192

Re:Bus Stop: 有馬変電所
Re:Coordinates: Lat 35.569075, Lon 139.584080

Re:Bus Stop: 中有馬
Re:Coordinates: Lat 35.571500, Lon 139.584235

Re:Bus Stop: 神明社前
Re:Coordinates: Lat 35.571684, Lon 139.580940

Re:Bus Stop: 地区センター前
Re:Coordinates: Lat 35.560333, Lon 139.595547

Re:Bus Stop: 北山田駅
Re:Coordinates: Lat 35.561022, Lon 139.592536

Re:Bus Stop: 山田富士
Re:Coordinates: Lat 35.561428, Lon 139.590315

Re:Bus Stop: 重代
Re:Coordinates: Lat 35.563485, Lon 139.584835

Re:Bus Stop: 北山田小学校入口
Re:Coordinates: Lat 35.563816, Lon 139.582279

Re:Bus Stop: 東山田営業所
Re:Coordinates: Lat 35.561115, Lon 139.606000

Re:Bus Stop: 東山田営業所前
Re:Coordinates: Lat 35.561358, Lon 139.604353

Re:Bus Stop: 山田小学校
Re:Coordinates: Lat 35.560874, Lon 139.602905

Re:Bus Stop: 長泉寺
Re:Coordinates: Lat 35.560052, Lon 139.597552

=========================
Route Name: 鷺沼線;有馬線
Re:Bus Stop: 神明社前

2023,江端さんの技術メモ

sharpファイルで得られたバスルートのデータを力づくでosmファイルにする

上記の方法で作成したOSMファイルでは、OSMにした時に、Nodeがバスルートの終端ににしかできないことが分かり、正直愕然としていました。これでは、バスの乗客は、バスの出発と到着地点でしか乗降できないことになるからです。

なんとかNodeを作り出せないか、色々試していたまま、いたずらに時間が過ぎていったのですが、ようやく、分かりました。

答えは、Tag情報を付与すること、でした。

作成したOMSファイルはこんな感じ

<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='200000' visible='true' version='1' lat='35.568239' lon='139.552822' />
<node id='200001' visible='true' version='1' lat='35.568164' lon='139.5528' />
<node id='200002' visible='true' version='1' lat='35.568321' lon='139.551491' />
<node id='200003' visible='true' version='1' lat='35.568338' lon='139.55136' />
<node id='200004' visible='true' version='1' lat='35.568355' lon='139.551264' />
<node id='200005' visible='true' version='1' lat='35.568406' lon='139.550885' />
<node id='200006' visible='true' version='1' lat='35.568423' lon='139.550768' />
<node id='200007' visible='true' version='1' lat='35.568445' lon='139.550568' />
<node id='200008' visible='true' version='1' lat='35.568462' lon='139.550513' />
<node id='200009' visible='true' version='1' lat='35.568507' lon='139.550154' />
<node id='200010' visible='true' version='1' lat='35.568564' lon='139.549755' />
<node id='200011' visible='true' version='1' lat='35.568603' lon='139.549438' />
<node id='200012' visible='true' version='1' lat='35.568665' lon='139.548962' />
<node id='200013' visible='true' version='1' lat='35.568671' lon='139.54888' />
<node id='200014' visible='true' version='1' lat='35.56871' lon='139.548563' />
<node id='200015' visible='true' version='1' lat='35.568817' lon='139.54744' />
<node id='200016' visible='true' version='1' lat='35.568851' lon='139.547054' />
<node id='200017' visible='true' version='1' lat='35.568879' lon='139.546737' />
<node id='200018' visible='true' version='1' lat='35.568924' lon='139.546475' />
<node id='200019' visible='true' version='1' lat='35.568986' lon='139.546241' />
<node id='200020' visible='true' version='1' lat='35.569071' lon='139.545979' />
<node id='200021' visible='true' version='1' lat='35.569094' lon='139.545918' />
<node id='200022' visible='true' version='1' lat='35.569057' lon='139.54587' />
<node id='200023' visible='true' version='1' lat='35.568969' lon='139.54582' />
<node id='200024' visible='true' version='1' lat='35.568586' lon='139.545565' />
<node id='200025' visible='true' version='1' lat='35.568372' lon='139.545373' />
<node id='200026' visible='true' version='1' lat='35.567171' lon='139.543939' />
<node id='200027' visible='true' version='1' lat='35.566558' lon='139.543161' />
<node id='200028' visible='true' version='1' lat='35.566434' lon='139.543016' />
<node id='200029' visible='true' version='1' lat='35.56622' lon='139.542644' />
<node id='200030' visible='true' version='1' lat='35.565938' lon='139.542162' />
<node id='200031' visible='true' version='1' lat='35.565519' lon='139.541454' />
<node id='200032' visible='true' version='1' lat='35.565482' lon='139.541383' />

QGISの表示はこんな感じ

Nodeが全然表われません。

今度は、これに、適当に

'/>  → '> <tag k='highway' v='bus_stop'/> 

と、適当に変換・追加してしてみました。

<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='200000' visible='true' version='1' lat='35.568239' lon='139.552822'/>
<node id='200001' visible='true' version='1' lat='35.568164' lon='139.5528'/>
<node id='200002' visible='true' version='1' lat='35.568321' lon='139.551491'/>
<node id='200003' visible='true' version='1' lat='35.568338' lon='139.55136'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200004' visible='true' version='1' lat='35.568355' lon='139.551264'/>
<node id='200005' visible='true' version='1' lat='35.568406' lon='139.550885'/>
<node id='200006' visible='true' version='1' lat='35.568423' lon='139.550768'/>
<node id='200007' visible='true' version='1' lat='35.568445' lon='139.550568'/>
<node id='200008' visible='true' version='1' lat='35.568462' lon='139.550513'/>
<node id='200009' visible='true' version='1' lat='35.568507' lon='139.550154'/>
<node id='200010' visible='true' version='1' lat='35.568564' lon='139.549755'/>
<node id='200011' visible='true' version='1' lat='35.568603' lon='139.549438'/>
<node id='200012' visible='true' version='1' lat='35.568665' lon='139.548962'/>
<node id='200013' visible='true' version='1' lat='35.568671' lon='139.54888'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200014' visible='true' version='1' lat='35.56871' lon='139.548563'/>
<node id='200015' visible='true' version='1' lat='35.568817' lon='139.54744'/>
<node id='200016' visible='true' version='1' lat='35.568851' lon='139.547054'/>
<node id='200017' visible='true' version='1' lat='35.568879' lon='139.546737'/>
<node id='200018' visible='true' version='1' lat='35.568924' lon='139.546475'/>
<node id='200019' visible='true' version='1' lat='35.568986' lon='139.546241'/>
<node id='200020' visible='true' version='1' lat='35.569071' lon='139.545979'/>
<node id='200021' visible='true' version='1' lat='35.569094' lon='139.545918'/>
<node id='200022' visible='true' version='1' lat='35.569057' lon='139.54587'/>
<node id='200023' visible='true' version='1' lat='35.568969' lon='139.54582'/>
<node id='200024' visible='true' version='1' lat='35.568586' lon='139.545565'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200025' visible='true' version='1' lat='35.568372' lon='139.545373'/>

その結果、このOSMファイル(tsuzuki_bus_trial2.osm)を、QGISで表示してみたら、こんな感じになりました。

Nodeが追加されています。

しかし、問題は、postGISでダイクストラ計算ができことが重要ですので、まずは、このosmをPostgresql にインポートしてみます。手順はいつも通りですが、ざっと記載しておきます。

C:\Users\ebata>psql -U postgres -h 192.168.0.23 -p 15432
postgres=# create database tsuzuki_bus;
CREATE DATABASE
tsuzuki_bus=# create extension postgis;
CREATE EXTENSION
tsuzuki_bus=# create extension pgrouting;
CREATE EXTENSION

で、postGISが動くDBの作成を完了しました。
で次に、

まだ試してないけど、バス停の追加は多分、これで可能となるはず

で作成した、mapconfig_for_cars_rail_busstop.xml 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <tag_name name="highway" id="1">
    <tag_value name="bus_stop"/>
    <tag_value name="motorway"          id="101" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_link"     id="102" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
    <tag_value name="trunk"             id="104" priority="1.05" maxspeed="110" />
    <tag_value name="trunk_link"        id="105" priority="1.05" maxspeed="110" />    
    <tag_value name="primary"           id="106" priority="1.15" maxspeed="90" />
    <tag_value name="primary_link"      id="107" priority="1.15" maxspeed="90" />    
    <tag_value name="secondary"         id="108" priority="1.5" maxspeed="90" />
    <tag_value name="secondary_link"    id="109" priority="1.5" maxspeed="90"/>  
    <tag_value name="tertiary"          id="110" priority="1.75" maxspeed="90" />
    <tag_value name="tertiary_link"     id="111" priority="1.75" maxspeed="90" />  
    <tag_value name="residential"       id="112" priority="2.5" maxspeed="50" />
    <tag_value name="living_street"     id="113" priority="3" maxspeed="20" />
    <tag_value name="service"           id="114" priority="2.5" maxspeed="50" />
    <tag_value name="unclassified"      id="117" priority="3" maxspeed="90"/>
    <tag_value name="road"              id="100" priority="5" maxspeed="50" />
  </tag_name> 
  <tag_name name="railway" id="1">
    <tag_value name="subway"              id="101" priority="1.0" maxspeed="40" />
    <tag_value name="rail"              id="101" priority="1.0" maxspeed="40" />
  </tag_name> 
</configuration>

重要なのは、 <tag_value name="bus_stop"/>の部分です。

このXMLファイルを使って、

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)\N07-11_14_GML>osm2pgrouting -f tsuzuki_bus_trial2.osm -c mapconfig_for_cars_rail_busstop.xml -d tsuzuki_bus -U postgres -h 192.168.0.23 -p 15432 -W password

(tsuzuki_bus_trial2.osm は、変更後のOSMファイル)

を実施し、QGISでDBの内容を表示してみました。

ちゃんとNodeが追加されているようです。

しかし、ダイクストラ計算ができるかどうかは、まだ分かりませんので、QGISの地物情報でNode番号を把握して、計算を試みてみました。

 

tsuzuki_bus=# SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id,source, target,length as cost, reverse_cost FROM ways',2, 7);
seq | node | edge | cost
-----+------+------+-----------------------
1 | 2 | 25 | 0.002503402202160114
2 | 3 | 1 | 0.003623692651717509
3 | 4 | 26 | 0.0073121202899935804
4 | 5 | 27 | 0.006205490305965455
5 | 6 | 28 | 0.0048274159495506515
6 | 7 | -1 | 0
(6 rows)

ちゃんと出力されているようです。

ようやく、目処がついてきました ―― ヘナヘナと座り込みそうです。

本当にしんどくて辛い夏季休暇でした。

2023,江端さんの技術メモ

GolangでOSMファイルから、<tag k="highway" v="bus_stop"/>が入っているnode情報と、その中にあるtag k="name"の情報を出して

と、ChatGPTに頼んだら、サクッと作ってくれました。

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Osm struct {
	XMLName xml.Name `xml:"osm"`
	Nodes   []Node   `xml:"node"`
}

type Node struct {
	XMLName xml.Name `xml:"node"`
	Lat     string   `xml:"lat,attr"`
	Lon     string   `xml:"lon,attr"`
	Tags    []Tag    `xml:"tag"`
}

type Tag struct {
	XMLName xml.Name `xml:"tag"`
	Key     string   `xml:"k,attr"`
	Value   string   `xml:"v,attr"`
}

func main() {
	// XMLファイルの読み込み
	xmlFile, err := os.Open("tsuzuki.osm")
	if err != nil {
		log.Fatal(err)
	}
	defer xmlFile.Close()

	// XMLデータの読み込み
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		log.Fatal(err)
	}

	var osm Osm

	// XMLデータのUnmarshal
	err = xml.Unmarshal(xmlData, &osm)
	if err != nil {
		log.Fatal(err)
	}

	// <tag k="highway" v="bus_stop"/> のノード情報を表示
	for _, node := range osm.Nodes {
		hasBusStopTag := false
		var busStopName string

		// ノード内のタグ情報を探索
		for _, tag := range node.Tags {
			if tag.Key == "highway" && tag.Value == "bus_stop" {
				hasBusStopTag = true
			}
			if tag.Key == "name" {
				busStopName = tag.Value
			}
		}

		if hasBusStopTag {
			fmt.Printf("Bus Stop Name: %s, Lat: %s, Lon: %s\n", busStopName, node.Lat, node.Lon)
			//fmt.Printf("%s, %s,%s\n", busStopName, node.Lat, node.Lon)
		}
	}
}

>go run bus_stop2.go
Bus Stop Name: 川和町, Lat: 35.5341695, Lon: 139.5461286
Bus Stop Name: 川和町, Lat: 35.5344793, Lon: 139.5458792
Bus Stop Name: 東名江田, Lat: 35.5628753, Lon: 139.5577658
Bus Stop Name: 石橋, Lat: 35.5209186, Lon: 139.5571699
Bus Stop Name: 桜通り, Lat: 35.5677990, Lon: 139.5446995
Bus Stop Name: 鶴蒔橋, Lat: 35.5496160, Lon: 139.5451910
Bus Stop Name: 鶴蒔橋, Lat: 35.5491291, Lon: 139.5461293
Bus Stop Name: 泉公園, Lat: 35.5480514, Lon: 139.5475269
Bus Stop Name: 市ヶ尾中学校前, Lat: 35.5468751, Lon: 139.5464900
Bus Stop Name: 市ヶ尾中学校前, Lat: 35.5468380, Lon: 139.5466080

2023,江端さんの技術メモ

https://josm.openstreetmap.de/wiki/Help/Action/JumpToPosition

ショートカットキー: Ctrl+J

または、ここをクリックすると、

このダイアログが出てくので、ここに名称または座標を入れる。