2023,江端さんの技術メモ

自分用のメモ。PC落すと、忘れてしまうので残します。

目的

バスルートをDBで格納する。

やってきたこと

新規に、データベースを作る。postgisとpgroutingの対応できるようにしておく。

yoko_db=# create database route_db;
CREATE DATABASE
yoko_db=# \c route_db
psql (13.4, server 12.5 (Debian 12.5-1.pgdg100+1))
You are now connected to database "route_db" as user "postgres".
route_db=# CREATE EXTENSION postgis;
CREATE EXTENSION
route_db=# create extension pgrouting;
CREATE EXTENSION

色々分かったこと

geometry型のデータには指定方法がある(らしい)。

http://cse.naro.affrc.go.jp/yellow/pgisman/3.0.0/using_postgis_dbmanagement.html

POINT: SRID指定なしでの2次元ポイントジオグラフィのテーブル生成は次の通りです。デフォルトは4326 WGS84経度緯度となります。

CREATE TABLE ptgeogwgs(gid serial PRIMARY KEY, geog geography(POINT) );
POINT: NAD83経度緯度での2次元ポイントジオグラフィのテーブル生成は次の通りです。

CREATE TABLE ptgeognad83(gid serial PRIMARY KEY, geog geography(POINT,4269) );
Z値を持ち、明示的にSRIDを指定したポイントのテーブル生成は次の通りです。

CREATE TABLE ptzgeogwgs84(gid serial PRIMARY KEY, geog geography(POINTZ,4326) );
LINESTRING

CREATE TABLE lgeog(gid serial PRIMARY KEY, geog geography(LINESTRING) );
POLYGON

-- ポリゴン NAD 1927経度緯度
CREATE TABLE lgeognad27(gid serial PRIMARY KEY, geog geography(POLYGON,4267) );
MULTIPOINT

MULTILINESTRING

MULTIPOLYGON

GEOMETRYCOLLECTION

ジオグラフィ型のフィールドはgeography_columnsシステムビューに登録されます。

"geography_columns"ビューをチェックして、テーブルが一覧にあるか見て下さい。

CREATE TABLEの文法でジオグラフィカラムを持つテーブルを新規に生成できます。

CREATE TABLE global_points (
    id SERIAL PRIMARY KEY,
    name VARCHAR(64),
    location GEOGRAPHY(POINT,4326)
  );

で、ちょっと、試しに、ちょっと以下のgeomデータを入れてみたのですが、興味深い結果が得られました。

route_db=# create table route_geom(geog geography(LINESTRING));
CREATE TABLE
route_db=#
route_db=# insert into route_geom(geog) VALUES('0105000020E610000001000000010200000012000000E97DE36BCF6F6140CDCCCCCCCCCC4140E4141DC9E56F614006D847A7AECC41400D8E9257E76F61400DFD135CACCC4140BEBC00FBE86F6140A27A6B60ABCC4140404D2D5BEB6F61401422E010AACC414045F0BF95EC6F6140A99F3715A9CC4140923F1878EE6F614062F3716DA8CC41400708E6E8F16F61401B47ACC5A7CC4140ABECBB22F86F6140F870C971A7CC414055F65D11FC6F61401B47ACC5A7CC414014ED2AA4FC6F61403F1D8F19A8CC414072A774B0FE6F6140A99F3715A9CC414047ACC5A70070614038F8C264AACC414075C8CD700370614031D3F6AFACCC4140130A117008706140B1E1E995B2CC4140C3B645990D70614006F52D73BACC414043C5387F13706140E23B31EBC5CC4140003ACC9717706140A2D11DC4CECC4140');
ERROR:  Geometry type (MultiLineString) does not match column type (LineString)

とエラーが出てきます。LineStringではなくて、MultiLineStringにしなさい と注意されました。

insertの段階でパースされているとは思いませんでした。

という訳で、次のようにやってみました。

