leafletでGeoJSONを使った時のメモ

データ

このサイトに地球地図日本のshapefileをGeoJSON、TopoJSONに変換したものが置いてあるのでそれを使います。

library(jsonlite)

j <- fromJSON("https://github.com/dataofjapan/land/raw/master/japan.geojson", simplifyVector = FALSE)

GeoJSON

GeoJSONの仕様は以下に定められています。

GeoJSON Specification

が、まあそんなに細かい仕様を知りたいわけじゃないので、実物をざっくり見てみます。

str(j, max.level = 3, list.len = 3, vec.len = 3)
#> List of 2
#>  $ type    : chr "FeatureCollection"
#>  $ features:List of 47
#>   ..$ :List of 3
#>   .. ..$ type      : chr "Feature"
#>   .. ..$ properties:List of 3
#>   .. ..$ geometry  :List of 2
#>   ..$ :List of 3
#>   .. ..$ type      : chr "Feature"
#>   .. ..$ properties:List of 3
#>   .. ..$ geometry  :List of 2
#>   ..$ :List of 3
#>   .. ..$ type      : chr "Feature"
#>   .. ..$ properties:List of 3
#>   .. ..$ geometry  :List of 2
#>   .. [list output truncated]

この`Feature`というのがひとつひとつの都道府県にあたるようです。

ひとつの`Feature`の中は、以下のような構造になっています。

str(j$features[[1]], max.level = 5, list.len = 3, vec.len = 3)
#> List of 3
#>  $ type      : chr "Feature"
#>  $ properties:List of 3
#>   ..$ nam   : chr "Kyoto Fu"
#>   ..$ nam_ja: chr "京都府"
#>   ..$ id    : int 26
#>  $ geometry  :List of 2
#>   ..$ type       : chr "MultiPolygon"
#>   ..$ coordinates:List of 4
#>   .. ..$ :List of 1
#>   .. .. ..$ :List of 1235
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. .. [list output truncated]
#>   .. ..$ :List of 1
#>   .. .. ..$ :List of 6
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. .. [list output truncated]
#>   .. ..$ :List of 1
#>   .. .. ..$ :List of 8
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. ..$ :List of 2
#>   .. .. .. .. [list output truncated]
#>   .. .. [list output truncated]

色の設定

公式ドキュメントのやり方を見ると、どうやらFeatureごとのpropertiesfillColorという名前で指定すればいいようです。

library(purrr)
library(stringr)

colgen <- colorNumeric("Oranges", domain = range(d$チョコレート))

j$features <- j$features %>%
  map(function(feat) {
    nam <- feat$properties$nam
    nam <- str_to_lower(str_split(nam, " ")[[1]][1])
    nam <- if(nam == "hokkai") "hokkaido" else nam
    feat$properties$style <- list(fillColor = colgen(d[d$pref_alpha == nam, "チョコレート"]), fillOpacity = 1)
    feat
  })

描く

これをこうすると地図が描けます。が、めっちゃ遅い。。

leaflet() %>%
  addTiles() %>%
  addGeoJSON(j)

よく見ると、遅いよ?って書いてました。

Note that for larger JSON data, using parsed is significantly slower than using stringified, because parsed data must go through a JSON encoding step. (https://rstudio.github.io/leaflet/json.html

うーん、やっぱりRでGeoJSONとかTopoJSONを扱うのはつらそう。あんまり色の設定とかも楽にならなかったし。

If your data is in GeoJSON or TopoJSON format, you can either convert it into sp classes using rgdal::readOGR or geojsonio (docs) and then use the marker and shape functions to add them

けっきょくSPDFに変換してから処理をするほうがいいみたいです。うむむ。