2017,江端さんの忘備録

以前、私は嫁さんに、高村薫さんの「神の火」を読んで感激し、その本を嫁さんに強く勧めました。

About ten years ago, I was moved to the book titled "God Fire." The author is Takamura Kaoru-san, and I strongly recommend the book to my wife.

嫁さんは、「最後までガマンして読んだけど、最後まで何の感慨もなかった」と言われて、かなりショックを受けました。

She said, "I accepted your recommendation without complaining, and I could not have any emotion about this book," I was shocked to hear her comment.

―― 自分が良いと思うものが、他人が良いと思うとは限らない

"Things that I think are good are not always good for others."

これは、ティーンエイジャが最初に学ぶ通過儀礼の一つですが、それでも、私は、

That is a typical "rite of passage" for teenagers; however, I thought

―― 自分が「熱狂的に良い」と思うものであれば、それは客観的に「良い」ものも含んでいて、自分の想いの1/100くらいは伝わるんじゃないないかな

"Things that I think are good fanatically may include some objective good things. So, the hundredth part of my illusion will get the point across to others."

という仮説があったのですが、これが「バラバラ」に壊れた瞬間でした。

This hypothesis of mine was broken all to pieces at the moment,

-----

今、中学3年生の次女には、課題図書として、サイモン・シンさんの「宇宙創成」が出ているようです。

Now, my junior daughter has a homework assignment on a "book report" for "space creation," the author of which is Mr.Simon Lehna Singh.

宇宙の創成を解明していく科学者たちの闘いを描いた、科学ドキュメントの本です。

It is a book of scientific documents that depicts the battle of scientists who clarify the creation of the universe.

私は、サイモン・シンさんの本は、全て読んでいます。

I read all the books of Mr.Simon Lehna Singh.

家族旅行でバリにいったとき、「暗号解読」に夢中になってしまい、そのバリの旅程を想い出せないほどです。

When I went to Bali on my family trip, I became infatuated with the book, whose title was "Decryption," and I could not remember Bali's itinerary.

ですから、この「宇宙創成」の素晴しさも、当然に理解しています。

So, of course, I understand the wonderfulness of this "space creation" as well.

この課題図書を出した<次女>の教諭とは、多分、良い友人になれると思っています。

I think I can probably become a good friend with the teacher of "junior daughter," who submitted this assignment book.

-----

ですが、

However, I am quite doubtful

―― この教諭と私が「熱狂的に良い」と思うこの本への想いの1/100でも、次女にも伝わるか

"whether 1/100 of this book's value will also be transmitted to the second daughter, even if both this teacher and I feel that this book is 'enthusiastic good'"

というのは、かなり疑わしいと思っています。

「サイモン・シンさんの本は、人を選ぶ」と思うのです。

I think that the books of Mr.Simon Lehna Singh will choose a person.

未分類

GStreamerにおけるkeep-listeningの機能は、主にSRTプロトコルの特性に基づいて設計されています。SRTはストリーミング中のネットワーク障害や接続の一時的な切断に対して高い耐障害性を持ち、再接続をプロトコルレベルでサポートしています。このため、GStreamerのSRTプラグインにはkeep-listeningオプションが実装されており、再接続処理が標準で可能となっています。

一方で、RTSPプロトコルは再接続に対する標準的なメカニズムを持っておらず、ストリーミング接続が切断された場合にはアプリケーション側で再接続処理を実装する必要があります。この理由は以下の通りです:

  1. プロトコルの設計思想の違い
    SRTはリアルタイムのビデオ伝送を想定し、途切れた接続を回復するための仕組み(例:パケットの再送や接続の再試行)が組み込まれています。一方、RTSPは主にコントロールプロトコルとして設計されており、接続の維持や再接続は仕様の範囲外です。
  2. GStreamerプラグインの実装方針
    GStreamerのRTSPプラグイン(rtspsrc)は、RTSPプロトコルの標準に忠実であり、アプリケーション側で自由に再接続ロジックを実装できるよう設計されています。このため、keep-listeningのようなオプションはRTSPプラグインに含まれていません。
  3. 運用環境での要件
    RTSPストリームの中断や切断が発生する状況は、ネットワーク環境やストリーミングサーバーの設定に依存するため、再接続の実装はユーザーごとの要件に基づいてカスタマイズされることが一般的です。