route_db=# drop table route_geom;
DROP TABLE
route_db=# create table route_geom(geog geography(MULTILINESTRING));
CREATE TABLE
route_db=# insert into route_geom(geog) VALUES('0105000020E610000001000000010200000012000000E97DE36BCF6F6140CDCCCCCCCCCC4140E4141DC9E56F614006D847A7AECC41400D8E9257E76F61400DFD135CACCC4140BEBC00FBE86F6140A27A6B60ABCC4140404D2D5BEB6F61401422E010AACC414045F0BF95EC6F6140A99F3715A9CC4140923F1878EE6F614062F3716DA8CC41400708E6E8F16F61401B47ACC5A7CC4140ABECBB22F86F6140F870C971A7CC414055F65D11FC6F61401B47ACC5A7CC414014ED2AA4FC6F61403F1D8F19A8CC414072A774B0FE6F6140A99F3715A9CC414047ACC5A70070614038F8C264AACC414075C8CD700370614031D3F6AFACCC4140130A117008706140B1E1E995B2CC4140C3B645990D70614006F52D73BACC414043C5387F13706140E23B31EBC5CC4140003ACC9717706140A2D11DC4CECC4140');
INSERT 0 1

と、今度はinsertできました。

postGISで接触する線を抽出する方法を探す

のgeomのデータを入力したのですが、座標がおかしい、と、こちらも入力を拒否されました。

2023,江端さんの技術メモ

OpenStreetMapとOpenTripPlannerで経路検索してバスに乗れと言ってもらった

オープンソースの経路探索「OpenTripPlanner」をUbuntuで動かして岡山県で経路探索をする

上記の「岡山県」を丸ごと試させて頂いています。

違いがあるのは、私は、>wsl -d Ubuntu-20.04  on Windows10を使っているところと、

「Windows11にWSL2+Ubuntu20.04をインストールする」を試してみて、Golangをインストールしてみた件

otp-1.3.0-shaded.jar → 1.4.0のバージョンアップ版を使っているところです。

中々 Grizzly server running.  の表示が出てこないので、1.4.0を使ったということと、あと、

wget "http://www.shimoden.net/busmada/opendata/GTFS-JP.zip" -O shimodenbus.gtfs.zip

だけにしたところです。全部入れたら、エラーになるので、どれかのファイルに問題があるものと思います。

後は、明日以降にします。


横浜市交通局 バスの情報に適用します

https://ckan.odpt.org/dataset?q=%E6%A8%AA%E6%B5%9C&tags=%E3%83%90%E3%82%B9-bus&sort=score+desc%2C+metadata_modified+desc

から、データをダウンロードします。

これを、C:\Users\ebata\yokohama\yoko_db などを作っておき、

>wsl -d Ubuntu-20.04

を立ち上げて、osmをpbfに変換する

osmconvert yokohama.osm --out-pbf >yokohama.pbf

を作ります。

osmconvertの使い方

 

C:\Users\ebata\yokohama\yoko_dbに移動して、

ebata@DESKTOP-P6KREM0:/mnt/c/Users/ebata/yokohama/yoko_db$ java -Xmx5G -jar otp-1.4.0-shaded.jar --build ./ --inMemory

を実施すると、サーバが立ち上がります。

ebata@DESKTOP-P6KREM0:/mnt/c/Users/ebata/yokohama/otp$ java -Xmx5G -jar otp-1.4.0-shaded.jar --build ./ --inMemory
14:24:02.863 INFO (OTPServer.java:39) Wiring up and configuring server.
14:24:02.868 INFO (GraphBuilder.java:165) Wiring up and configuring graph builder task.
14:24:02.870 INFO (GraphBuilder.java:171) Searching for graph builder input files in .
(中略)
14:24:13.837 INFO (NetworkListener.java:750) Started listener bound to [0.0.0.0:8080]
14:24:13.849 INFO (NetworkListener.java:750) Started listener bound to [0.0.0.0:8081]
14:24:13.851 INFO (HttpServer.java:300) [HttpServer] Started.
14:24:13.851 INFO (GrizzlyServer.java:153) Grizzly server running.

