25. 逆ジオコーディングの改善(2/4)
位置参照情報と同様に、e-Stat境界データと国土数値情報(行政区域)のシェープファイルをダウンロード
後、GDALの ogr2ogr コマンドでPostgreSQLで読み込める PGDump 形式に保存し、 estat ・ ksj の
各スキーマ内のテーブルに保存後、pgGeocoder側の各 boundary_* テーブルに反映
逆ジオコーディング( reverse_geocoder 関数)実行時の内部処理を、境界データを考慮したものに変更
コード箇所: https://github.com/gtt-
project/pgGeocoder/blob/gtt/master/sql/pgReverseGeocoder.sql#L72-L121
s_flag := FALSE; -- 市区町村境界フォールバックフラグ
SELECT INTO point st_setsrid(st_makepoint(mLon,mLat),4326);
-- 指定した緯度・経度にかかる大字境界ポリゴンを検索
SELECT INTO o_bdry geom FROM boundary_o WHERE st_intersects(point,geom);
IF FOUND THEN
-- 大字境界ポリゴンが見つかれば、その中に含まれる位置参照情報の街区ポイントを指定距離(デフォルト:50m)内から検索
SELECT INTO record todofuken, shikuchoson, ooaza, chiban,
lon, lat,
todofuken||shikuchoson||ooaza||chiban AS address,
st_distance(point::geography,geog) AS dist
FROM address
WHERE st_intersects(geog,o_bdry.geom::geography) AND st_dwithin(point::geography,geog,mDist)
` ` ` ` ` ` ` `
` `
` `
26. 逆ジオコーディングの改善(3/4)
IF FOUND THEN
-- 大字境界ポリゴン内で条件に合う街区ポイントがあれば返却
RETURN mk_geores(record, 1);
ELSE
-- 街区ポイントがなければ、大字ポイントから同様に検索
SELECT INTO record todofuken, shikuchoson, ooaza, NULL::varchar as chiban,
lon, lat,
todofuken||shikuchoson||ooaza AS address,
st_distance(point::geography,geog) AS dist
FROM address_o
WHERE st_intersects(geog,o_bdry.geom::geography)
ORDER BY dist LIMIT 1;
IF FOUND THEN
RETURN mk_geores(record, 2);
ELSE
-- 大字境界ポリゴン内で大字ポイントも見つからなければ、市区町村境界フォールバックフラグをONに設定
s_flag := TRUE;
END IF;
END IF;
ELSE
-- 都道府県境界などで大字境界ポリゴンが見つからない場合も、市区町村境界フォールバックフラグをONに設定
s_flag := TRUE;
27. 逆ジオコーディングの改善(4/4)
IF s_flag THEN
-- 指定した緯度・経度にかかる市区町村境界ポリゴンを検索
SELECT INTO s_bdry geom FROM boundary_s WHERE st_intersects(point,geom);
IF FOUND THEN
-- 市区町村境界ポリゴンが見つかれば、その中に含まれる市区町村ポイントを検索
SELECT INTO record todofuken, shikuchoson, NULL::varchar as ooaza, NULL::varchar as chiban,
lon, lat,
todofuken||shikuchoson AS address, 0 AS dist
FROM address_s AS a
WHERE st_intersects(a.geog, s_bdry.geom::geography);
IF FOUND THEN
-- 市区町村境界ポリゴン内で条件に合う市区町村ポイントがあれば返却
RETURN mk_geores(record, 3);
ELSE
RETURN NULL;
END IF;
ELSE
RETURN NULL;
END IF;
END IF;