これらの理由から、RTSPでkeep-listeningを実現するには、アプリケーション側でエラー検知と再接続処理を実装する必要があります。これは、RTSPの特性に起因する設計上の制約であり、プロトコルやGStreamerプラグインの動作仕様によるものです。

------

今回の質問は、
『GStreamerでSRTはKeep-listening が使えるのですが、RTSPではkeep-listeningが使えません。この理由を上司に説明できる文章として作成して下さい』
としました。

我ながら、色々なChatGPTの姑息な使い方ができるようになってきたものだと、自分に感心しています。

2024,江端さんの技術メモ

エクスプローラで、ファイルをコピーする場合、同じファイル名の場合には時刻が新しい場合のみ上書きしたいですがどうすれば良いですか
ChatGPT
ChatGPT
Windowsエクスプローラでファイルをコピーする際、同じファイル名の場合は時刻が新しい場合のみ上書きするという機能は標準では提供されていません。しかし、以下の方法でこの操作を実現できます。

方法1: コマンドプロンプトでrobocopyを使用
Windowsにはrobocopyという強力なコマンドラインツールがあり、これを使用してファイルのコピーを行うと、指定した条件に基づいてファイルを上書きできます。

以下の手順で行います。

コマンドプロンプトを管理者権限で開く

以下のrobocopyコマンドを実行

cmd
コードをコピーする
robocopy "コピー元フォルダのパス" "コピー先フォルダのパス" /XO
ここで、/XOオプションは古いファイルを除外します。これにより、コピー元フォルダのファイルがコピー先フォルダのファイルより新しい場合にのみ上書きされます。


コピー元フォルダがC:\source、コピー先フォルダがD:\destinationの場合、次のように入力します。

cmd
コードをコピーする
robocopy "C:\source" "D:\destination" /XO


cmd.exeを管理者モードで立ち上げ

C:\WINDOWS\system32>robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z

C:\WINDOWS\system32>robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z

C:\WINDOWS\system32>robocopy "g:home\ebata\tomioka3B\src" "\\192.168.0.9\share\tomioka3B\src" /XO /E /Z
C:\WINDOWS\system32>robocopy "g:home\ebata\hakata" "\\192.168.0.9\share\hakata" /XO /E /Z

======

robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z

 

robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z

 

robocopy "g:home\ebata\tomioka3B\src" "\\192.168.0.9\share\tomioka3B\src" /XO /E /Z

 

robocopy "g:home\ebata\hakata" "\\192.168.0.9\share\hakata" /XO /E /Z

 

echo

======

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー
-------------------------------------------------------------------------------
  開始: 2024年6月23日 10:23:39
   コピー元 : G:\home\ebata\tomioka3B\src\
     コピー先 : \\192.168.0.9\share\tomioka3B\src\
    ファイル: *.*
  オプション: *.* /S /E /DCOPY:DA /COPY:DAT /Z /XO /R:1000000 /W:30
------------------------------------------------------------------------------
                           4    G:\home\ebata\tomioka3B\src\
                           2    G:\home\ebata\tomioka3B\src\.vscode\
                          20    G:\home\ebata\tomioka3B\src\Agent\
                           4    G:\home\ebata\tomioka3B\src\Agent\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent\old\
                          14    G:\home\ebata\tomioka3B\src\Agent - kese09161446\
                           2    G:\home\ebata\tomioka3B\src\Agent - kese09161446\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent - kese09161446\old\
                          14    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\
                           2    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\old\
                           1    G:\home\ebata\tomioka3B\src\agent_db\
                          14    G:\home\ebata\tomioka3B\src\CartはAgentに併合\
                           1    G:\home\ebata\tomioka3B\src\CartはAgentに併合\ldarp\
                           2    G:\home\ebata\tomioka3B\src\CartはAgentに併合\old\
                           1    G:\home\ebata\tomioka3B\src\inc\
                           5    G:\home\ebata\tomioka3B\src\Join\
                           1    G:\home\ebata\tomioka3B\src\Join\ldarp\
                           3    G:\home\ebata\tomioka3B\src\ldarp\
                           4    G:\home\ebata\tomioka3B\src\old\
                          22    G:\home\ebata\tomioka3B\src\old\doc\
                         253    G:\home\ebata\tomioka3B\src\others\
                           1    G:\home\ebata\tomioka3B\src\others\.vscode\
                           8    G:\home\ebata\tomioka3B\src\others\chart\
                         105    G:\home\ebata\tomioka3B\src\others\csvファイルのバックアップ\
                           1    G:\home\ebata\tomioka3B\src\others\main49\
                           1    G:\home\ebata\tomioka3B\src\others\main50\
                           8    G:\home\ebata\tomioka3B\src\PrumeMobile\
                          10    G:\home\ebata\tomioka3B\src\PrumeMobile\chart\
                           9    G:\home\ebata\tomioka3B\src\PrumeMobile\chart2\
                           8    G:\home\ebata\tomioka3B\src\PrumeMobile\old\
                          12    G:\home\ebata\tomioka3B\src\PrumeMobile\static\
                          25    G:\home\ebata\tomioka3B\src\trip_cluster\