http://localhost:8080/

をすると、以下のような画面が出てきます。

この使い方は後回しにして、とりあえず以下を確認します。

http://localhost:8080/otp/routers/default/index/agencies/1

http://localhost:8080/otp/routers/default/index/agencies/1/3000020141003/routes

使い方は、まだ良く分かりませんし、エラーも出ていますが、今日はここまで。

 

2023,江端さんの技術メモ

osm.pbfファイルを、osmファイルに変換する方法

■pbfからpbfを切り出す

osmconvert chugoku-latest.osm.pbf -b=133.455201,34.274923,134.298740,35.284564 --complete-ways -o=okayama.pbf

は、chugoku-latest.osm.pbf から、133.455201,34.274923,134.298740,35.284564の領域で、Pbfファイルとして切り取れ。

■osmをpbfに変換する

osmconvert yokohama.osm --out-pbf >yokohama.pbf

 

2023,江端さんの忘備録

WSL2が凄い ―― と、今、実感しています。

WSL2 is awesome -- and now I realize it.

WSL2は、Windows BoxでLinuxを使えるようにしたものです。

WSL2 is a Windows Box that allows you to use Linux on your Windows Box.

私、これ、長い間、WindowsをホストOSとする仮想マシン(ゲストOS)だと思ってきました ―― まあ、間違っていないのですが。

I have long thought that this is a virtual machine (guest OS) with Windows as the host OS -- well, I am not wrong.

で、ゲストOSは、かならずホストOSの性能に「足を引っ張られる」と決めつけていました ―― これも、一般的には間違っていません。

So, I assumed that the guest OS would always be "dragged down" by the performance of the host OS -- which is also generally not wrong.

-----

しかし、昨年、制作を依頼した担当者から『WSL2を使えば、Go言語のパフォーマンスが向上する』と連絡があったんです。

But last year, the person in charge of commissioning the production contacted me and said, 'If you use WSL2, you can improve the performance of the Go language.

疑いながらも、実際に使ってみると、驚くような性能アップを確認しました。

Despite our doubts, I actually used the system and confirmed the surprising improvement in performance.

―― これ、ホストとゲストの関係じゃないぞ

"This is not a host/guest relationship"

と、ようやく気がつきました。

I finally realized that.

で調べてみたら、やはり、その通りでした。

I looked into it, and I was right.

-----

まあ、これだけでも凄いと思うのですが、Windowsの環境のディレクトリ構造をそのままで、"sudo apt install"等が使える、という、幸せに浸っております。

Well, I think this alone is great, but I am happy that I can use "sudo apt install" etc. without changing the directory structure of the Windows environment.

Linuxでの開発の記事の内容を、Windowsでそのままできて、コーディングはWindowsのvscodeそのままで問題なし ―― 天国かよ。

I can do the content of the article on development on Linux as it is on Windows, and coding is no problem with the Windows vscode intact -- is this heaven?

"sudo apt"も"wget"もできて、javaもlinux版がサクッとインストールできました。

I was able to do "sudo apt" and "wget" and install the linux version of java.

OpenTripPlanner のトライアル

WordやPowerPointから離れることができず、しかし、Linuxでの開発も必要という研究者にとって、これは最高の環境です。

For researchers who can't get away from Word or PowerPoint, but still need to develop on Linux, this is the perfect environment.

-----

で、まあ、何が言いたいかといいますと、

So, well, what I'm trying to say is,

ITエンジニアが『ゲスト』『ホスト』『幸せ』『天国』『最高』という言葉を使っている時は、IT開発環境の話をしているのであって

When IT engineers use the words 'guest', 'host', 'happy', 'heaven', and 'best', they are talking about the IT development environment.

―― 下世話ことをしゃべっている訳ではない

"They are not talking about juicy story"

