はんけトケのロゴタイプ
これは何?
開発ノート

小ネタ

個別の記事にするまでもない小ネタを五月雨に羅列します。 ときどき追記するかもしれません。

検索ボックスのオートコンプリート

JavaScriptによる検索ボックスのサジェスト/オートコンプリートの方法については、ネットを探せば例がいくらでも出てきます。 ユニコード正規化したりひらがな・カタカナを同一視したりなど、日本語特有の手間を加える必要はあるかもしれません。

肝心の候補を列挙する仕組みは、市区町村名をキー、経緯度を値とする配列を用意しておき、入力文字列とキーとが前方一致するものを探すだけ。 文字数が少ないこともあり、数千件程度ならいまどきのコンピューターは瞬時に探し終えます。 たとえもっと件数が多くて重くても、多少タイマー遅延させるとかワーカーに投げるとかすれば操作性は落ちないでしょう。

はんけトケでは、この配列中に見つからなかったら(かつオンラインなら)外部のジオコーディングAPIを使う、との二段構えになっています。 具体的には国土地理院のジオコーディングAPIで、JSON形式で複数の候補を返してきます。 が、実装もユーザーとしての操作も面倒になるためこちらはサジェスト表示せず、1つ目の候補の経緯度を即採用しています。

市区町村名のローマ字表記データ

オートコンプリート検索を、アルファベットでもできるようにしたい。 そのためには市区町村名のローマ字表記を網羅したデータが必要です。 でも、いったいどこにあるのでしょうか。

ネットを探すと、民間のオープンデータがいくつか出てきました。 どうやらいずれもカナの市区町村名を機械的にローマ字変換したもののようです。 これはB案として、できればもう少し公的なデータが欲しいところ。

以前e-Statでデータを漁っていたとき、ローマ字表記の含まれたファイルを見かけたことはあるのですが、それが何だったか覚えておらず、ちょっと探してみても見つかりません。 英語版の検索ページから探してはどうか、と思いついて開いてみたら、なんとすぐに意外なところに見つかりました。

e-Stat英語版のデータ検索フォームに市区町村の選択リスト(region candidate)があり、その各要素が「市区町村コード+ローマ字名」なのです。 内部のデータベースだかファイルだかをJavaScriptで流し込んでいるらしく、詳細は不明ながらまずまず公的なものと見なしてよさそう。 市区町村名を片っ端からローマ字にしてあるだけなので、いわゆる「データベースの著作物」にも当たらないでしょう。

海を省く

はんけトケは、日本全域の人口メッシュをバイナリー化したデータ(要は画像のピクセル配列のようなもの)を内部に持っています。 しかしご承知のように、日本は経緯度の座標系を斜めに細長く断つ列島で、メッシュのほとんどは海です。 はんけトケは基本的に人口を扱うため、誰もいない海の領域はメモリーの無駄でしかありません。

そこで、このデータから海を省く工夫、一種の圧縮(ファイルを縮めるのではなく、占めるメモリーを減らすデータの持ち方)をします。 仕組みがごく単純で、計算の際にデコードに時間がかからないこと、が条件です。

目標としては、だいたい元の半分くらいのサイズになれば十分。 実は気にしているのはおなじみiOS版Safariの制約であり、むやみに省メモリーを追求したいわけではありません。

はんけトケの場合

いろいろ考えられるでしょうが、現在はんけトケが採っているのはきわめて原始的な方法です。 すなわち、メッシュデータ各行(横1ライン)について、先頭(左端)から格子を一つずつ調べていき、陸地が初めて現れるまでの海の格子を省くのです。 そして、省いた格子の個数を行の先頭に書き込んでおき、そのすぐ隣へ陸地以降の格子すべてを移して空白を詰めます。 最後の陸地から終端までの海の格子はこれまた省きます。

ざっくり例えると、日本の陸地の東西に面する海をランレングス法で縮めるようなものです。 するとその結果、メッシュデータ全体の横幅がそこそこ縮みます。 欠点としては、最初の陸地と最後の陸地とのあいだにある海は省けないこと。

じぱんぐライクの場合

ついでなので記しておくと、『じぱんぐライク』も同様のメッシュデータを持っています。 ただし、こちらは地図をクリックした地点の市区町村を判定するためのもので、人口計算ほどの高速性は要求されません。 とはいえ軽いに越したことはなく、実装も面倒だったので、アイデアは違えどやはり原始的な方法を採っています。