100%      新しいファイル                     105        #robocopy#
100%            新しい              7540        main.go
                          12    G:\home\ebata\tomioka3B\src\trip_cluster\bic\
100%      新しいファイル                     858        plot_cluster7.gnuplot
                           4    G:\home\ebata\tomioka3B\src\trip_cluster\bus\
100%      新しいファイル                     357        plot_cluster2.gnuplot
100%      新しいファイル                     858        plot_cluster2.gnuplot~
                          56    G:\home\ebata\tomioka3B\src\trip_cluster\data(最初に手動で作成)\
                           9    G:\home\ebata\tomioka3B\src\trip_cluster\walk\
100%      新しいファイル                     775        plot_cluster7.gnuplot
100%      新しいファイル                     858        plot_cluster7.gnuplot~
                        2001    G:\home\ebata\tomioka3B\src\trip_normalization\
100%            新しい              4466        main.go
100%      新しいファイル                    3678        main.go~
                          73    G:\home\ebata\tomioka3B\src\trip_test\
                          75    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018\
100%            新しい             23276        main.go
100%      新しいファイル                     124        robocopy
                           0    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018\main copy.go(5\
                          75    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018_harugakkai\
                           6    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018_harugakkai\others\
                           4    G:\home\ebata\tomioka3B\src\trip_tomioka2018\
                           4    G:\home\ebata\tomioka3B\src\trip_tomioka2018\others\
100%      新しいファイル                     587        dummy.txt
100%      新しいファイル                      58        dummy.txt~
100%            新しい              3272        main.go
        新しいディレクトリ       4      G:\home\ebata\tomioka3B\src\trip_tomioka2018_harugakkai\
100%      新しいファイル                  162161        agent_od_test.csv
100%      新しいファイル                    9022        libdarp.go
100%      新しいファイル                   15470        main.go
100%      新しいファイル                   18255        tools.go
        新しいディレクトリ       4      G:\home\ebata\tomioka3B\src\trip_tomioka2018_harugakkai\others\
100%      新しいファイル                  162161        agent_od_test.csv
100%      新しいファイル                     587        dummy.txt
100%      新しいファイル                      58        dummy.txt~
100%      新しいファイル                    3272        main.go
------------------------------------------------------------------------------
                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:        47         2        45         0         0         0
     ファイル:      2890        22      2868         0         0         0
      バイト:   35.39 m   408.0 k   34.99 m         0         0         0
       時刻:   0:00:02   0:00:01                       0:00:00   0:00:01
       速度:              278161 バイト/秒
       速度:              15.916 MB/分
   終了: 2024年6月23日 10:23:42

 

未分類

Amazon Primeで「深夜食堂」を流しながらコーディングしています。

「深夜食堂」について調べてみたら、原作本については世界中で翻訳されているみたいですが、ドラマのリメイクも、中国、台湾、韓国でされていて、放映されているようです。

舞台などにもなっているそうです ―― で、情報のウラは取れなかったのですが「フランス」でリメイクだか、舞台だかが、あったとかなかったとか。

「フランス版深夜食堂」。うん、なんか、凄く見たい。

「ドイツ版深夜食堂」「ロシア版深夜食堂」はイメージできる。

北欧もイメージできる。

西欧であれば、スペイン版とかイタリア版とかも見てみたい。

イスラム圏の深夜食堂 ―― アルコール抜きバージョンも、可能なら見てみたいです。

未分類

select * from ways where name LIKE '%Dummy Railway Line%'; で選ばれたnode とwayを全部削除するにはどうしたら良いですか

ways テーブルにおける name 列の内容が '%Dummy Railway Line%' に一致する way と、それに関連する node を削除するには、以下の手順を実行します。ways テーブルと ways_vertices_pgr テーブルのリレーションを考慮した方法です。


手順

1. name 列が空か確認

name 列の値がすべて NULL または予期しない値かもしれません。以下のクエリで name 列の値を確認します。

SELECT DISTINCT name FROM ways WHERE name IS NOT NULL;

 


2. 削除対象の gid を確認

対象となる gid を取得します。もし name が NULL である場合には以下のように NULL 対応を追加してください。

SELECT gid FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 

もし上記クエリに結果がない場合、代わりに以下を確認します。

  • tag_idrule 列など他の列に対象の特徴があるか確認する。
  • 該当の値を直接確認する(例: IS NOT NULL を使う)。

3. 関連する node を特定

sourcetarget のノードが ways_vertices_pgr テーブルに存在する場合、それを削除します。

以下のクエリで関連する sourcetarget を確認します。

SELECT source, target FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 

これにより、削除対象のノード sourcetarget を特定できます。


4. 関連する ways_vertices_pgr の削除

取得した source および target に基づき、ways_vertices_pgr テーブルからノードを削除します。

DELETE FROM ways_vertices_pgr WHERE id IN ( SELECT source FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL UNION SELECT target FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL );

 


5. ways テーブルの削除

最後に ways テーブルから該当する行を削除します。

DELETE FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 


注意事項

  • バックアップを作成: データ削除は不可逆操作です。削除前にバックアップを必ず取得してください。
  • インデックスを活用: クエリ性能を向上させるため、適切なインデックスがあるか確認します(ways_pkey など)。
  • 依存関係: 外部キー制約があるため、削除の順序(ノード懼ウェイ)を守る必要があります。

これにより、name LIKE '%Dummy Railway Line%' に該当するデータを完全に削除できます。

この方法だと関連のあるnodeも消してしまうような気がします。wayだけ消せれば良いのです。

関連のある node を削除せずに、ways テーブルだけから特定の way を削除する場合、以下の手順で進めることができます。


方法

1. 削除対象の gid を確認

name に基づいて削除対象の waygid を確認します。

SELECT gid FROM ways WHERE name LIKE '%Dummy Railway Line%';

 


2. ways テーブルから対象の行を削除

特定した gid を使って ways テーブルから削除します。関連ノードは削除されません。

DELETE FROM ways WHERE name LIKE '%Dummy Railway Line%';

 


外部キー制約について

ways テーブルには外部キー制約が設定されていますが、ways テーブル自体からの削除では関連ノード(sourcetarget)を削除する必要はありません。外部キー制約は、通常、ノードが削除される際に ways のデータが参照整合性を保つようにするためのものです。

この方法であれば、ways_vertices_pgr テーブルやその他の関連ノードはそのまま維持されます。


確認

削除後にデータが正しく削除されたかを確認するには、以下を実行してください。

SELECT * FROM ways WHERE name LIKE '%Dummy Railway Line%';

 

結果が空であれば、対象の way が正しく削除されています。

コスト付き(hakata_ex_cost_db)とコストなし(hakata_no_dummy_db)の地図を2種類作れました。

2024,江端さんの忘備録

『ダイクストラ計算を行った結果を、(1)'Dummy Rail Line'が連続するリスト、(2)(1)'Dummy Bus Line'が連続するリスト、(3)その他のリストに分割するプログラムに改造しつつ、(1)(2)(3)はその順番通りにリストを作成し、(1)(2)(3)が、2度以上出てくる場合は、別のリストとして取得するには、どうコーディングすれば良いのか?』(読まなくていいです)

'How should I code to create lists (1) 'Dummy Rail Line' in succession, (2) 'Dummy Bus Line' in succession, and (3) other lists while modifying the program to divide the results of the Dijkstra calculation into these three lists, and to obtain a separate list if (1), (2), or (3) appears more than once? (You don't need to read this.)