ということを知っておいて頂きたいのです。

I want you to know that.

2023,江端さんの技術メモ

いつも通り、2台目のパソコンにdockerを使ったDBを作成して、psqlを使って、DBアクセスを試みましたが、

postgres=# \c yoko_db
psql (13.4, server 12.5 (Debian 12.5-1.pgdg100+1))
You are now connected to database "yoko_db" as user "postgres".
yoko_db=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | configuration | table | postgres
public | pointsofinterest | table | postgres
public | spatial_ref_sys | table | postgres
public | ways | table | postgres
public | ways_vertices_pgr | table | postgres
(5 rows)

yoko_db=# select * from ways;
ERROR: character with byte sequence 0xe9 0xb7 0x97 in encoding "UTF8" has no equivalent in encoding "SJIS"

という見たことのないエラーが出てきました。

ローカルからアクセスしたところ問題はないようですし、As:SQL Mk-2を使ってリモートからも読めました。

A5:SQL Mk-2 トライアル(解決)

psqlでログインして、\c (テーブル) (ここの場合は、# \c yoko_db)とした後、

yoko_db=# set client_encoding to utf8;
SET
yoko_db=# \encoding
UTF8

とすることで、エラーが出てこなくなりました。

以上

 

2023,江端さんの技術メモ

type testJSON struct {
	Id      string `json:"@id"`
	Type    string `json:"@type"`
	Date    string `json:"dc:date"`
	Context string `json:"@context"`
	Title   string `json:"dc:title"`
	Note    string `json:"odpt:note"`
	Regions struct {
		Type        string `json:"type"`
		Coordinates []interface{}
	} `json:"ug:region"`
	Owl              string `json:"owl:sameAS"`
	Pattern          string `json:"odpt:pattern"`
	Busroute         string `json:"odpt:busroute"`
	Operator         string `json:"odpt:operator"`
	Direction        string `json:"odpt:direction"`
	BusstopPoleOrder []struct {
		Note        string `json:"odpt:note"`
		Index       int    `json:"odpt:index"`
		BusstopPole string `json:"odpt:busstopPole"`
	} `json:"odpt:busstopPoleOrder"`
}

の、

Coordinates []interface{}

の部分をsrting型→分割 → float64型に戻して処理しようしているのですが、

for _, e := range data {
		fmt.Println(e) // 全情報表情
		coors := e.Regions.Coordinates
		fmt.Println("len_mm", len(coors))
		for _, coor := range coors {
			fmt.Println(coor)
			str_coor := coor.(string)
			arr := strings.Split(str_coor, " ")
			lng := arr[0]
			lat := arr[1]
			fmt.Println(lng, lat)
		}
	}

[139.6249873 35.4648941]
panic: interface conversion: interface {} is []interface {}, not string

goroutine 1 [running]:
main.main()
C:/Users/ebata/yoko_bus_route/route_json.go:92 +0x694
exit status 2

というエラーが出てきて停止します ―― キャストできない。

多分対応方法はあると思うのですが、調べるのが面倒なので、C/C++で定番の、あの美しくない方法 "sprintf"を使いました

for _, coor := range coors {

			//	str_coor := coor.(string)   
			str_coor := fmt.Sprintf("%v", coor) // この段階では" [139.575019, 35.439622]"という文字列 

			arr := strings.Split(str_coor, " ") // スペース" " で arr[0], arr[1]という文字列に分離する

			str_lng := strings.Replace(arr[0], "[", "", -1) // arr[0] ("[139.575019")から、"["を消す
			str_lat := strings.Replace(arr[1], "]", "", -1) // arr[1] ("35.439622]")から、"]"を消す

			lng64, _ := strconv.ParseFloat(str_lng, 64) // float64に強制的に型変換する
			lat64, _ := strconv.ParseFloat(str_lat, 64) // float64に強制的に型変換する

			fmt.Println("lng:", lng64)
			fmt.Println("lat:", lat64)

		}

動けばいいんですよ、動けば。

2023,江端さんの技術メモ

https://ckan.odpt.org/dataset/b_busroute-yokohamamunicipal


■動かなくて悩んでいたコード

// xml_parse.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type testXML struct {
	Date     string `json:"dc:date"`
	Busroute string `json:"odpt:BusroutePattern"`
}

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusroutePattern?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
	if err != nil {
		log.Fatal(err)
	}

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	//fmt.Println(body)

	var data testXML

	err = json.Unmarshal(body, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)

	}

	fmt.Println(data)

}

