2020/07,江端さんの技術メモ

石膏ボード 600円 5+1 枚
4x2フォーム 3000円くらい

吸音ざい 910X910 6 = 4500 x 6 27000 → 18000円くらい

防音シート 5885円
https://item.rakuten.co.jp/pialiving/cz-12/?iasid=07rpp_10095___eh-kcng6x35-2p-d8c44078-682d-426b-96ad-33c9bf2dc05f

2020/07,江端さんの技術メモ

	m_conn->prepare(                    // HACK 1. 2文を1文に(PQExec仕様)、2. JOIN周り、 3. ORDER BYを消せないか?
		"find_shortest_path_by_dijkstra_calc",
		R"(
			INSERT INTO s_dijkstra_memoization (source, target, node, edge, length_m)
			
				SELECT
					$1, $2, d.node, d.edge, coalesce(ways.length_m, 0) AS length_m
				FROM
					pgr_dijkstra (
						'SELECT gid AS id, source, target, length_m AS cost from ways',
						start_vid:=$1::bigint, end_vid:=$2::bigint, directed:=false::boolean
					) as d LEFT JOIN ways ON ways.gid = d.edge
			
			WHERE NOT EXISTS (SELECT source, target FROM s_dijkstra_memoization WHERE source = $1 AND target = $2);
		)",
					//RETURNING node, edge, length_m;
		2
	);

のところで、問題が発生しているのは分かるのだけど、私にとっては上記な呪文であり、さっぱり分からない。

とりあえず、psql から地道に部分的に動かしてみて、問題点を探っている。

ca_sim=# SELECT gid, source, target, length_m AS cost from ways;

gid | source | target | cost
------+--------+--------+--------------------
1 | 55 | 23 | 121.17749638577058
2 | 844 | 1 | 710.1279290280786
3 | 4807 | 2 | 40.26044319993349
4 | 6296 | 3 | 251.21876036796243
5 | 22 | 4 | 2181.7785758382133
6 | 18 | 6 | 435.2439693722031
7 | 4304 | 6 | 950.7269653866767
8 | 6289 | 7 | 29.068747479235597

となるが、

ca_sim=# SELECT * FROM pgr_dijkstra(
'SELECT gid, source, target, length_m AS cost FROM ways',
2, 3
);
ERROR: Column 'id' not Found
CONTEXT: SQL function "pgr_dijkstra" statement 1

となる。pgr_dijkstraを実行する為には、パラメータの名前まで注意しなければなならないらしい。

ca_sim=# SELECT * FROM pgr_dijkstra(
'SELECT gid AS id, source, target, length_m AS cost FROM ways',
2, 3
);
seq | path_seq | node | edge | cost | agg_cost
-----+----------+------+------+--------------------+--------------------
1 | 1 | 2 | 342 | 224.26753559377073 | 0
2 | 2 | 229 | 8773 | 295.36268951709405 | 224.26753559377073
3 | 3 | 6359 | 8771 | 41.04204131422657 | 519.6302251108648
4 | 4 | 6357 | 344 | 136.12897946273213 | 560.6722664250914
5 | 5 | 231 | 8688 | 58.55503032553214 | 696.8012458878235
6 | 6 | 6294 | 8690 | 191.73693713817062 | 755.3562762133556
7 | 7 | 6296 | 4 | 251.21876036796243 | 947.0932133515262
8 | 8 | 3 | -1 | 0 | 1198.3119737194886
(8 rows)

くるしまぎれに、

start_vid:=$1::bigint, end_vid:=$2

の部分に、

1、2

を、実数でベタ書きしたら、エラーが取れて、シミュレーションが走りだした(原因不明)

しかし、

start_vid:=$1::bigint, end_vid:=$2 → $1, $2

では、