上記のコーディング方法について、今朝の深夜までもんもんと考え続けていました。

I kept thinking about the coding method above until late this morning.

ところが、朝方、夢の中で、この方法が、天からの啓示のごとく突如閃きました。

However, this method suddenly flashed into my mind in the morning like a revelation from heaven.

『ChatGPTにプログラム作成してもらおう』

“Let's have ChatGPT create a program for us.”

-----

先程、ChatGPTが作ってくれたプログラムの稼動を確認しました。

I just checked to see if the program ChatGPT created is working.

ようやくホッとしていますが(今から少し寝ます)、同時に『問題を考えなくなっていく自分の頭が、どんどん悪くなっている』を痛感しています。

I'm finally feeling relieved (I'm going to sleep for a bit now), but at the same time, I'm acutely aware that 'my brain, which is no longer thinking about problems, is getting worse and worse.'

これは、これで、かなり恐しいことだと思っています。

I think this is quite a frightening thing.

-----

すでに、この業界では、この問題の弊害が出ているそうです ―― かなり広範囲に、しかも相当に深刻な弊害です。

I hear that the harmful effects of this problem are already being seen in the industry - quite severe and widespread.

ソフト外注に発注した人が、発注したプログラムの内容について開発者に質問しているうちに、

While the person who ordered the software was asking the developer questions about the content of the program they ordered, it turned out that -