出力結果

> go run xml_parse.go
Unmarshal
2023/05/01 18:05:31 json: cannot unmarshal array into Go value of type main.testXML
exit status 1

悩むこと1時間、("type testXML"スキーマを色々いじったりしていた)

『そういえば、このjsonのデータは、違う路線データも入っているはずだよな』
→ 『ということは、複数のデータが入っていることになるよな』
→ 『 For文で取らなければ不味くないか?』

で、ググってみたら、どうやらループになるように仕込んでおかないといけないらしいことが分かりました(XMLの先頭の情報が取れるだけだと思っていた)

■動いたコード

// xml_parse.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type testXML struct {
	Date     string `json:"dc:date"`
	Busroute string `json:"odpt:BusroutePattern"`
}

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusroutePattern?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
	if err != nil {
		log.Fatal(err)
	}

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
		x
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	//fmt.Println(body)

	var data []testXML

	err = json.Unmarshal(body, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)

	}

	for _, e := range data {
		fmt.Println(e.Date)
	}

}

go run xml_parse.go
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00"当たり"だったようです。


バス路線情報のJSONをブラウザで読みとってみました。


ここから、酷いハマり方をします(10時間くらい)。

上記のルートの位置情報の表示のコーディングがどうしても分からない。

以下は、上記のJSONを簡略化したものです(route.json)。

[
	{
		"dc:date":"2023-04-03T00:00:00+09:00",
		"dc:title":"007",
		"ug:region":
				{
					"type":"Triangle",
					"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]
				},
		"owl:sameAs":"test1"
	},
	{
		"dc:date":"2023-04-03T00:00:00+09:00",
		"dc:title":"008",
		"ug:region":
				{
					"type":"LineString",
					"coordinates":[[139.667765,35.416456],[139.668006,35.416708],[139.668116,35.416788],[139.668276,35.416841]]
				},
		"owl:sameAs":"test2"
	}
]

問題は、ネストの中に入っていて、タグの名前のついていない、

"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]

の部分です。

10時間くらいは戦ったかなぁ ―― もう疲れ果てて、質問サイトに投稿する為に、(上記の)JSONファイルと、このパーサープログラムを成形していました。

で、そのプログラムをテストランさせたら ―― これが動いてしまったのです。

// route_json.go

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type testXML struct {
	Date    string `json:"dc:date"`
	Title   string `json:"dc:title"`
	Note    string `json:"odpt:note"`
	Owl     string `json:"owl:sameAS"`
	Regions struct {
		Type        string `json:"type"`
		Coordinates []interface{}
		//Coordinates []struct {
		//	Longitude float64 `json:"longitudes>longitude"`
		//	Latitude  float64 `json:"latitudes>latitude "`
		//} `json:"coodtinates"`
	} `json:"ug:region"`
}

func main() {
	file, err := ioutil.ReadFile("route.json")
	//file, err := ioutil.ReadFile("odpt_BusroutePattern.json")

	if err != nil {
		// エラー処理
	}

	var data []testXML

	err = json.Unmarshal(file, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)
	}

	fmt.Println(string(file))

	// ループによる取得
	for _, e := range data {

		fmt.Println(e) //
		mm := e.Regions.Coordinates

		fmt.Println(len(mm))

		for _, m := range mm {
			fmt.Println(m)
		}
	}
}