ERROR: function pgr_dijkstra(unknown, unknown, unknown, directed => boolean) is not unique
LINE 7: pgr_dijkstra(
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.

Error:ERROR: function pgr_dijkstra(unknown, unknown, unknown, directed => boolean) is not unique
LINE 7: pgr_dijkstra(
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.

となってしまう。


ブログを読んで頂いたからから、以下のアドバイスを頂いたので、その観点より挑戦。

上の箇所の$1や$2は、SQLインジェクションされないためのprepare文のプレースホルダーです。
ドキュメントの該当箇所は次のものです。
https://www.postgresql.org/docs/current/sql-prepare.html
$1と$2に該当するものをうしろから代入してあげれば動く(はず)と思います。
MySQLは、たしか「?」がプレースホルダで、SQLiteも「?」がプレースホルダ(https://docs.python.org/ja/3/library/sqlite3.html をみたら、合ってました)だったように覚えています。PostgreSQLは$+数字をつかうことになっています。

そこで、このページを印刷しながら、比較して、色々試してみた

                pgr_dijkstra(
                    (SELECT gid AS id, source, target, length_m AS cost from ways),
                    start_vid:=$1::bigint, end_vid:=$2::bigint, directed:=false::boolean
                ) as d LEFT JOIN ways ON ways.gid = d.edge

ERROR:  subquery must return only one column
LINE 8:       (SELECT gid AS id, source, target, length_m AS cost fr...
              ^

Error:ERROR:  subquery must return only one column
LINE 8:       (SELECT gid AS id, source, target, length_m AS cost fr...
            FROM
                pgr_dijkstra(
                    'SELECT gid AS id, source, target, length_m AS cost from ways',
                    (start_vid:=$1::bigint), (end_vid:=$2::bigint), directed:=false::boolean
                ) as d LEFT JOIN ways ON ways.gid = d.edge
ERROR:  syntax error at or near ":="
LINE 9:       (start_vid:=$1::bigint), (end_vid:=$2::bigint), direct...
                        ^

Error:ERROR:  syntax error at or near ":="
LINE 9:       (start_vid:=$1::bigint), (end_vid:=$2::bigint), direct...

すでに試してみたが、これもやってみた

                pgr_dijkstra(
                    'SELECT gid AS id, source, target, length_m AS cost from ways',
                    $1, $2, directed:=false::boolean
                ) as d LEFT JOIN ways ON ways.gid = d.edge
ERROR:  function pgr_dijkstra(unknown, unknown, unknown, directed => boolean) is not unique
LINE 7:      pgr_dijkstra(
             ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

Error:ERROR:  function pgr_dijkstra(unknown, unknown, unknown, directed => boolean) is not unique
LINE 7:      pgr_dijkstra(
             ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

なんかエラーが増えてきたようだ(unknownが3つになった)。

他の行と比較してみながら、start_vid と end_vid を消してみた(これが記載されていない別の行があったので)

            FROM
                pgr_dijkstra(
                    'SELECT gid AS id, source, target, length_m AS cost from ways',
                    $1::bigint, $2::bigint, directed:=false::boolean
                ) as d LEFT JOIN ways ON ways.gid = d.edge

これで動いた。

けど、理由はさっぱり分かりません。$1::bigint, $2::bigint がキャストの書式?

トライアンド&エラーでやろうとすると、こういう目にあう、という良い教訓として下さい。

2020/07,江端さんの技術メモ

(Step 1) アイコンをコピー → [ファイル]→[クリップボードからキャンパス作成]→

(Step 2) [レイヤー]→[輝度を透明度に変換]

(Step 3) [合成モード]→[カラー2値化]

(Step 4) [不透明度]→80%くらい

(Step 5) [不透明度保護]くりっく

(Step 6) 赤を指定して、2値ペンで塗りたくる

以上

http://www.kobore.net/diary_techno/?date=20170204

Keyword: SAI 赤 赤色

2020/07,江端さんの技術メモ

AWSから「AWS Free Tier limit alert」という脅迫・・ではなくて、警告メールが来て怖い思いをしています。

EC2を全部止めているのに、なぜ?と思っていたのですが、どうやら、スナップショットを置いてあると、それだけで課金されることが分かりました。

で、まあ、消してもいいかな、と思って消そうと思ったら「スマップショット削除中のエラー」が発生して消すことができませんでした。

この場合、連携しているAMI(私は未だに、このAMIという奴が良くわからんのですが)の登録解除をすると消せました。

2020/07,江端さんの忘備録,江端さんの技術メモ

先月、AWSから、こんな請求書が来て青冷めました。

練習用のEC2を立ち上げておいただけで、5000円以上持っていかれました。

そもそも仕事で使うAWSの練習用のAWSで、5000円以上も自腹を切らわされるのは、なんとも業腹です ―― しかし、会社の飲み会で、まずい飯とつまらん会話で8000円支払わされること思えば、圧倒的に安いとは思いますが。

で、面倒なので、練習をしていない時は、EC2を落すようにしました(下記参照)

今月の支払いは、以下のようになりました。

まあ、200円弱くらいならいいかな、と思いました。

勉強や練習でEC2を使っている人は、こまめにEC2を落しましょう。

2020/07,江端さんの技術メモ

docker start -a ebata_db_1

docker container exec -it ebata_db_1 bash

で、SQLファイル(create_tables.sql)が、/db_data に入っている場合

psql -f /db_data/create_tables.sql(フルパス) -U postgres(ユーザ名) -d ca_sim(テーブル名)

で、実行可能。

フルパスにしないと、/db_dataの中から実行しても、"そんなファイルないよ"と(平気で)言われるので注意のこと

2020/06,江端さんの技術メモ

内容コマンド例
サービスの起動postgres -D /usr/local/var/postgres
デフォルトのテーブルに接続psql -d postgres
直接データベースに接続psql -d テーブル名
データベース一覧の表示\l
データベースへの接続\c データベース名
テーブルの作成create table テーブル名 (
counter int primary key,
present_station int,
departure_station int,
present_time time
);
データの書き込み
INSERT INTO テーブル名(counter, present_station, departure_station, present_time) VALUES(1, 2, 3, '12:23:34');
データの上書きUPDATE テーブル名 set present_time = '23:34:45' WHERE counter = 1;
テーブル一覧の表示\dt;
テーブル構造の表示d テーブル名;
テーブル内のデータを一覧select * from テーブル名;
指定したカラムの内容を小さい順に表示select * from テーブル名 order by カラム;
指定したカラムの内容を大きい順に表示select * from テーブル名 order by カラム desc;
表示数指定select * from テーブル名 limit 数;
表示の開始位置指定select * from テーブル名 offset 数;
カラム内の任意の文字を表示select distinct カラム名 from テーブル名;
カラム内の合計値select sum(カラム名) from テーブル名;
カラム内の最大値select max(カラム名) from テーブル名;
カラム内の最小値select min(カラム名) from テーブル名;
カラム内の平均値select avg(カラム名) from テーブル名;
データの更新update テーブル名 set 更新内容;
全データの削除delete from テーブル名;
テーブル本体の削除drop table テーブル名;
データの削除delete from テーブル名 where 条件;
テーブルのオーナーの変更alter table テーブル名 owner to オーナー名;
文字数select length(カラム名) from テーブル名;
文字列連結select concat(文字列, 文字列, ...) from テーブル名;
カラムの追加alter table テーブル名 add カラム名 データ型;
カラムの削除alter table テーブル名 drop カラム名;
カラム名の変更alter table テーブル名 rename カラム名 to 新カラム名;
カラムのデータ型を変更するalter table テーブル名 alter カラム名 type データ型;
インデックス追加create index インデックス名 on テーブル名(カラム名);
インデックス削除drop index インデックス名;
viewの作成create view ビュー名 as viewに指定するコマンド;
view一覧の確認\dv;
viewの使用方法select * from ビュー名;
viewの削除drop view ビュー名;
SQL文を外部ファイルに書いて実行する時に使う\i ファイル名

2020/06,江端さんの技術メモ

osm_railway_linestringの場所がさっぱり分からないので、とりあえずOpenMapTilesがあやしいので、「OpenMapTiles Map Server を使ってサイトに地図を埋め込む」を、そのまま真似てみる

https://qiita.com/kmdsbng/items/fe9239e96afe29eb893c をそのまま実行

タイルデータをダウンロードする
https://openmaptiles.com/downloads/

Downloads > Asia > Japan > Tokyo から 東京エリアをダウンロードする

OpenMapTiles Map Serverを起動する
タイルデータを置いたディレクトリで以下の docker コマンドを実行

docker run --rm -it -v $(pwd):/data -p 8080:80 klokantech/openmaptiles-server

C:\Users\ebata\Desktop\hirohakama_sim>docker run --rm -it -v $(pwd):/data -p 8080:80 klokantech/openmaptiles-server
Unable to find image 'klokantech/openmaptiles-server:latest' locally
latest: Pulling from klokantech/openmaptiles-server
c5e155d5a1d1: Pull complete 221d80d00ae9: Pull complete 4250b3117dca: Pull complete 3b7ca19181b2: Pull complete 425d7b2a5bcc: Pull complete 69df12c70287: Pull complete ea2f5386a42d: Pull complete d421d2b3c5eb: Pull complete da30b29849e7: Pull complete 737fbec6f196: Pull complete e4745ce6fed7: Pull complete 28b22a8cf232: Pull complete Digest: sha256:1a6fec0108fa78cf778d385205b4b0197b8c599fb91f9e08a1f114af9df75584
Status: Downloaded newer image for klokantech/openmaptiles-server:latest
docker: Error response from daemon: create $(pwd): "$(pwd)" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.

あ、Windows10のコマンドプロンプトでは、$(pwd)が解釈できないみたいなので、

C:\Users\ebata\Desktop\hirohakama_sim>docker run --rm -it -v ~/data -p 8080:80 klokantech/openmaptiles-server としてみたら

C:\Users\ebata\Desktop\hirohakama_sim>docker run --rm -it -v ~/data -p 8080:80 klokantech/openmaptiles-server
/usr/lib/python2.7/dist-packages/supervisor/options.py:298: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
2020-06-29 15:43:52,652 CRIT Supervisor running as root (no user in config file)
2020-06-29 15:43:52,652 INFO Included extra file "/etc/supervisor/conf.d/openmaptiles.conf" during parsing
2020-06-29 15:43:52,655 INFO Creating socket tcp://localhost:8081
2020-06-29 15:43:52,656 INFO Closing socket tcp://localhost:8081
2020-06-29 15:43:52,663 INFO RPC interface 'supervisor' initialized
2020-06-29 15:43:52,663 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2020-06-29 15:43:52,664 INFO supervisord started with pid 1
2020-06-29 15:43:53,669 INFO spawned: 'wizard' with pid 8
2020-06-29 15:43:53,674 INFO spawned: 'xvfb' with pid 9
Starting OpenMapTiles Map Server (action: run)
2020-06-29 15:43:54,196 INFO success: wizard entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2020-06-29 15:43:54,196 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Config file not found!
Starting installation…
Installation wizard started at http://:::80/
List of available downloads ready.

で、このまま、で停止した状態。

ブラウザで http://localhost:8080/ にアクセス

"CONTINUE"を押下

"CONTINUE"を押下

"SAVE & RUN THE SERVER"を押下

Click here to get the download keyを押下

上記のKeyをコピペして、"START DOWNLOAD"を押すと

てな画面がでてくる。

"OPEN MAP SERVER"を押下した後、http://localhost:8080/をすると以下の画面が出てくる。

疲れた。今日はここまで。

2020/06,江端さんの技術メモ

------- PostgresのpostGISに、鉄道情報も入れる --------

omsのデータには、鉄道情報入っていません(と思う osm2pgrouting にtrainを取り出すオプションがなかったので) ―― ので、国土地理院からダウンロードする

https://nlftp.mlit.go.jp/ksj/index.html から 鉄道時系列(ライン)(ポイント)を探して、ここからファイル(N02-08.zip)をPCにダウンロードして解凍する。中身はKS-META-N02-08.xmlと、N02-08.xml が入っている。

ところが、xmlファイルは、postgresにインポートできないのでshpファイルに変換する必要がある。

で、https://nlftp.mlit.go.jp/ksj/jpgis/jpgis_tool.html にある、「国土数値情報XML-シェープ変換ツール」をダウンロードしてインストールする。私の場合、64Bit版OSに対応した変換ツールはこちらからダウンロードできます。(ksjtool_64_v1.8.zip 約18MB)をダウンロードした。

で、先程のN02-08.xmlを変換すると、N02-08_EB02.dbf、N02-08_EB02.shp、N02-08_EB02.shx、N02-08_EB03.dbf、N02-08_EB03.shp、N02-08_EB03.shx が生成される。

(どういう訳か、shp2pgsqlがなくて、apt-get install shp2pgsql にも失敗するので)、QGIS3を使って、PostgresのDBにつっこむ。

N02-08_EB02 を選んで、OKを押下して、さらにN02-08_EB03を選んで、OKを押下する(2つインポートする)

以下を見ると、N02-08_EB02は路線情報が、N02-08_EB03は駅の情報が入っているみたい

ただ、selectしようとすると、変なエラーがでるので、テーブルの名前を変更した方がいい(が、今日は疲れたので、ここまで)

selectでは、テーブルの名前は小文字で、"-"も使えないようである。QGISから、以下のように変更した。

------- ところが鉄道の路線情報が、geometry型で、何が何やらさっぱり分からん --------

例えば、新百合ヶ丘駅から五月台駅までのルートは、以下のような情報が入っている

hirohakama_sim2=# select geom from n02_08_eb02 where id = 6328;

0105000020E610000001000000010200000012000000E97DE36BCF6F6140CDCCCCCCCCCC4140E4141DC9E56F614006D847A7AECC41400D8E9257E76F61400DFD135CACCC4140BEBC00FBE86F6140A27A6
B60ABCC4140404D2D5BEB6F61401422E010AACC414045F0BF95EC6F6140A99F3715A9CC4140923F1878EE6F614062F3716DA8CC41400708E6E8F16F61401B47ACC5A7CC4140ABECBB22F86F6140F870C97
1A7CC414055F65D11FC6F61401B47ACC5A7CC414014ED2AA4FC6F61403F1D8F19A8CC414072A774B0FE6F6140A99F3715A9CC414047ACC5A70070614038F8C264AACC414075C8CD700370614031D3F6AFA
CCC4140130A117008706140B1E1E995B2CC4140C3B645990D70614006F52D73BACC414043C5387F13706140E23B31EBC5CC4140003ACC9717706140A2D11DC4CECC4140
(1 row)

これが訳が分からんのだが、QGISではちゃんと曲線も含めて表示される。

地物情報としては、両端の位置情報は入っているが、カーブの情報とかどうやて表現しているんだ?

なんか、色々探しているうちに、こんなのが出てきた。(参考 http://www.jurigis.me/2015/02/07/select-in-postgis/)

hirohakama_sim2=# select ST_Astext(geom) from n02_08_eb02 where id = 6328;
MULTILINESTRING((139.49407 35.6,139.4968 35.59908,139.49699 35.59901,139.49719 35.59898,139.49748 35.59894,139.49763 35.59891,139.49786 35.59889,139.49828 35.598
87,139.49904 35.59886,139.49952 35.59887,139.49959 35.59888,139.49984 35.59891,139.50008 35.59895,139.50042 35.59902,139.50103 35.5992,139.50166 35.59944,139.5023
8 35.59979,139.50288 35.60006))
(1 row)

エクセルで、この座標を並べて、QGIS3と比較してみた。

中間状態が、座標で表示されていることが分かった。

hirohakama_sim2=# select ST_Length(geom) from n02_08_eb02 where id = 6328;
st_length
0.009214722968728321
(1 row)

 

これだと、デカルトの長さになるらしい。これをメートルに変換するには、以下の様にする。

hirohakama_sim2=# select ST_Length(Geography(ST_Transform(geom,4326))) from n02_08_eb02 where id = 6328;
st_length
852.3697682752311
(1 row)

で、次は駅の情報。駅は、n02_08_eb03(×n02_08_eb02)に入っている。

五月台駅は、こんな感じ。

hirohakama_sim2=# select * from n02_08_eb03 where id = 3106;
id | geom | rac | int | lin | opc | stn
3106 | 0105000020E610000001000000010200000002000000E97DE36BCF6F6140CDCCCCCCCCCC4140A857CA32C46F614030478FDFDBCC4140 | 1
2 | 4 | 多摩線 | 小田急電鉄 | 五月台
(1 row)

で、駅の端点は、こんな感じで出てくる。

hirohakama_sim2=# select ST_Astext(geom) from n02_08_eb03 where id = 3106;
st_astext
MULTILINESTRING((139.49407 35.6,139.4927 35.60046))

hirohakama_sim2=# select ST_Length(Geography(ST_Transform(geom,4326))) from n02_08_eb03 where id = 3106;
st_length
134.22648323273413
(1 row)

ふーん、五月台駅って、134メートルなんだ

結論 geometryのフォーマットはさっぱり分からんが、関数使って取り出せるなら、それで良しとしよう。

課題 鉄道のgeometryを使った最短経路問題を解くのメソッドってあるのかな? pgr_dijkstra()とか・・・

http://kenpg.seesaa.net/article/385517945.html を、後で試してみること