【追記あり】sfパッケージでシェープファイルを読み込んでmapviewパッケージで可視化するまで

お久しぶりです。 位置情報データ分析をやっていくことになりました。 素人なので備忘録を書いていきます。 GISを使えませんが、Rなら少々できますので、限界が来るまでRでチャレンジしてみます。 周りにRで位置情報分析をする人がいない環境なので、ツッコミを欲しています。 何卒よろしくお願いいたします。


今日の環境はMacです。

まず、位置情報データを入手し、可視化することにチャレンジしてみます。 今回のお題は地域メッシュです。とにかくシェープファイルを入手することからスタートです。 位置情報系のデータは、国土数値情報ダウンロードサービスに多くのデータがあるので、今回もこちらを使用します。下記URLです。

国土数値情報 土地利用3次メッシュデータの詳細

全国分をダウンロードすると容量が大変なことになりそうなので、東京都のデータだけにしておきます。 zipを展開して任意の位置に配置します。

シェープファイルの取り扱いには sf パッケージを使用するのが 2017年現在ナウいようです。詳しくは いつもお世話になっている @yutannihilation さんの下記ブログをご参照ください。

notchained.hatenablog.com

では、まずはシェープファイルを読み込みます。

> library(sf)
> d1 <- sf::read_sf("./Downloads/L03-a-14_5339-tky_GML/L03-a-14_5339-tky.shp")
 make.names(vnames, unique = TRUE) でエラー: 
   '<83><81><83>b<83>V<83><85>' に不正なマルチバイト文字があります 
 wrapup 中にエラーが起こりました:  '<83><81><83>b<83>V<83><85>' に不正なマルチバイト文字があります 

怒られました。

sfパッケージにおけるマルチバイト文字を含むシェープファイルを読み込む方法が結局わからなかった*1ので、今回は従来の方法のひとつである rgdal パッケージで読み込んでから sf パッケージで使えるクラスに変換する方針でやっていきましょう。

> library(rgdal)
> d1 <- rgdal::readOGR("./Downloads/L03-a-14_5339-tky_GML/L03-a-14_5339-tky.shp", encoding = "Shift_JIS") %>%
+   sf::st_as_sf() # Convert to an sf object
OGR data source with driver: ESRI Shapefile 
Source: "./Downloads/L03-a-14_5339-tky_GML/L03-a-14_5339-tky.shp", layer: "L03-a-14_5339-tky"
with 6300 features
It has 13 fields
Integer64 fields read as strings:  田 他農用地 森林 荒地 建物用地 道路 鉄道 他用地 河川湖沼 海浜 海水域 ゴルフ場 
> d1 %>% head
Simple feature collection with 6 features and 13 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 139 ymin: 35.33333 xmax: 139.075 ymax: 35.34167
epsg (SRID):    NA
proj4string:    +proj=longlat +ellps=bessel +no_defs
  メッシュ    田 他農用地    森林   荒地 建物用地 道路 鉄道 他用地 河川湖沼 海浜 海水域 ゴルフ場
0 53390000     0        0 1050436      0        0    0    0      0        0    0      0        0
1 53390001     0        0  976895      0        0    0    0      0        0    0      0    73530
2 53390002     0        0  808820 241595        0    0    0      0        0    0      0        0
3 53390003     0        0 1050404      0        0    0    0      0        0    0      0        0
4 53390004     0        0 1039890      0    10504    0    0      0        0    0      0        0
5 53390005 42015   136550  829804  21008        0    0    0  21007        0    0      0        0
                        geometry