実行結果は以下の通りです。

> go run route_json.go
[
{
"dc:date":"2023-04-03T00:00:00+09:00",
"dc:title":"007",
"ug:region":
{
"type":"Triangle",
"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]
},
"owl:sameAs":"test1"
},
{
"dc:date":"2023-04-03T00:00:00+09:00",
"dc:title":"008",
"ug:region":
{
"type":"LineString",
"coordinates":[[139.667765,35.416456],[139.668006,35.416708],[139.668116,35.416788],[139.668276,35.416841]]
},
"owl:sameAs":"test2"
}
]

{2023-04-03T00:00:00+09:00 007 test1 {Triangle [[139.6249873 35.4648941] [139.6237514 35.4648862] [139.623672 35.4650137]]}}
3
[139.6249873 35.4648941]
[139.6237514 35.4648862]
[139.623672 35.4650137]
{2023-04-03T00:00:00+09:00 008 test2 {LineString [[139.667765 35.416456] [139.668006 35.416708] [139.668116 35.416788] [139.668276 35.416841]]}}
4
[139.667765 35.416456]
[139.668006 35.416708]
[139.668116 35.416788]
[139.668276 35.416841]

ずっとエラーが出ていたんですが、突然表示されるようになりました。

        Coordinates []interface{}

JSONタグが付いていない問題は、これで解消できるようです。

で、(簡易版ではなく)実体のJSONファイルを使ってみても動きました。

こういうことがあるから、本当にコーディングというのは厄介なんですよね。


パースしたデータを表示してみました。

通路が(多分)順番に表示されることが確認できました。


だいたいこれで完成です。

// route_json.go
// 横浜市交通局 バス路線情報 / Bus route information of Transportation Bureau, City of Yokohama
// https://ckan.odpt.org/dataset/b_busroute-yokohamamunicipal

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type testJSON struct {
	Id      string `json:"@id"`
	Type    string `json:"@type"`
	Date    string `json:"dc:date"`
	Context string `json:"@context"`
	Title   string `json:"dc:title"`
	Note    string `json:"odpt:note"`
	Regions struct {
		Type        string `json:"type"`
		Coordinates []interface{}
	} `json:"ug:region"`
	Owl              string `json:"owl:sameAS"`
	Pattern          string `json:"odpt:pattern"`
	Busroute         string `json:"odpt:busroute"`
	Operator         string `json:"odpt:operator"`
	Direction        string `json:"odpt:direction"`
	BusstopPoleOrder []struct {
		Note        string `json:"odpt:note"`
		Index       int    `json:"odpt:index"`
		BusstopPole string `json:"odpt:busstopPole"`
	} `json:"odpt:busstopPoleOrder"`
}

func main() {

	// JSONファイルから読み取る場合
	//file, err := ioutil.ReadFile("route.json")
	file, err := ioutil.ReadFile("odpt_BusroutePattern.json")
	if err != nil {
		// エラー処理
	}

	/*
		// Webアクセスで取得する場合

		client := &http.Client{}
		req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusroutePattern?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
		if err != nil {
			log.Fatal(err)
		}

		resp, err := client.Do(req)
		if err != nil {
			log.Fatal(err)
		}
		defer resp.Body.Close()
		if err != nil {
			log.Fatal(err)
		}

		file, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Fatal(err)
		}
	*/

	var data []testJSON

	err = json.Unmarshal(file, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)
	}

	//fmt.Println(string(file))

	// ループによる取得
	for _, e := range data {

		fmt.Println(e) // 全情報表情
		coors := e.Regions.Coordinates

		fmt.Println("len_mm", len(coors))

		for _, coor := range coors {
			fmt.Println(coor)
		}

		stops := e.BusstopPoleOrder

		fmt.Println("len_ss", len(stops))

		for _, stop := range stops {
			fmt.Println(stop.Note)
			fmt.Println(stop.Index)
			fmt.Println(stop.BusstopPole)
		}

	}
}

