📚

サーバレスで逆ジオコーディングができないか考えてみる

2024/12/22に公開

はじめに

この記事は、FOSS4G Advent Calendar 2024 シリーズ2の12/22の記事です。本当は、簡単でも良いので実装をすれば良いのですが、時間がないのでアイディアのを出してみようと、いうネタです(汗

ジオコーディングと逆ジオコーディングについて

まず、確認です。ジオコーディングと逆ジオコーディングについて、ChatGPT-4oにまとめてもらいました。曰く、

ジオコーディングと逆ジオコーディングは、地理空間情報を扱う際に非常に重要なプロセスです。それぞれの概要と実装に必要なシステムについて説明します。

とのことです。

ジオコーディングとは?

ジオコーディング(Geocoding)は、住所や地名などのテキスト情報を
地理座標(緯度・経度)に変換するプロセスです。

利用例
- 顧客住所を地図上にプロットする。
- 施設(病院、店舗など)の位置を可視化する。

実装に必要なシステム
1. 地理空間データベース
 ・住所や地名の情報が保存されたデータベースが必要です。
 ・PostGIS(PostgreSQLの拡張)を使用すると、地理情報を効率的に管理できます。

2. データソース
 ・住所データ(例:国土数値情報の位置参照情報)。
 ・オープンな地図データ(例:OpenStreetMap)。

3. ジオコーディングエンジン
 ・オープンソース例: Nominatim(OpenStreetMap対応)。
 ・商用サービス例: Google Maps API, HERE API。

4. 検索アルゴリズム
 ・部分一致や補完に対応できる柔軟な検索ロジック。
 ・日本では住所の正規化が重要(丁目や大字の形式の揺らぎ対応)。

5. APIやフロントエンド
 ・ユーザーが住所を入力し、座標を取得できるシステム

逆ジオコーディングとは?

逆ジオコーディング(Reverse Geocoding)は、地理座標(緯度・経度)から、
対応する住所や地名を取得するプロセスです。

利用例
 ・GPSデバイスが取得した位置情報をユーザーに分かりやすい形式で表示する。
 ・地図上のクリックした地点の住所を表示する。

実装に必要なシステム
1. 地理空間データベース
 ・緯度・経度に対応する地理データが必要。
 ・PostGISで管理可能。特に空間インデックス(R-treeなど)を利用すると高速化。

2. データソース
 ・地理的な範囲と詳細度に応じた地図データ(例:OpenStreetMapのポリゴンデータ)。

3. 検索アルゴリズム
 ・点とポリゴンの包含関係を効率的に判定するロジック
  (PostGISのST_Contains関数などを使用)。
 ・最近傍検索(ST_Distance関数など)。

4. APIやフロントエンド
 ・座標を入力して住所を返すシステム。

ということで、基本的に以下のようにまとめることができると思います。

  • サーバにPostGISによる空間DBを構築する
  • 地名なり、緯度経度形を入れると、DBを検索し、緯度経度なり、地名なりを返すシステム

地理空間データベースは必要なの?

ChatGPT先生に聞いた限りでは、地理空間データが必要ですとの回答でしたが、実はなくても実装可能です。私の知っている範囲では、Geoloniaさんのcommunity-geocoderと、open-reverse-geocoderがあります。ABRジオコーダー(abr-geocoder)も多分、静的コンテンツで作られていると思うのですが、確認はできませんでした。

コミュニティジオコーダの場合、入力した住所に応じて、Geolonia 住所データの該当市町村データをゲットしてきて、それに基づき表示をこなっています。逆ジオコーディングは、ベクトルタイルの値を読み込んでいるようですね。

今回は、こうした仕組みとは別に、データPNGを使って逆ジオコーディングができないかと考えてみました。

データPNGとは?

これも、chatGPTにまとめてもらいました

データPNG(Data PNG)は、画像ファイルフォーマットであるPNG(Portable Network Graphics)を
利用してデータを表現する手法です。インターネット上で大量のデータを高速かつ効率的に扱う目的で考
案されました。PNGは標準で圧縮機能を持ち、ウェブブラウザでも容易に扱えるため、特にウェブアプリ
ケーションでの利用に適しています。主に地図タイルでの利用を想定していますが、他の分野でも有効です。 

データPNGは、以下の2つの形式に分類されます。

グリッドPNG(Grid PNG)
グリッドPNGは、平面上の格子データを扱うための形式です。縦横の等間隔の線が交差する各点にデータ
を関連付けるもので、一般的なメッシュデータも含まれます。グリッドPNGを地図タイルとして利用する
ものを「グリッドPNGタイル」と呼びます。 

数値PNG(Numerical PNG)
数値PNGは、グリッドPNGの一種で、連続的に変化するスカラー型のデータを表現します。各ピクセルの
RGB値を24ビットの符号付き整数として解釈し、係数とオフセットを用いて実際の値に変換します。 

パレットPNG(Palette PNG)
パレットPNGもグリッドPNGの一種で、限定された色のみを使用する形式です。各ピクセルのRGB値を24
ビットの符号無し整数として解釈し、その値に対応する情報(凡例情報)を別途提供する必要があります。 

リストPNG(List PNG)
リストPNGは、固定長レコードデータを扱うための形式です。単体でも使用できますが、点群PNGのよう
な派生フォーマットを作成して使用することも可能です。 

点群PNG(Point Cloud PNG)
点群PNGは、2次元または3次元の座標値を持つポイントデータを表現するための形式です。各ポイントに
は位置情報のほか、関連付けられる付加情報を含めることができます。 

データPNGは、これらの形式を活用することで、地理空間データやその他の大量データを効率的に配信・
表示することが可能となります。

データPNGを使った逆ジオコーディングのアイディア

ということで、データPNGに地番や住所のデータを入れ込んでしまって、それを読むことで逆ジオコーディングできないかと、妄想しました。やり方としては、パレットPNGタイルと、リストPNGタイルの二通りがあるのではないかと思います。

パレットPNGタイルの場合、@shi-worksが投稿されているFOSS4Gを活用した国土数値情報のベクトルタイル化とデータPNG化の試行についてや、MapLibre GL JSでのパレットPNGタイルの凡例情報のポップアップ表示についてを参考にして、各住所や地番と毎に凡例情報を作成するという手があると思います。

が、ただそうすると凡例ファイルが莫大なサイズになりそうな気がします・・・

ということで、リストPNGを使った方法を考えてみました。リストPNGは、「画像フォーマットであるPNG形式を利用して固定長レコードデータを扱うためのフォーマット」です。そのため、地番・住所情報を固定長レコードに変換する必要があります。これは、デジタル庁のアドレス・ベース・レジストリの、アドレス・ベース・レジストリデータ項目定義書の全国地方自治体コード(6桁)、町字ID(7桁)、地番ID(地番1(本番)5桁のみ使用)、住居表示フラグ(1桁)、街区ID(3桁)と住居ID(3桁)(合計6桁)をリストPNGにすれば良いのではと考えました。

ただし、リストPNGは、1ピクセルには7桁の整数までしか格納できないので、以下の4つのリストPNGタイルを作ることを想定します。

  • 全国地方自治体コードタイル
  • 町字IDタイル
  • 地番IDタイル
  • 街区・住居IDタイル

また、これとは別に、地番ID.json もしくは、街区・住居ID.jsonを作っておいて地番や街区・住居の名称を格納、/全国地方自治体コード/町字ID/フォルダに配置します。

そして、緯度経度を与えたとき、それれぞれのタイルの値を読みいって、https://hoge.hoge/全国地方自治体コード/町字ID/地番ID.json もしくは、街区・住居ID.json を読み取り、住所情報を取得当仕組みを考えました。

null値は地番IDがアルファ値が255の場合とし、住居表示フラグが1の場合は、街区・住居ID.jsonの取得を試み、なかった場合は地番IDから地名を、あった場合が街区・住居IDから地名を取得するというアイディアです。

ええ、アイディアです・・・・

ということで、実際にやって見られると良いのですが、アイディアで終わっています(汗

また、わざわざデータPNGにしなくてもベクトルタイルにすれば良いんじゃね、って話もあると思います。また、リストPNGじゃなくて、グリッドPNGで単純に値を読み込んだほうが良いんじゃないか、という話もあります。

そのへんも含め、検証は今後ということで・・・。

中途半端で、大変申し訳ありません(汗

Discussion