なんかtwitterでRとleaflet関係の話をいくつか見かけ、自分も使いたいなーと思ったのでやってみました。
leafletパッケージとかもあるみたいですが、rChartsの方がアウトプットとか簡単そうだったんでそっちにしました。
やりたい事は簡単で、前回読み込んだ学校のデータをleafletを使って地図上にプロットしたいただそれだけです。
とりあえず前回と同様にデータを読み込みます。
#map of japan
jap <- readShapePoly(“data/japan_ver72.shp”)
#school
doc <- xmlParse(“data/P29-13_13/P29-13_13.xml”)
xml_data <- xmlToList(doc)
latlon <- xpathSApply(doc, “//gml:Point”,xmlValue) %>%
strsplit(” “) %>% unlist() %>% matrix(ncol = 2, byrow = T)
lat <- latlon[,1] %>% as.numeric()
lon <- latlon[,2] %>% as.numeric()
name <- xpathSApply(doc, “//ksj:name”,xmlValue)
type <- xpathSApply(doc, “//ksj:type”,xmlValue)
address <- xpathSApply(doc, “//ksj:address”,xmlValue)
school <- data.frame(name, lat, lon, type)
schlis <- data.frame(type = as.factor(c(16001:16007,16012)),
shisetu = c(“小学校”,
“中学校”,
“中等教育学校”,
“高等学校”,
“高等専門学校”,
“短期大学”,
“大学”,
“特別支援学校”))
school <- school %>% inner_join(schlis,by=”type”) %>% select(lat,lon,shisetu,name)
#日本の地域をポリゴンデータとして扱う
japan <- SpatialPolygons(jap@polygons)
#学校の点データ
x <- school[,2]
y <- school[,1]
xy <- cbind(x,y)
dimnames(xy)[[1]] <- c(1:NROW(school))
pts <- SpatialPoints(xy)
#ポリゴンデータとの重ね合わせ
ov <- over(pts,japan, returnList = FALSE)
schoolov <- data.frame(school,areaid = ov)
areadata <- data.frame(areaid = 1:length(japan), jap@data$SIKUCHOSON)
schoolov <- schoolov %>% left_join(areadata,by=”areaid”)
さて、ここまで来るとあとはプロットするだけです。
学校名がそのままだと文字化けしてしまうので、iconvを使ってutf8になおしてあげます。
schoolov$name <- iconv(schoolov$name, “shift-jis”, “UTF-8”)
データが整ったので後はrChartsでプロットするだけです。
p <- Leaflet$new() #leafletのマップ作成
p$setView(c(35.69735, 139.7604), 7) #マップの中心位置と、ズームのレベルを指定
#学校の数だけ地図上にマーカーを付与する。
for(i in 1:NROW(schoolov)){
p$marker(c(as.character(schoolov$lat[i]),as.character(schoolov$lon[i])), bindPopup = schoolov$name[i])
}
p$save(“outp03.html”, cdn=TRUE) #出力
はい。p$markerがもっと素直なやり方がある気がするのですが、面倒だったのでforでやっちゃいました。
緯度経度でcharacterにしているのは数値で値を渡したときに小数が途中で切られてしまい、位置情報が正しく表示されなかったからです。
ちなみに結果は以下のようになりました。(マーカーをクリックすると学校名が出ます)
そういえば線ひいたりもしたいです。忘れてました。
宿題という事で。
rChartsでやるべきなのか、leafletパッケージでやるべきなのか、leafletRでやるべきなのか・・・悩みますね。