- そのプログラム開発者が、プログラマとして働き始めて、1年のキャリアもないこと

- the program developer had only been working as a programmer for less than a year

- そのプログラム開発者が、"サブルーチン"とは何かを知らなかったこと(注: サブルーチンという概念を知らなかった)

- the program developer did not know what a “subroutine” was (Note: He did not know the concept of a subroutine)

ことが、分かったそうです。

今、世界中で、そういう開発者たちが作成するプログラムが、大量生産されていると考えて間違いないでしょう。

It might be possible to assume that such developers mass-produce programs worldwide.

これも、これで、かなり恐しいことだと思っています。

I think this is also quite a frightening thing.

何が言いたいのかというと、「こういうプログラムを組める『私』には、市場価値があるのか、それとも、ないのか」、です。

未分類

hakata_ex_cost_db=# \e 
 start_seq | end_seq | line_name
 -----------+---------+-----------------------------------

1 | 6 | Dummy Railway Line JR鹿児島本線
7 | 7 | Dummy Railway Line JR篠栗線
8 | 10 | Dummy Railway Line 地下鉄航空線
12 | 12 | Dummy Bus Line 天神エリア限定バス
という結果が出てきました。start_seq と end_seq が同じ番号になっているところがありますが、これは、どのように解釈すれば良いでしょうか


SELECT seq, node, edge, cost, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target,length_m as cost FROM ways',66619, 92554, false);

WITH path AS ( SELECT seq, node, edge, cost, agg_cost FROM pgr_dijkstra( 'SELECT gid as id, source, target, cost, reverse_cost FROM ways', 66619, 92554 ) ), full_path AS ( SELECT path.seq, path.node, path.edge, path.cost, path.agg_cost, ways.length_m AS length_m, ways.name AS line_name FROM path LEFT JOIN ways ON path.edge = ways.gid ) SELECT seq, node, edge, cost, agg_cost, length_m, line_name FROM full_path ORDER BY seq;

----- ダイクストラ66619, 92554 の結果の一覧表示

WITH path AS (
    SELECT 
        seq, 
        edge, 
        b.name AS line_name,
        b.the_geom
    FROM 
        pgr_dijkstra(
            'SELECT gid as id, source, target, cost, reverse_cost FROM ways',
            66619, 92554
        ) a
    INNER JOIN 
        ways b 
    ON 
        a.edge = b.gid
    ORDER BY seq
)
SELECT 
    MIN(seq) AS start_seq,
    MAX(seq) AS end_seq,
    line_name
FROM 
    path
WHERE 
    line_name LIKE '%Dummy Railway Line%'
    OR line_name LIKE '%Dummy Bus Line%'
GROUP BY 
    line_name
ORDER BY 
    start_seq;

以下のSQL文で、"Dummy Rail Line""Dummy Bus Line" に該当する start_seqend_seq を取得できます。


SQL文

