【R】国勢調査 小地域 Shapefile を使って緯度経度から住所を求める(市までわかっているときver.)
はじめに
@u_riboさんによるこんなツイートがある。
一部で話題の(?)e-Statが提供する国勢調査小地域のShapefileをRからダウンロードする関数を書きました (gifが高速過ぎる orz) コードは https://t.co/Dd2R58ov94 pic.twitter.com/SRo2H1Fk4W
— Uryu Shinya (@u_ribo) 2017年7月14日
要するに、shapefileの細かい版ですね。細かいので、市レベルでファイルが分かれているようです。
今回は、これを使って逆ジオコーディングをやってみます。ただし、「やってみた」レベルなので今回は知りたい緯度経度が何市にあるかまでは絞れているとします。 市を見つけるのには、RであればRで緯度経度から都道府県・市区町村を求める、SASであればSASによる逆ジオコーディング(緯度経度から都道府県・市を求める)が参考になります。
場所を見つけるコード
まず、さきほどのツイートのコードに従って千葉県浦安市のshapefileをダウンロードします。もちろん、http://e-stat.go.jp/SG2/eStatGIS/page/download.htmlから手動でダウンロードしてもOKです。ダウンロードしたら、zipを解凍します。
shapefileの読み込み
これは{sf}パッケージを使います。
library(sf) urayasu_shp <- st_read("/path/to/A002005212015DDSWC12227/h27ka12227.shp")
find_place()
という関数を書きました。これは上記uriさんのQiitaを参考にしています。
# 住所(何丁目レベル)判定 #' @param sp_polygon object of class sf, sfc or sfg #' @param lon longitude #' @param lat latitude find_place <- function(sp_polygon = df, lon = lon, lat = lat) { which.row <- sf::st_contains(sp_polygon, sf::st_point(c(lon, lat)), sparse = FALSE) %>% grep(TRUE, .) if (identical(which.row, integer(0)) == TRUE) { message("指定した座標がポリゴンに含まれません") } else { geos <- sp_polygon[which.row, ] %>% dplyr::mutate_if(is.factor, as.character) place_name = paste0(geos$KEN_NAME, geos$GST_NAME, geos$MOJI) %>% stringr::str_replace_all("NA", "") return(place_name) } }
結果
# 東京ディズニーシー > find_place(urayasu_shp, 139.884678, 35.626065) although coordinates are longitude/latitude, it is assumed that they are planar [1] "千葉県浦安市舞浜" # 浦安駅 > find_place(urayasu_shp, 139.892544, 35.665573) although coordinates are longitude/latitude, it is assumed that they are planar [1] "千葉県浦安市北栄1丁目"
かなり細かくわかってしまって怖いですね… ちなみに浦安駅の住所は「千葉県浦安市北栄1-13-1」だそうです。
おそらく、このレベルで分かる必要があるときは多くは市レベルまで分割したデータなのでこういうshapefileを全部つなげて…みたいなのは必要ないんだろうなーと思います。