0 POLYGON((139 35.33333333333...
1 POLYGON((139.0125 35.333333...
2 POLYGON((139.025 35.3333333...
3 POLYGON((139.0375 35.333333...
4 POLYGON((139.05 35.33333333...
5 POLYGON((139.0625 35.333333...

いい感じです。


【追記01: 2017/06/27 20時】

コメントにてsfパッケージで読み込む方法を教えていただきました。 Macでもマルチバイト文字がきちんと表示されていました。 id:aaaazzzz036 さん、ありがとうございます。

d1 <- sf::st_read("./Downloads/L03-a-14_5339-tky_GML/L03-a-14_5339-tky.shp", options=c("ENCODING=CP932"))

【追記02: 2017/06/29 11時】

sf::read_sf 関数でも同じオプションでOKです。

d1 <- sf::read_sf("./Downloads/L03-a-14_5339-tky_GML/L03-a-14_5339-tky.shp", options=c("ENCODING=CP932"))

では、可視化してみましょう。

位置情報データの可視化には mapview パッケージを使ってみます。 今後の目標としては sfmapview をある程度使えるようになりたい というものがあります。

今回はお試しなので、新宿近辺の4メッシュほどを可視化してみましょう。

> library(mapview)
> library(dplyr)
> d1 %>% 
+   dplyr::filter(メッシュ %in% c(53394525, 53394526, 53394535, 53394536)) %>% 
+   mapview::mapview()

f:id:ksmzn:20170627145320p:plain

こちらもいい感じです。左のボタンからOpenStreetMapに切り替えると見やすいですね。

今の例のように、sf パッケージも mapview パッケージも、tidyverse系ライブラリと組み合わせて使えるのが便利すぎます。

今後も少しずつ sf パッケージと mapview パッケージをやっていきます。

SFが読みたい! 2017年版

SFが読みたい! 2017年版

*1:ご存知のお方は、教えていただけると幸いです…

ちょくちょくDjangoを触っている && 構成などメモ

6月くらいからちょくちょくDjangoでWebサイトを作っているので、 詰まったところとかハマったところをメモしていこうと思う。 Python3.4 + Django1.8 で構成している。

ディレクトリ構成について

ざっくりと、こんな感じ。

├── django_project
│   ├── manage.py
│   ├── pytest.ini
│   ├── django_project
│   ├── appA
│   ├── appB
│   └── templates
├── requirements.txt
├── reqs
│   ├── common.txt
│   ├── dev.txt
│   └── prod.txt
├── Dockerfile
├── docker-compose.yml
└── run_web.sh

こちら、参考にしたのは以下のページや書籍である。

上のページは、ありがたいことにディレクトリ構成以外にも詳しく述べられており、大変参考になった。 Two Scoops of Djangoはちょうど1.8版が出ていたので、購入してみた。

Docker-composeを試している。 今のところのdocker-compose.ymlはこのような感じ。 開発しながら、nginxやredisを追加する予定

storage:
  image: busybox
  volumes:
    - /var/lib/postgresql/data
    - /data
  command: "true"

db:
  image: postgres
  volumes_from:
    - storage

web:
  build: .
  command: ./run_web.sh
  volumes:
    - /vagrant:/code
  ports:
    - "80:8080"
  links:
    - db
  volumes_from:
    - storage

run_web.shにはmigration関連のコマンドとrunserverのコマンドが書いてある。gunicornやらを導入する際には書き換える。

その他メモる予定の事柄

  • py.testについて
    テストにはpy.testを用いる。python標準のunittestしか使ったことがないので、練習も兼ねている。
  • jinja2 について テンプレートエンジンにはJinja2を用いる。Django1.8からは標準でJinja2を選べるようになったが、設定でいろいろ困ることになったので、結局1.7以前のようにdjango-jinjaパッケージを用いた。
  • CIについて wercker か drone を用いるので、それについても書く。droneは試したが、CIサービスを使うほうがラクかもしれない。
  • CSS, JSについて 直接Djangoとは関係がないが、メモは残そうと思う。
  • Git 運用について こちらも直接Djangoとは関係がないが、メモは残そうと思う。

Dockerを使ってDigitalOceanにShinyアプリを公開する

こんにちは。冷やし中華を今年になって3回食べているのですが、友人は4回食べたそうです。

先日作成した「確率分布を動かして遊ぶShinyアプリ」ですが、 おかげさまでけっこうな数のかたに見ていただいているようです。 たいへん嬉しいのですが、ShinyApps.ioに公開しているため、 すぐに「THIS APPLICATION IS CURRENTLY UNAVAILABLE」となってしまいます。

せっかく紹介していただける機会も多いので、このたびDigitalOceanで公開することにいたしました。 こちらです↓

http://statdist.ksmzn.com/

前のURLでも見られるようにしておくつもりなので、 今後はお好きな方をごらんください。

ここからが本題です。 公開するにあたり、勉強がてらDockerを使ってみました。 ここでは、その作業手順を記しておきます。

DigitalOceanでサーバ作成

これに関してはメインではないので触れません。 僕はこちらのブログを参考にしました。

さくらのVPSからDigitalOceanへ移転

大事なのは、 Docker入りImage を選択することですね。

ちなみに、こちらのリンクからサインアップしていただけると お互いにメリットがあります。 https://www.digitalocean.com/?refcode=6dbd71c2251f

スワップを増やす

ワナがあります。このままの状態だと、メモリ不足でパッケージがインストールできないという事態に陥ります。 なので、こちらの記事を上から実行し、Ubuntuスワップ領域を増やしましょう。

How To Add Swap on Ubuntu 12.04 https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-12-04

Shiny用コンテナの作成

Dockerfileの作成

もうShinyアプリは完成している前提とします。

ありがたいことに、ShinyServerがインストール済のDockerイメージが公開されているので、 そちらを使わせていただきましょう。 https://registry.hub.docker.com/u/rocker/shiny/
↑のGithubリポジトリ

上記のrocker/shinyイメージだけでもShinyは動かせるのですが、 このイメージはRのパッケージが「Shiny」「rmarkdown」しかインストールされていません。

なので、rocker/shinyイメージをもとに、 自分のアプリに合わせたDockerfileを作成しましょう。

私のDockerfileは以下のようになっています。

FROM rocker/shiny:latest

RUN R -e "install.packages(c('shinydashboard', 'hypergeo'), repos='http://cran.rstudio.com/')"

COPY  /ShinyDistributionsApp/ /srv/shiny-server/

CMD exec shiny-server >> /var/log/shiny-server.log 2>&1

FROM 句でrocker/shinyを指定し、

RUN句で僕のアプリに必要な'shinydashboard'と'hypergeo'パッケージをインストールしています。 そして、COPY句でShinyアプリのソースをコピーし、CMD句でshinyを実行しています。単純ですね。

ビルド、そして実行

Dockerfileができたらビルドします。

DegitalOcean内にログインし、適当な名前をつけてビルド。

sudo docker build -t yourname/shiny-yourapp:latest .

初回は時間がかかります。 ビルドが完了したら、-d オプションをつけ、バックグラウンドで実行します。 rocker/shinyは、デフォルトでは3838ポートをEXPOSEしているようです。

sudo docker run -d -p 80:3838 yourname/shiny-yourapp:latest

これでバックグラウンドで実行されているので、 自分のドメインIPアドレスをブラウザに入力してみましょう。 アプリが動いているはずです。

ちなみに、大量アクセスが来た場合のことを何も考えていません。 おそらく、こちらのスライドのような対処が必要となることでしょう。

このスライドにおける方法①を試す場合、 Docker-Composeを使ってShinyとNginxのコンテナを立てることで実現可能ではないかと目論んでいます。 時期がきたら試してみます。

以上です。えんじょい。

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)