WITH path AS (
    SELECT 
        seq, 
        edge, 
        b.name AS line_name
    FROM 
        pgr_dijkstra(
            'SELECT gid as id, source, target, cost, reverse_cost FROM ways',
            66619, 92554
        ) a
    INNER JOIN 
        ways b 
    ON 
        a.edge = b.gid
    ORDER BY seq
)
SELECT 
    MIN(seq) AS start_seq,
    MAX(seq) AS end_seq,
    CASE 
        WHEN line_name LIKE '%Dummy Railway Line%' THEN 'Dummy Rail Line'
        WHEN line_name LIKE '%Dummy Bus Line%' THEN 'Dummy Bus Line'
    END AS line_type
FROM 
    path
WHERE 
    line_name LIKE '%Dummy Railway Line%'
    OR line_name LIKE '%Dummy Bus Line%'
GROUP BY 
    CASE 
        WHEN line_name LIKE '%Dummy Railway Line%' THEN 'Dummy Rail Line'
        WHEN line_name LIKE '%Dummy Bus Line%' THEN 'Dummy Bus Line'
    END
ORDER BY 
    start_seq;

 

SQL文のポイント

  1. WITH句で経路情報を取得:
    • pgr_dijkstra の結果に ways.name を結合して、全経路のエッジ情報を準備します。
  2. CASE文で分類:
    • line_name に基づき、Dummy Rail LineDummy Bus Line の2種類に分類します。
    • この処理により、元の路線名が詳細でも、2つのカテゴリに整理されます。
  3. MINMAX で開始と終了を取得:
    • 経路順序 (seq) の最小値 (start_seq) と最大値 (end_seq) を取得します。
  4. グループ化:
    • CASE文で分類された路線タイプごとにグループ化 (GROUP BY) します。
  5. ソート順序:
    • 結果は start_seq の順に並びます。

結果例

以下のような結果が得られます:

start_seq end_seq line_type
1 10 Dummy Rail Line
12 15 Dummy Bus Line

注意事項

  • 必要に応じて、WHERE 条件や LIKE 演算子を調整してください。
  • 出力をさらに簡潔にしたい場合や、追加情報が必要な場合はお知らせください。適切に対応します。

 

2024,江端さんの技術メモ

江端がずっとメンテナンスしているgetDijkstraPath関数は、costを変更することによって、ダイクストラ計算を引き曲げているので、距離が正確に出せない。

そこで、agg_costを使わずに、agg_length_mというものを作って、強制的に距離を作り出すようにコードを変更した。

 

