プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

古いNASへの接続について

先日、近所の電気工事のため、昼から2時間程度停電すると予告がありました。まあ、家なので家電とかはそのままでいいかなと思ったんですが、自宅においてある NAS は一応シャットダウンしておこうと思いました。

さて、いざ当日の朝、 NAS を落とそうと思ってアクセスしたら、つながらない。

ウィルス対策ソフト入れてるので、そいつの影響かな?と考えて、一時的に切ってみると、

に変わりました。エラーは

ERR_SSL_VERSION_OR_CIPHER_MISMATCH

となってます。

かなり古い NAS (Netgear ReadyNas)なので、管理画面が https じゃなくて http だったけな?とかも思ったんですが、残っていたメモ書きに https での URL が明記されてたので、これとも違いました。

原因

まあ、仕方ないので、ググってエラーを調べてみると、どうも SSL(TLS) のバージョンの問題のようです。 ある時期以降の Chrome では、TLS 1.0 / 1.1 での接続を行わないようになったみたいです。

※ 下記によると Chrome 98 (2022年2月2日)から無効になり、設定で回避することもできなくなったそうです。

Previous release notes - Chrome Enterprise and Education Help

今のChromeのバージョンを確認すると、

バージョン: 111.0.5563.148(Official Build) (64 ビット)

となっていました。

対応方法

NAS 側のサポートはとっくに切れてるので、NAS側の TLS をアップデートすることもできません。 じゃあどうすればいいんだろうか?と思ってググってみると、

「ERR_SSL_VERSION_OR_CIPHER_MISMATCH」サポートされていないプロトコル (更新あり) | AMK 情報館

にあるように Firefox だと TLS のバージョンを指定することができるようです。

なので、こちらを参考にして、 Firefox でつなげてみます。

Firefox が入ってないので、まずはダウンロードして、インストールします(作業時点の最新版、バージョン 112.0 (64 ビット))。

アドレスバーに

about:config

と入力して、設定画面を開きます。

で、上部の検索窓に、tlsと入力して、表示された設定内容で

security.tls.version.min

が 3 となっているのを、 1 に変更します。

で、再度接続します。

すると。おお、警告文が表示されましたが、無事に接続できました。

TLS 1.0 の確認

さて、接続した NAS ですが、 TLS のバージョンを一応、確認してみます。下記の記事にあるように、

Chrome「ERR_SSL_OBSOLETE_VERSION」警告通知の解決方法

Chrome でも確認できるとあるのですが、これって、サイトとの接続後に表示される情報なので、現状の Chrome だと使えません。

なので、 FireFox でサイトに接続後、セキュリティを表示してSSLのバージョンを確認すると

となっており、 TLS 1.0 が使われてることが確認できました。

当面 NAS 替える予定もないし、自宅の NAS につなぐ時だけ、 Firefox を使うことになりそうですね。

経営セーフティ共済へ加入しました

先日、ネットを見ていたら、何かの拍子に『経営セーフティ共済』というのがあることを知りました。今となっては、なんでこれを目にしたかも覚えていないのですが、まあ、そういう制度があるということを知ったんですね。

で、これを調べてみたら、ちょっとおもしろい。

取引先が倒産などした際に、売掛などの債権があれば、掛け金の10倍まで(正しくは債権額または、掛け金の10倍のいずれか少ないほうの金額まで)融資してもらえるというものです(共済金と呼ぶようです)。融資は、無担保・無保証人・無利子とのことです(ただし、手数料なのか、借りる金額の1割が積立金から取られるので、まったく経費がかからないわけではないです)。

もし、共済金を受け取らず、4年以上掛け続けると、解約時に全額戻ってきます(解約手当金と呼ぶらしい)。ただ、解約は一部分だけ解約するというのはできないとのこと。

掛け金は月5千円から20万円までとのこと。 税法上も、掛け金は経費扱いにできるとのことです。ただし、解約手当金は、解約した事業年度の事業所得になるのでその時に税金がかかります。

ちなみに、ネットでいろいろと調べていると、節税になる、という表現もありますが、正確には、解約手当金を受け取るタイミング次第ですね。解約したタイミングの売上が大きければ、節税になるとは限らないです。 なので、そのあたりは自分でコントロールするか、税金の支払いの繰り延べと割り切るか、考えておく必要がありそうです。

やってるのは、独立行政法人 中小企業基盤整備機構(小規模企業共済やってるところです)なので、信用して大丈夫でしょう。

入るにしろ、入らないにしろ、こういう制度もあるというのを知っておいて損はないと思ったので、まとめてみました(が、素人なので内容は保証できません)。興味のある方はご自分で調べてみてください。

で、結局