こちらでは、メッシュデータの各行を均等に16ブロックに分け、各ブロックに1格子でも陸地が含まれていたら1、海だけだったら0として16ビットのビット列を作り、行の先頭に書き込んでおきます。 そして「0」に該当するブロックを省き、「1」に該当するブロックをそのぶん左へ詰めていきます。 結果、メッシュデータ全体の横幅がそこそこ縮みます。

ブロックは細かく刻むほど無駄が減りますが、たとえば16ブロックと32ブロックとで劇的な差が生じるほどではなく、ほかの要素との兼ね合いで16としました。

このように、はんけトケもじぱんぐライクも海を東西へ一次元的に圧縮していますが、南北にも注目して二次元的にしてみたり、元々の座標系を変えてしまう(45度回すだけでも日本を囲む矩形くけいは小さくなりそう)といった工夫も考えられます。

画像ファイルのワナ

画像データをブラウザーに読ませるには、もちろんPNGその他の汎用画像ファイルフォーマットを使うのが最も簡単で高速でしょう。 しかし、たとえばバイナリー化した人口メッシュのようなデータテクスチャーの場合、この方法には問題があります。

ひとつは、画像圧縮において最適化の影響でアルファ値が変化してしまうこと。 作業用ではなく流通用のフォーマットなので仕方ありませんが、これでは事実上、アルファ値を使うことができません。 端からRGBAではなくRGBテクスチャーとして用いるつもりならいいのですが。

そしてもうひとつ、こちらは危険な大問題。 環境によっては画像ファイルの展開処理にバグがあり、なんとそのせいで情報が壊れてしまうのです。 どの環境かというと、やはりiOS版Safariです。 具体的には、iOS26版。 バグ報告はしてみたものの、iOS26.2現在まだ修正されていません。

バグが生じること自体は仕方ありません。 気づいたら直せばいいのです。 が、厄介なのはこのバグが気づかれにくいことと、気づいても一般には無問題とみなされ対処が後回しにされやすそうなことです。 なぜなら、「展開した画像の色味が視認できぬほどほんのわずか変化する」との“軽微”な現象だから(ちなみに、色変換のたぐいが一切起こらないようメタ情報やAPIへの指示やOS設定にまで注意してみても同じ)。 いかにも優先度が低そうでしょう。

ヒトが目で見るだけの画像なら、確かに問題ありません。 しかしプログラムが処理するデータにおいては、値が±1変わってしまうだけでも重大な作用を引き起こしかねません。

たまたまiOS版Safariがバグっていたためやり玉に挙げてしまいましたが、そもそも厳密であるべきデータに画像展開を用いる手法には、環境を問わずこうした危うさが常に潜在していると考えられます。

なぜ人口計算が「概算」なのか?

精度の説明などからおおよそ察しがつくかと思いますが、はんけトケの人口計算が概算なのは、メモリー節約のため、計算に用いる人口メッシュデータを対数化しているからです。 16ビットの原数値を8ビットの対数にしています。

その後データの持ち方を変えたため、現在はそこまでケチらなくてもいいものの(対数でなくしたほうが処理も速い)、概算と断っているほうが気楽なのでそのままにしています。

そもそも、5年周期で秘匿・補完上等の国勢調査の人口にせよ、刻一刻と変化するリアルタイム人口にせよ、1人単位で“正確”な数値にこだわる意味がどれほどあるのか。 法的・学術的な根拠として(つまりわれわれ日常の営みとは別の次元で)用いる以外、そんなことに汲々きゅうきゅうとするのは計算機やデータに人間が使われる現代病の感があり、利益もないのに与したくありません。

用語・注釈

ユニコード正規化
ユニコードでは、ひとつの字形に対して複数の表し方があり得る。 たとえば「ガ」という字形は、「ガ」と1文字でも、「カ」+「濁点」の2文字(合字)でも表すことができる。 こうした表し方をどれかに統一することをユニコード正規化という。
もし正規化しないと、見た目は同じでコードの異なる字が混在する恐れがあり、検索やソートにおいて具合が悪い。
ワーカー(ウェブワーカー)
JavaScriptにおけるバックグラウンド実行スレッド。
ジオコーディングAPIについて
こうしたAPIを利用する際は、結果をキャッシュするなどしてアクセス数を減らす工夫をするのが望ましい(APIサーバーの設定さえ適切ならブラウザー任せでよいはずだが)。 一般論としては、取得データの権利問題が生じないよう、キャッシュの寿命はセッション内に限るのが無難。
カナのローマ字変換について
カナをローマ字に変換するアルゴリズムは案外厄介で、未検証の変換結果データは採用しにくい。 これに加えて公的なデータを求めた理由は、ローマ字の表記方式を当該機関なりの根拠とともに統一するため。

 

(最終更新:2026.1.17)