Rから国土数値情報ダウンロードサービス Web APIを使うパッケージをつくりました
(この記事はFOSS4G Advent Calendar 2015 9日目の記事です)
RからGRASSを使います、と宣言していたんですが、GIS初心者すぎて挫折しました。。
即席でつくったパッケージの紹介でお茶を濁します。すみません…
国土数値情報ダウンロードサービスとは
国土に関する基礎的なGISデータセットをダウンロードできるサービスです。データの形式はJPGISという独自形式や、ESRI Shapefileなどがあります。
とてもありがたいサービスなんですが、いかんせんUIがイケてなくて欲しい情報探しづらいのが難点です。そこで、APIです。
国土数値情報ダウンロードサービスWeb APIとは
2014年12月からは、国土数値情報ダウンロードサービスの情報をXML形式で取得できるAPIが試験的に提供されています。
今のところ、利用できるのは、国土数値情報の概要情報を取得するAPIと、国土数値情報のZIPファイルダウンロードURLを取得するAPIです。検索できる形式も今はJPGISに限られています。
これをRから使うパッケージをつくりました。
国土数値情報ダウンロードサービスの利用規約
で、パッケージの紹介をするわけですが、その前に。国土数値情報ダウンロードサービスのAPIや、APIから取得したURLでダウンロードできるデータを利用する際は以下の利用規約を確認してからお願いします。
kokudosuuchiパッケージ
つくりました。
インストール
Githubからインストールします。
devtools::install_github("yutannihilation/kokudosuuchi")
使い方
kokudosuuchiパッケージを読み込みます。
library(kokudosuuchi) #> このサービスは、「国土交通省 国土数値情報(カテゴリ名)」をもとに加工者が作成 #> 以下の国土数値情報ダウンロードサービスの利用約款をご確認の上ご利用ください: #> #> http://nlftp.mlit.go.jp/ksj/other/yakkan.html
まずは国土数値情報の概要情報を取得するAPIの方を使ってみます。getKSJSummary()
という関数を使います。(パラメータもいくつか指定できますが、今のところはすべて指定できるものが1種類しかないのでデフォルトのままで問題ありません)
すると、APIへの問い合わせ結果を以下のようにtbl_df
にして返してくれます。
library(dplyr) d <- getKSJSummary() d #> Source: local data frame [100 x 5] #> #> identifier title field1 field2 areaType #> (chr) (chr) (chr) (chr) (chr) #> 1 A03 三大都市圏計画区域 政策区域 大都市圏 2 #> 2 A09 都市地域 国土(水・土地) 土地利用 3 #> 3 A10 自然公園地域 地域 保護保全 3 #> ...
ここで、identifier
は各データを表す識別子です。次のAPIで使います。field1
,field2
はカテゴリです。areaType
は、「1:全国のみ」「2:三大都市圏で分類」「3:全国・都道府県で分類」「4:メッシュで分類」の4種類があります。この種類によって次のAPIで指定するパラメータが違います。
次に、国土数値情報のZIPファイルダウンロードURLを取得するAPIの方を使ってみます。getKSJURL()
という関数を使います。こちらのAPIには、いくつかのパラメータが指定できます。(詳しくは仕様書を参照)
identifier
: データ識別子metroArea
/prefCode
/meshCode
: 欲しいエリアを指定します。指定するパラメータはareaType
によって変わります。(メッシュについては国土数値情報ダウンロードサービス(国土数値情報統一フォーマット)に詳細が書かれています)fiscalyear
: 年度
たとえば、大阪府の河川に関するデータが欲しいとします。まず、河川のデータのidentifier
を探します。
filter(d, stringr::str_detect(title, "河川")) #> Source: local data frame [1 x 5] #> #> identifier title field1 field2 areaType #> (chr) (chr) (chr) (chr) (chr) #> 1 W05 河川 国土(水・土地) 水域 3
ここでareaType
が3なので、指定するパラメータはprefCode
です。都道府県コードは毎回探すのがめんどくさいので、これもパッケージに入れておきました。
data("KSJprefCodes") filter(KSJprefCodes, prefName == "大阪府") Source: local data frame [1 x 2] prefCode prefName (dbl) (chr) 1 27 大阪府
27ですね。
では、指定するパラメータがわかったところでさっそくAPIに投げてみます。
getKSJURL("W05", prefCode = 27) #> Source: local data frame [1 x 9] #> #> identifier title field year areaType areaCode datum zipFileUrl #> (chr) (chr) (chr) (chr) (chr) (chr) (chr) (chr) #> 1 W05 河川 国土(水・土地) 2009 3 27 1 http://nlftp.mlit.go.jp/ksj/gml/data/W05/W05-09/W05-09_27_GML.zip #> zipFileSize #> (chr) #> 1 1.56MB
ありました。このURLからZipをダウンロードすれば、河川のデータが手に入ります。
河川をプロット
せっかくなので、このデータを使ってみます。APIで検索できるのはJPGIS 2.1のファイルのみ、と書かれていますが同じZIPにShapefileも入っていることもあります。河川データとかはそれなので、さくっとRで読み込むことができます。
データ読み込み
まずは先ほどのURLからデータをダウンロードしてきます。
W05file <- tempfile(fileext = "zip") download.file("http://nlftp.mlit.go.jp/ksj/gml/data/W05/W05-09/W05-09_27_GML.zip", destfile = W05file) #> trying URL 'http://nlftp.mlit.go.jp/ksj/gml/data/W05/W05-09/W05-09_27_GML.zip' #> Content type 'application/zip' length 1633167 bytes (1.6 MB) #> downloaded 1.6 MB #> W05dir <- tempdir() unzip(W05file, exdir = W05dir)
これをrgdalパッケージで読み込みます。レイヤーは二つありますが、今回はW05-09_27-g_Stream
の方を使います。
library(rgdal) ogrListLayers(W05dir) #> [1] "W05-09_27-g_RiverNode" "W05-09_27-g_Stream" #> attr(,"driver") #> [1] "ESRI Shapefile" #> attr(,"nlayers") #> [1] 2 river <- readOGR(W05dir, "W05-09_27-g_Stream") #> OGR data source with driver: ESRI Shapefile #> Source: "C:\Users\user1\AppData\Local\Temp\RtmpmqbOOY", layer: "W05-09_27-g_Stream" #> with 2125 features #> It has 10 fields
追記(2016//11/3):
readOGR()
にはencoding
引数があったので、以下のように指定すれば、このあとの自分でEncoding()
を設定する手順は必要はありませんでした。すみません。
river <- readOGR(W05dir, "W05-09_27-g_Stream", encoding = "UTF-8")
データを覗いてみる
データをちょっと覗いてみます。
knitr::kable(head(river@data))
W05_001 | W05_002 | W05_003 | W05_004 | W05_005 | W05_006 | W05_007 | W05_008 | W05_009 | W05_010 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 860603 | 8606030000 | 4 | 繧ォ繧、隹キ | 4 | 1 | #gb03_2700942 | #gb03_2701226 | #gb03_2700942 | #gb03_2701226 |
1 | 860604 | 8606040044 | 2 | 蟆サ辟。蟾㤼㹤 | 3 | 1 | #gb03_2700011 | #gb03_2702076 | #gb03_2700008 | #gb03_2700032 |
2 | 860604 | 8606040044 | 2 | 蟆サ辟。蟾㤼㹤 | 3 | 1 | #gb03_2700011 | #gb03_2702076 | #gb03_2700032 | #gb03_2702076 |
3 | 270001 | 2700010002 | 4 | 隘ソ蟾㤼㹤 | 3 | 1 | #gb03_2701757 | #gb03_2701450 | #gb03_2701757 | #gb03_2701756 |
4 | 860604 | 8606040001 | 1 | 豺蟾㤼㹤 | 1 | 1 | #gb03_2701546 | #gb03_2700000 | #gb03_2701073 | #gb03_2700000 |
5 | 860604 | 8606040001 | 1 | 豺蟾㤼㹤 | 1 | 1 | #gb03_2701546 | #gb03_2700000 | #gb03_2701405 | #gb03_2701073 |
ここで、カラム名がW05_001
とかよく分からない文字列になっています。これがどういう意味かを調べるには、今のところAPIでは完結しなくて、各データの詳細ページを見る必要があります。たとえば、河川データであれば以下です。
順番的に、W05_003
が区間種別のようです。一級河川とか二級河川とか、そういう区分で見たければここでデータを分割するのがよさそうです。
それはそうと、Windowsで見るとW05_004
が文字化けしてるっぽく見えるので修正しておきます。これは文字化けしてるように見えるだけで、変換したりしなくてもEncoding()
を設定すれば終わりです。
l <- levels(river@data$W05_004) Encoding(l) <- "UTF-8" levels(river@data$W05_004) <- l knitr::kable(head(river@data))
W05_001 | W05_002 | W05_003 | W05_004 | W05_005 | W05_006 | W05_007 | W05_008 | W05_009 | W05_010 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 860603 | 8606030000 | 4 | カイ谷 | 4 | 1 | #gb03_2700942 | #gb03_2701226 | #gb03_2700942 | #gb03_2701226 |
1 | 860604 | 8606040044 | 2 | 尻無川 | 3 | 1 | #gb03_2700011 | #gb03_2702076 | #gb03_2700008 | #gb03_2700032 |
2 | 860604 | 8606040044 | 2 | 尻無川 | 3 | 1 | #gb03_2700011 | #gb03_2702076 | #gb03_2700032 | #gb03_2702076 |
3 | 270001 | 2700010002 | 4 | 西川 | 3 | 1 | #gb03_2701757 | #gb03_2701450 | #gb03_2701757 | #gb03_2701756 |
4 | 860604 | 8606040001 | 1 | 淀川 | 1 | 1 | #gb03_2701546 | #gb03_2700000 | #gb03_2701073 | #gb03_2700000 |
5 | 860604 | 8606040001 | 1 | 淀川 | 1 | 1 | #gb03_2701546 | #gb03_2700000 | #gb03_2701405 | #gb03_2701073 |
川の名前が出てきました。
ggplot2で河川をプロット
詳細は割愛しますが、ggplot2で地図を描くには以下の記事が参考になります。下の公式wikiの情報はやや古いです。
やることは、broom::tidy()
でriver
をdata.frameに変換して、元のriver@data
とマージするだけです。
library(broom) library(ggplot2) r <- tidy(river) river@data %>% add_rownames("id") %>% inner_join(r, by = "id") %>% { ggplot(., aes(long, lat, group = group, colour = W05_003)) + geom_line() + coord_quickmap() + facet_wrap(~W05_003) }
あんまり意味はないですが、等級別の河川のプロットが描けました。
まとめ
Rから国土数値情報ダウンロードサービス Web APIを使うパッケージをつくりました。使ってみて変なところがあれば、GithubのIssuesかTwitterあたりでお知らせいただけるとうれしいです。
では、明日からも引き続きFOSS4G Advent Calendarの記事をお楽しみください。次はuriさんです。