2023,江端さんの忘備録

私は、「良い部下」だった、という記憶がありません。

I don't remember that I was a "good subordinate".

そのような部下であっても、『この上司、リーダーについていこう』と決めた人もいました。

Even so, I thought to decide, 'I will follow this boss and leader.

それらの人々には共通した性格がありました。

They had a common character.

―― リーダーシップがない

"No leadership"

この一言に尽きます。

This is the one word.

-----

『リーダーシップがないリーダー』は、頼りがなく、いつも心配をしなければなりませんでした。

'Leaders without leadership' were unreliable and I always had to worry.

私よりも知見がなく、そのことに対して大した拘泥(こだわり)もプライドもないようでした。

They were less knowledgeable than I was and did not seem to have any great obsession or pride in the matter.

ですから、私は、自分のことだけでなく、チーム全体の動きも気にかけばけばなりませんでした。

So I had to be concerned not only about myself but also about the team as a whole.

しかし、そのようなリーダーは、威圧的ではなく、私の話もちゃんと聞いてくれ、必要に応じて方針を変更してくれる人でした。

However, such a leader was not overbearing, but would listen to me and change policy as needed.

私の失敗を責め立てるでもなく、黙って一緒にお客さんの所に謝りに行ってくれて、その後、その事をすっかり忘れてしまうように振る舞ってくれました。

They did not blame me for my mistake, but quietly went with me to apologize to the customer and then acted as if they would forget all about it.

そのような、ボンヤリとしたマネージメントの元、私を含めチームメンバは、自律的に動き、そしてメンバ間のコミュニケーションも円滑でした。

Under such a vague management, the team members, including myself, moved autonomously, and communication among them was smooth.

一番の要因は、私が、その人のことを「個人的に好きである」ということでした。

The most important factor was that I had a "personal liking" for the person.

-----

ただ、このようなリーダーは、社会的というか、会社的には評価されにくいようです。

However, such leaders seem to be less valued socially, or company-wise.

そして、省みるに、私がそのようなリーダーに憧れても、いざ自分がリーダーになると、時間や成果に対して厳密な人間になってしまいました。

And in reflection, even though I aspired to be such a leader, when I became one, I became a person strict about time and results.

立ち位置や保身で、人間というのは、簡単に姿を変えてしまいます。

People are easily disfigured by their standing and self-preservation.

そして現実として、パワハラを発動させるリーダーが、チームの成果を上げるのは事実です。

And the reality is that leaders who initiate power harassment improve the results of their teams.

ただ、"パワハラ"に対して、"退職"という形の報復で、リーダーの権限を失墜させることができます ―― 特に若い世代は。

However, retaliation for "power harassment" in the form of "resignation" can be used to disqualify a leader's authority, especially by the younger generation.

こうして考えると、(どの世代であっても)若者の離職率の高さというのは、ある種、会社のモラルを維持する機能として働いていると言えるかもしれません。

In this way, it may be said that the high turnover rate of young people (in any era) is, in a sense, a function of maintaining company morale.

-----

総じて、『リーダーシップがないリーダー』になることは、これはこれで、相当に難しいのです。

In general, to be a 'leader without leadership' is a lot more difficult.

なぜなら『リーダーシップがないリーダー』を目指した瞬間に、そのようなリーダーにはなれなくなるからです。

Because the moment you aim to be a 'leader without leadership,' you will not be such a leader.

「のび太」という国家理念

 

2011,江端さんの忘備録

『「リーダーシップを張れる政治家」が望まれている』と言われ続けていますが、私は、このフレーズ、かなり嫌いです。

65年程前に、

○カリスマとリーダシップを発揮し、
○戦後の復興を見事に成しとげ、
○欧州で突出した経済力を発揮し、
○公共事業を次々と打ち出して、失業率をかつてないレベルにまで低下させ、
○軍事力の増強を図り続け、米国や周辺の大国を威嚇し、国際発言力を爆発的に向上させた、優れた政治家がいました。