func getDijkstraPath(dbMap *sql.DB, locInfoStart, locInfoGoal LocInfo) ([]LocInfo, float64) {

	var path []LocInfo // 経路 (返り値の一つ目)
	var totalDistanceKm float64

	// 例外処理 locInfoStart.source == locInfoGoal.source の場合
	if locInfoStart.Source == locInfoGoal.Source {
		source := locInfoStart.Source

		// SQLクエリの作成
		query := fmt.Sprintf(`
		SELECT x1, y1
		FROM ways
		WHERE source = %d;
	`, source)

		// SQLクエリの実行
		var x1, y1 float64
		err := dbMap.QueryRow(query).Scan(&x1, &y1)
		if err != nil {
			fmt.Println("tools.go line 204 error occures")
			//log.Fatal(err)  // ここで止めたらリターンしなくなる
		}

		var loc LocInfo
		loc.Source = source
		loc.Lon = x1
		loc.Lat = y1

		path = append(path, loc)

		totalDistanceKm = 0.0
		return path, totalDistanceKm
	}

	// こちらは、cost, reverse_cost を使っている
	query := `
	SELECT seq, source, target, x1, y1, x2, y2, agg_cost, length_m
	FROM pgr_dijkstra(
		'SELECT gid as id, source, target, cost, reverse_cost FROM ways', 
		$1::bigint, 
		$2::bigint, 
		directed:=false
	) a 
	INNER JOIN ways b ON (a.edge = b.gid) 
	ORDER BY seq
	`

	rowsDijkstra, errDijkstra := dbMap.Query(query, locInfoStart.Source, locInfoGoal.Source)
	if errDijkstra != nil {
		log.Fatal(errDijkstra)
		os.Exit(1)
	}
	defer rowsDijkstra.Close()

	var agg_cost float64
	var length_m float64
	agg_length_m := 0.0

	var loc LocInfo
	var x1, y1, x2, y2 float64
	var seq int
	var target int
	var source int

	isFirstCheck := true
	isSourceCheck := true

	count := 0

	for rowsDijkstra.Next() {
		// まずnodeを読む
		if err := rowsDijkstra.Scan(&seq, &source, &target, &x1, &y1, &x2, &y2, &agg_cost, &length_m); err != nil {
			fmt.Println(err)
		}

		agg_length_m += length_m
		// fmt.Println("length_m", length_m, "agg_length_m", agg_length_m)

		// 最初の1回だけチェックのために入る これについては、https://wp.kobore.net/江端さんの技術メモ/post-7668/を参照のこと
		// もし rowsDijkstra.Scanで最初のsource値を読みとり、locInfoStart.Source の値と同じであれば、x1,y1をベースとして、異なる値であれば、x2,y2をベースとする

		if isFirstCheck {
			if source == locInfoStart.Source {
				isSourceCheck = true // x1, y1をベースとする処理になる
			} else {
				isSourceCheck = false // x2,y2をベースとする処理になる
			}
			isFirstCheck = false // 最初の1回をチェックすることで、2回目はこのループには入らなくなる
		}

		//var loc LocInfo

		if isSourceCheck { // x1, y1をベースとする処理
			loc.Source = source
			loc.Lon = x1
			loc.Lat = y1
		} else { // x2,y2をベースとする処理
			loc.Source = target
			loc.Lon = x2
			loc.Lat = y2
		}
		path = append(path, loc)

		count++
	}

	// ラストノードだけは手入力 (ここは引っくり返す) (今、ここの部分は無視されている(いいのかな?))
	if isSourceCheck { // x1, y1をベースとする処理
		loc.Source = target
		loc.Lon = x2
		loc.Lat = y2
	} else { // x2,y2をベースとする処理
		loc.Source = source
		loc.Lon = x1
		loc.Lat = y1
	}

	// なんかprg_dijkstraが変な値を返す場合があるので、その対応(ロジカルではないが、パッチ的に対応)
	if loc.Source == locInfoGoal.Source {
		path = append(path, loc)
	}

	fmt.Println("count", count)

	if count == 0 { // 1行のみの場合、ヌルになるという問題に対応するため、
		loc.Source = locInfoGoal.Source
		loc.Lon = locInfoGoal.Lon
		loc.Lat = locInfoGoal.Lat

		// 入力値の指定
		source := locInfoStart.Source
		target := locInfoGoal.Source

		// SQLクエリの作成
		query := fmt.Sprintf(`
		SELECT length_m, x1, y1, x2, y2
		FROM ways
		WHERE source = %d AND target = %d;
	`, source, target)

		// SQLクエリの実行
		var length float64
		var x1, y1, x2, y2 float64
		err := dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
		if err != nil {
			log.Println("First attempt failed. Retrying with swapped source and target.")
			// 入れ替えたsourceとtargetの値でクエリを再実行
			query = fmt.Sprintf(`
			SELECT length_m, x1, y1, x2, y2
			FROM ways
			WHERE source = %d AND target = %d;
		`, target, source)
			err = dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
			if err != nil {
				//log.Fatal(err)  // 諦める。とりあえず、エラーを返す
				return nil, 0.0
			}
		}

		// 結果の出力
		fmt.Printf("length_m: %f\n", length)
		fmt.Printf("source: %d\n", source)
		fmt.Printf("target: %d\n", target)
		fmt.Printf("x1: %f\n", x1)
		fmt.Printf("y1: %f\n", y1)
		fmt.Printf("x2: %f\n", x2)
		fmt.Printf("y2: %f\n", y2)

		if source == locInfoGoal.Source {
			loc.Lon = x1
			loc.Lat = y1
		} else {
			loc.Lon = x2
			loc.Lat = y2
		}

		agg_cost = length

		fmt.Println("loc", loc)

		path = append(path, loc) // 354
	} // if count == 0

	//totalDistanceKm = agg_cost / 1000.0
	totalDistanceKm = agg_length_m / 1000.0
	return path, totalDistanceKm
}

2024,江端さんの忘備録

昨夜から、長女が実家に帰省しています。

My eldest daughter has stayed at my parents' house since last night.