以前、取引先からの売掛金回収に数年かかり、いろいろと気をもんだことがありました(まあ、倒産ではないので、これに入っていても使えなかったのですが)。

その経験を踏まえると、取引先がどうなるかなんて、先が見通せないと思うので、いざという時に困らない程度(というか、何かあった際の選択肢を増やしておくため)に、加入することにしました。

加入手続きは、直接中小機構とやり取りするのではなく、中小機構と提携している団体または金融機関で手続きするとのことでした。私の場合は、近くの伊勢商工会議所を通じて手続きしました。

あと、この制度は、前払い制度があり、来年1年分を前払いするという形でこの昨年の12月に加入してみました。12月スタートにしたのは、翌年からも前払い制度を使うなら、開始月の1か月前に手続きを行う必要があり、この手続き月を11月にできるようにしたかったためです。

ちなみに、実は最初に11月中に手続きに行ったんですが、12月スタートにするには、12月になってから前払金を振り込む必要があったので、その点だけちょっと手間取りました。もし、加入を考えている方がいるなら、振込月が結構絡んでくるので、タイミングの調整ができるように余裕をもって検討したほうがよさそうです。

振込を完了して、商工会議所に書類一式と振込時の控えを持っていくと、無事に受理されました。その後は、銀行に引き落とし口座の確認等を行うとのことで、無事に確認ができたら、申込書の控えが送られてきました。

これで、一連の手続きが無事完了です。先日、証書も送られてきたので特に問題もなかったようです。

なんにしても、取引先の倒産なんて遭遇しなくて、将来、無事に解約手当金を受け取れることを願っています。

歩行者向けのルート検索に挑戦(その1)

こちらの記事などで、 OpenStreetMap のデータを OverpassAPI で取得する話を書きました。

で、これを一生懸命やっているのは、 OpenStreetMap の地図データをもとに、歩行者向けのルート検索をやってみたいなと思ったためです。

というのも、リリース中のアプリ 避難所検索@伊勢 でルート検索ができるようしているのですが、ここで使っている GraphHopper というライブラリが、スマホ上でのオフラインルート検索機能の開発を停止したためです。

もちろん、現行のものは継続して使えるんですが、先々サポートされないので、困ったな、というのが動機です。

このアプリでカバーする範囲は(一般的なアプリに比べれば)狭い地域だし、歩行者向けであれば交通規制とかの考慮も後回しでいいかなと思うので、自分で組んでみると面白そうです。

もし、うまくルート検索ができるようになれば、このアプリ自体は現在 Android 版だけなので、 Flutter を用いて Android / iOS 両対応にもできるかなと思います。

ということで、手を出してみました。

とりあえず、ルート検索全体の形が見えるまで、あれこれと試行錯誤するだろうから、お手軽に使えるとういことで、まずは Python で試してみることにしました。

今回取り組んだこと

アプリに載せるところまで考えるとなかなか先が長いので、まずは、下記の部分を実装してみました。

  1. OpenStreetmap のデータから、道路のデータを取り出す
  2. 道路のデータから、グラフを作る
  3. グラフ上の2点間の最短経路を見つける

OpenStreetMap の道路は way とそれを構成する node になっているので、それをグラフの形にして持たせてやればなんとかなりそうです。グラフ上の2点間の最短経路を求める方法も、とりあえずは簡単なものを使って試します。

作成したプログラムは GitHub 上のリポジトリにアップしてますので、興味のある方は見てみてください。

OpenStreetmap のデータから、道路のデータを取り出す

OverpassAPI で取得します。取得するデータは、下記クエリで指定するものとします。

[out:json]
[bbox: 34.48756, 136.71216, 34.48906, 136.71424];
way["highway"];
out geom;

地図上でbboxで緯度経度を使って範囲を限定しているのは、扱うデータが大きいとテストにいろいろと余計な手間がかかるためです。

Overpass turbo で表すとこんな感じになります。近鉄宇治山田駅周辺の道路ですね。

問題なく実装ができれば、最終的には下記のように伊勢市全体に範囲を広げてやるつもりです。

[out:json];
area["name" = "伊勢市"];
way(area)["highway"];
out geom;

なお、道路を表すタグとしては、

を参考にして、 highway タグが存在している way としました。

道路のデータから、グラフを作る

取得したデータをもとに、グラフを作ります。クラスの構成としては node クラスを作り、OpenStreetMap の node に対応させます。で、この node クラスに、道路でつながっている他の node を記録させていきます(C とかでグラフを実装するときに使う隣接リストに似たイメージですかね)。

具体的には、つながってる他の node ID とそこまでの距離をペアにしたものを『辺』として、リストにします。ある node に注目したときに、隣接する node の数はそんなに多くないだろうと見込んで、単純なリストにしてみました。