アドルフ・ヒトラー

という人物です。

-----

尖閣諸島問題や、北方領土問題、竹島問題、米軍基地問題で、

『我が国政府が、弱腰外交をしている』

と言われていますが、そんなこと「あったり前」じゃないですか。
馬鹿じゃなかろうか。

我が国は、

「国権の発動たる戦争と、武力による威嚇又は武力の行使は、国際紛争を解決する手段としては、永久にこれを放棄する」

と、国家の最高規範である憲法で規定しているのです。

ピストル持っている相手に、「俺は正しい」と素手で立ちむかえば、撃ち殺されるに決っています。

『弱腰外交』が嫌なら、憲法第9条を撤廃(×改正)し、軍隊(×自衛隊)を設立し、核武装をするような政策をぶち上げて、世論を、その方向に誘導しなければなりません。

-----

リーダシップを持つ政治家が、そのまま、再軍備をする政治家になる、というのは短絡すぎており、論理破綻していることは認めます。

しかし、「リーダシップを持つ政治家」というのは、恐しいリスクを持っているということくらいは、当然に認識しておくべきです。

-----

私は、

○平和憲法を維持し、
○弱腰外交を支持し、
○のらりくらりとその場対応を続ける政治家を支援します。

別に、かっこよくて、マッチョな国家にならなくても、良いと思うし、そういうスマートな政府も期待していません。

我が国は、ドラえもんの「のび太」の生き方に学べば良いのです。

2023,江端さんの技術メモ

https://ckan.odpt.org/dataset/b_busstop-yokohamamunicipal/resource/da256719-0c39-48a7-a1f2-20354e18d529

// stop_json.go
// 横浜市交通局 バス停情報 / Bus stop information of Transportation Bureau, City of Yokohama
// https://ckan.odpt.org/dataset/b_busstop-yokohamamunicipal

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type stopJSON struct {
	Id        string `json:"@id"`
	Type      string `json:"@type"`
	Lng_Title struct {
		En      string `json:"en"`
		Ja      string `json:"ja"`
		Ko      string `json:"ko"`
		Zh      string `json:"zh"`
		Ja_Hrkt string `json:"ja-Hrkt"`
	} `json:"title"`
	Date              string        `json:"dc:date"`
	Lat               float64       `json:"geo:lat"`
	Long              float64       `json:"geo:long"`
	Context           string        `json:"@context"`
	Title             string        `json:"dc:title"`
	Kana              string        `json:"odpt:kana"`
	SameAS            string        `json:"owl:sameAS"`
	Operator          []interface{} `json:"odpt:operator"`
	BusroutePattern   []interface{} `json:"odpt:busroutePattern"`
	BusstopPoleNumber string        `json:"odpt:busstopPoleNumber"`
	// BusstopPoleTimetable
}

func main() {

	// JSONファイルから読み取る場合
	//file, err := ioutil.ReadFile("route.json")
	//file, err := ioutil.ReadFile("odpt_BusroutePattern.json")
	file, err := ioutil.ReadFile("odpt_BusstopPole.json")
	if err != nil {
		// エラー処理
	}

	/*
		// Webアクセスで取得する場合

		client := &http.Client{}
		req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusstopPole?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
		if err != nil {
			log.Fatal(err)
		}

		resp, err := client.Do(req)
		if err != nil {
			log.Fatal(err)
		}
		defer resp.Body.Close()
		if err != nil {
			log.Fatal(err)
		}

		file, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Fatal(err)
		}
	*/

	var data []stopJSON

	err = json.Unmarshal(file, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)
	}

	//fmt.Println(string(file))

	// ループによる取得
	for _, e := range data {

		fmt.Println(e) // 全情報表情

		stops := e.BusroutePattern
		fmt.Println("len_stop", len(stops))

		for _, stop := range stops {
			fmt.Println(stop)
		}

	}
}