で、先日の結婚式の私のスピーチについて、レビューを貰いました。

So, I got a review of my speech at the wedding the other day.

「結婚とは不幸になること」でいいんです。

結婚式の二次会で、以下のようなフレーズが出てきたそうです。

At the after-party for their wedding, the following phrases were said.

―― やっぱり新婦の父親って"おかしい"よね

After all, the bride's father is “strange,” isn't he?

この話を聞いて、私はおもわずガッツポーズを取りました。

I couldn't help but pump a fist when I heard this story.

話を簡単に纒めますと、彼らの結婚式の二次会において、

To put it simply, at the after-party for their wedding, there was a conversation that went something like

「一体、どこの世界に、世間で最もお目出たいとわれる結婚式というイベントで『地獄』という言葉を使用する奴がいるか?」

 “Where in the world would someone use the word ‘hell’ at an event considered the most auspicious of all weddings?"

という会話がなされた、ということです。

私は、スピーチというものは『人の心に傷跡を付けてナンボ』と思っていますので、まさに"狙い通り"と、喜んでいる訳です。

I think a speech is only as good as its impact on the audience, so I was glad it went exactly as I had planned.

「新婦の父」などという、出席必須だけど存在感が希薄である人物の話が、結婚式の二次会で出てくること自体が、『大成果』と言えます。

The fact that a story about a character who is required to attend but has a shallow profile, such as the “bride's father,” is mentioned at the wedding reception can be said to be a “great achievement.”

-----

まあ、このような『人の心に傷跡を付けてナンボ』のスピーチは、こちらにもありますように、江端家の伝統、というか、家風のようなもののようです。

As you can see here, speeches like this, where the speaker “gets a scar on their heart,” seem to be a tradition, or rather, a family tradition, of the Ebata family.

30年以上の前の嫁さんと私の結婚披露宴において、先輩が、私(江端)の亡き父のスピーチをメモに残してくれています。

At my wedding reception over 30 years ago, a senior colleague wrote down a speech by my late father.

===== ここから =====

===== From here =====

フィナーレは新郎・新婦および各々の御両親の挨拶。

The finale is the groom and bride, as well as the respective parents, giving their greetings.

まずは代表として新郎の父君がスピーチを始める。

First, the groom's father begins the speech on behalf of both families.

型通りの挨拶に続き、新郎について語り始めた。

After the standard greetings, the groom's father began to talk about the groom himself.

「智一(私)はまだ未熟者で、常識が全然ありません!」

“Tomoichi (me) is inexperienced and has no common sense!”

身内を卑下するのが日本社会の風習とはいえ、30にもなった男をつかまえて まるっきり社会常識が欠落しているかのように言うのは、いかがなものか、と 思っていると、引き続き次の様に語った。

Even though it is customary in Japanese society to belittle one's relatives, I thought it was a bit much to say that a man who had reached the age of 30 had completely lost his common sense, but then he continued to say the following.

「智一は私に似て、ハッキリ言って、馬鹿です!!」

“Tomoichi is like me; honestly, he's an idiot!”

会場は笑いに包まれた。

The venue was filled with laughter.

苦笑する新郎。

The groom with a bitter smile.

「しかし、幸いにも、智一に母親の血が半分入っている、とするならば」

“However, fortunately, if Tomoichi has half of his mother's blood in him.”

するならば、って仮定してどーする・・・。

what will you do if you “assume” that...

===== ここまで =====

===== To here =====

そもそも、今回の長女の結婚式のスピーチについては、予告もなく私たち(新婦の両親)にスピーチを振った新郎新婦のカップルも悪い。

To begin with, the bride and groom who asked us (the bride's parents) to give a speech at their daughter's wedding without warning were also at fault.

ノーチェックで私にスピーチさせたら、『何が起こるか分からない』ことくらい、当然予想しておくべきだったのです。

If they had let me give the speech without checking it, they should have naturally expected that 'anything could happen.'

-----

次女も結婚式/結婚披露宴の開催を希望しているようですので、今回の件で、私のスピーチに「検閲」をかけてくる可能性はあります ――

My second daughter also seems to want to hold a wedding ceremony/wedding reception, so there is a possibility that they will “censor” my speech on this occasion.

というか、そもそも、私にスピーチさせるな。

Or rather, don't make me give a speech in the first place.