★データ解析備忘録★

ゆる〜い技術メモ

【R】国勢調査 小地域 Shapefile を使って緯度経度から住所を求める(市までわかっているときver.)

はじめに

@u_riboさんによるこんなツイートがある。

要するに、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を全部つなげて…みたいなのは必要ないんだろうなーと思います。