way 単位でこの処理を繰り返しますが、新しい way を追加する場合、同じ node ID が出現したら、既存の node に対してもグラフの辺を追加してやる必要があるので、その処理を行います。

これで、グラフができるはずです(詳細は実装を見てください)。

2点間の距離の算出

なお、グラフを構成する際に、2点間の距離も求めておきます。緯度経度から距離を求めるには、下記の記事を参考にして GeoPy を利用します。

緯度経度から距離を算出するPythonのライブラリ ― GeoPy | H-MEMO

こういうのが簡単に使えるのが Python のありがたいところですね。

グラフ上の2点間の最短経路を見つける

とりあえず、経路検索はダイクストラでやってみます。訪問先の node のうち、最も近い node を取り出すのはヒープを使います。このあたりのことは、

こちらの『データ構造とアルゴリズム』を参考にしています。

動かしてみた結果

作成した Python プログラムを用いて、経路検索を行ってみます。

始点の node は 1301959953 終点の node は 5743469002 という点を選んでみました。

mor@DESKTOP-DE7IL4F:~/work/routing/osm$ python3 overpassapi.py 
test
number of osm elements:  11
node id: 332553449, (lat, lon) =(34.4896078, 136.7123982)
    adj id: 4594086915, (lat, lon) = (34.4895336, 136.7124605), dist = 10.024779836730287
(中略)
number of node:  62
shortest path
node id: 1301959953, distance: 0 m
node id: 5743469008, distance: 32.745117994646556 m
node id: 1303115718, distance: 83.19043320656411 m
node id: 1251267334, distance: 100.06976611499306 m
node id: 4594086913, distance: 105.76866701812669 m
node id: 4594086921, distance: 112.61548106213671 m
node id: 945145693, distance: 121.24926125927396 m
node id: 945145699, distance: 131.42225299846484 m
node id: 1303115774, distance: 151.44713160863677 m
node id: 1303115756, distance: 203.6311246298111 m
node id: 4592585522, distance: 211.5478194591524 m
node id: 5743469002, distance: 221.89806496501768 m
mor@DESKTOP-DE7IL4F:~/work/routing/osm$ 

これだけだとよくわからないので、出てきたノードのリストを OverpassAPI で表示させると、

[out:json]
[bbox: 34.48756, 136.71216, 34.48906, 136.71424];
node(id:
1301959953,
5743469008,
1303115718,
1251267334,
4594086913,
4594086921,
945145693,
945145699,
1303115774,
1303115756,
4592585522,
5743469002
);
out;

それっぽい経路が出てますね。

次は

これで、ごくごく簡単ですが、グラフ上の node から 別の node までの経路検索を行うことができるようになりました。

次は、実際の地図アプリで、この経路検索を使うことを想定し、任意の地点から任意の地点までの経路検索をできるようにしたいと思います。

というのも、アプリでルート検索するときに、開始点とかをアプリの地図上でタップして指定したりすると思いますが、このときの地点って、必ずしも道路そのもや道路上にある node に一致しているとは限らないと思います。

なので、タップして指定した地点から、何らかの方法で、道路上にある一番近くの node をどうにか見つける必要があるかと思ってます。これって、考え出すと結構面倒そうです。世の中のルート検索ツールってすごいんですね、改めて実感します。

なかなか先は遠そうですね。

グラフの簡略化

ほかにも、こんなことも組み入れたいです。

今回の実装で作成したグラフですが、分岐(交差点)がないのに node だけがあるような場合があります。例えば、 OpenStreetMap だと一本道だけど曲がってるようなときは、折れ線のような形で表現されるため、折れ線の頂点にノードが存在します。

こういう node (node_t と呼ぶことにします)に隣り合う、前後の同じ way 上の node を node1 , node2 として

node1 - node_t - node2

という並びの関係があるときを考えてみます。

このとき、 node1 - node_t 間の距離を d1 、 nod2 - node_t 間の距離を d2 とすれば、node1 - node2 間の距離は d1 + d2 として求められます。なので、 node_t を削除して、 node1 の隣接ノードとして node2 が存在し、その間の距離は d1 + d2 であるとしてしまえば、最短経路を求めるためのグラフとしては同じものとして扱えるかと思います。ノード数が減れば、グラフがコンパクトになるので、計算時間などの面で有利かなと思われます。

参考までに、下記などに途中のノードを省略する考えとかが載ってました(中身を全部読んだわけではないです)。

https://www.gisa-japan.org/content/files/conferences/2016/papers/F55.pdf

参考

既存のサービス(BBBike)を使って、道路データを抽出する話などもありました。

Webサービスを使って道路ネットワークを取得してみる – FRONT