Webアプリを創る 😊クリエイティブWeb

カテゴリー: オープンデータ

市区町村コード表(履歴付)を作成する .NET Core アプリを公開しました

2017年2月20日

国勢調査等の市区町村別の統計データを過去から集計して比較しようとすると、平成の大合併により過去のデータは合併前の市町村のデータを集計する必要があり、普通に手作業ですると非常に手間のかかる作業になります。

政府統計の総合窓口(e-stat)の統計LODで、1970年以降の標標準地域コードのデータが公開されているので、それを利用して、任意の時点での市区町村コード表の作成や対応表が作成できるデータベースを作成するコンソールアプリケーションを作成しました。

.NET Core で作成したので、Windows だけでなく、Mac や Linux でも動作するし、.NET Core はインストールも手軽で簡単に動作させられるようになったので GitHub で公開してみました。URL は、以下のとおりです。

NAreaCode

このアプリを作っていて気がついた点を2点メモしておきます。

コマンドラインの解析

コマンドラインの解析には、Microsoft.Extensions.CommandLineUtils を使いました。CommandLineUtils は、.NET Core になってやっと組み込まれた機能です。

以前の Microsoft はエンタープライズ向けのことには熱心なのですがシンプルに処理をするということにはあまり力が入っていなかったように思っていましたが、.NET Core、ASP.NET Core になって、シンプルに作りたい場合にも使いやすくなったと思います。コマンドラインの解析は、簡単そうですが実際に自分で作るとなると結構手間がかかるので、.NET Core になって改善された典型的な例だと思います。

コード表の処理速度

作成した市区町村コードのデータは、json形式にしています。例えば、期間付き市区町村コードは以下のような形式になっていて、4588件のレコードがあります。

public class StandardAreaCode
{
    [JsonProperty("id")]
    public int Id { get; set; }
    public string 名称 { get; set; }
    public string ふりがな { get; set; }
    public string 英語名 { get; set; }
    public 自治体種別 種別 { get; set;}
    //北海道、東京都島嶼部、長崎県対馬(旧)は支庁・振興局、その他の町村は郡、区は政令指定都市のコード
    public int 所属 { get; set; }
    //北海道及び旧長崎県対馬支庁の町村のみ
    public string 郡名称 { get; set; }
    public string 郡ふりがな { get; set; }
    public DateTime 施行年月日 { get; set; }
    public DateTime 廃止年月日 { get; set; }
    public List<int> 施行データ { get; set; }
    public List<int> 廃止データ { get; set; }
}

これらのデータを Web アプリケーションの中で使う時に、RDB にインポートするのは面倒なので、メモリーベースで処理をするということで、処理時間を計測してみました。都道府県毎に市区町村コードの一覧を計算する処理で、画面の例は「北海道の市区町村コード一覧」です。また、一覧を計算するコードのメインは以下のようになっていて、LINQ を使うのであれば、リストや配列の場合でも SQL Server を使うのとほぼ同じコードで書くことができます。

public IEnumerable<(int id, string 名称, string ふりがな)> GetAreaCode(int pref, DateTime date) =>
    AreaCodeList
    .Where(x => x.Id / 1000 == pref && x.施行年月日 <= date && x.廃止年月日 > date && x.所属 != 99)
    .Select(x => (id: x.Id, 名称: x.名称, ふりがな: x.ふりがな))
    .OrderBy(x => x.id);

Google Compute Engine の n1-standard-2 (AWS の m4.large とほぼ同性能)を使って処理時間を計測すると以下のようになりました。

  • ファイルサイズ 1126KB
  • データの読み込み時間 45ms
  • 計算時間 0.4~0.008ms

結果としては、SQL Server Express を使うよりも遙かに早いです。計算時間の 0.4ミリ秒は初回の計算の時で計算ルーティンやデータが CPU のキャッシュメモリーに入っていない場合の処理時間です。計算の必要なコードとデータが CPU のキャッシュメモリにキャッシュされてしまえば 0.008ms という圧倒的な速さで処理がなされます。こういう処理ではデータのやりとりにばっかり時間を食っていて、本当の計算時間なんてごく僅かのものだなと感じます。

そういうことで、データー量がそれほど大きくないコード関係は RDB を使うのをやめてメモリーに乗せていこうと思っています。管理も、RDB で管理するよりも、テキストベースにして git で管理した方が遙かに管理しやすいし、入力もデータベース用の入力画面を使うよりも、テキストエディターや Excel で編集できた方が楽です。RDB をやめることの欠点ってといえば、コードを修正する毎にアプリをデプロイしなければいけないので、その手間が増えるのですが、昔と違って今はデプロイが楽になっているのでデータの更新の頻度ににもよりますがそれほどの負担にはならないと思います。

統計LODのバグから見える沖縄の歴史

2017年1月18日

統計LODの「統計に用いる標準地域コード」を使っていて面白いバグを見つけたのでメモしておきます。

沖縄県では、北部が本土に近いので国頭(くにがみ)郡で、南部はシマの尻となるので島尻郡です。それにもかかわらず、沖縄県の最も北に位置し東シナ海上に浮かぶ伊平屋村及び伊是名村は国頭郡ではなくて島尻郡に属しています。

伊平屋島は、琉球王朝の第一尚氏縁の地であり、伊是名島は、第二尚氏縁の地です。そのため琉球王朝の時代には直轄地だったという歴史があり、その後の経過を経て島尻郡に属するようになったようです。

具体的な統計 LOD のバグの内容ですが 検索用画面で以下の Query を実行してみてください。

PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
PREFIX org:<http://www.w3.org/ns/org#>
PREFIX dcterms:<http://purl.org/dc/terms/>
PREFIX sacs:<http://data.e-stat.go.jp/lod/terms/sacs#>
PREFIX sac:<http://data.e-stat.go.jp/lod/sac/>
PREFIX sace:<http://data.e-stat.go.jp/lod/sace/>
PREFIX sacr:<http://data.e-stat.go.jp/lod/sacr/>

SELECT ?p ?o WHERE { 
  sace:C394 ?p ?o .  
}

Output を Text にすると次のように検索結果が返されます。

-------------------------------------------------------------------------------------------------
| p                         | o                                                                 |
=============================================================================
| rdf:type                  | sacs:CodeChangeEvent                                              |
| org:resultingOrganization | sac:C47361-20020401                                               |
| org:resultingOrganization | sac:C47352-20020401                                               |
| org:resultingOrganization | sac:C47351-20020401                                               |
| dcterms:description       | "Nakazato-son(47351) and Gushikawa-son(47352) are merged, and Kumejima-cho(47361) in Shimajiri-gun is newly established."@en |
| dcterms:description       | "仲里村(47351)、具志川村(47352)が合併し、久米島町(47361)を新設"@ja|
| org:originalOrganization  | sac:C47352-20001222                                               |
| org:originalOrganization  | sac:C47361-19720607                                               |
| org:originalOrganization  | sac:C47351-20001222                                               |
| dcterms:identifier        | "394"                                                             |
| sacs:reasonForChange      | sacr:establishmentOfNewMunicipalityByMmerging                |
| dcterms:date              | "2002-04-01"^^<http://www.w3.org/2001/XMLSchema#date>       |
-------------------------------------------------------------------------------------------------

org:originalOrganization(変更前の期間つき標準地域コードのリソース)に、sac:C47361-19720607 があります。確かに 47361 は現在の久米島町の市町村コードではありますが、1972年には久米島町はなかったはずです。実は C47361-19720607 は、宮古郡城辺町(現宮古市)の昔の市町村コードです。47361 という市町村コードは使い回しされていたのです。

市町村コードは廃止されたコードは欠番とされ、新たなコードとして別の自治体に交付しないという原則に例外があったのです。恐らくそのことを知らないエンジニアが間違ったプログラムを書いたのですが、影響はあまりないのでそのままになっていると思います。

なぜこういうことが発生したのか、まず、1965年(昭和40年)の沖縄県の国勢調査の結果をみてみると、以下の図のように琉球政府の時代には郡は使わずに北部地区という名称を使っていたようです。

1965年の沖縄県の国勢調査のの画像

1970年(昭和45年)の沖縄県の国勢調査の結果をみると、復帰前ですが本土と同じように市町村コードが振られて郡が復活しています。その際に北部地区をそのまま国頭郡にしてしまったようです。

1970年の沖縄県の国勢調査のの画像

本土復帰後になって、伊平屋村及び伊是名村が島尻郡に属していることがわかり修正しようとしたのですが、運悪く島尻郡に属する町村が多すぎて伊是名村が47360というコードになり宮古郡のコードと衝突してしまったのです。それで宮古郡のコードを47370に変更し、宮古郡に属する町村のコードも変更せざるを得なくなったようです。そして、合併で久米島町ができたときに 47361 になり城辺町の昔のコードを使い回してしまったということのようです。

統計LODから取得した標準地域コードを利用して、統計メモ帳のページを追加中なので、完成したらそのページの方も紹介したいと思います。

5374 徳島市版を作ってわかった地域アプリの厳しさ

2015年9月1日

今日から9月です。約3ヶ月このWebサイトを更新するのに時間がかかっていたのでブログの更新ができていませんでした。最初に 5374 徳島市版のアクセス状況を書いてみます。

8月分のページビュー数は、73PVでした。うち5374 の本来の使い方である Direct が約半数の36PVで1日で1PVという感じで、アクセスは本当に少ない状況です。

自分でも5374徳島市版は使っていません。「ごみの日」を知る必要があるのは後片付けの時なので、手がぬれている場合が多いのでスマートフォンは使う気がしません。台所にごみカレンダーを貼っておいた方が便利だと思います。

金沢の成功事例である5374の本家版の利用者は、月間で4000人だそうです(出典:TheWave の 「強い想いが仲間と流れをよびよせた/Code for Kanazawa(前編)【鈴木まなみ】」)。

ecitizen.jp 全体だと8月のユーザー数は31000人なので、5374の本家版よりも8倍も多くなっています。

それで、ecitizen.jp の方が 5374の本家版より優れているというつもりはありません、5374の本家版は金沢市が対象なので46万人が対象になりますが、ecitizen.jp だと全国の市町村の人口のグラフを作っているので日本全国が対象になるので、対象人口が大きく違います。

Code for Kanazawa のように地域で活動するのも一つの方法ですが、それでうまくいかない場合に、あきらめずにもう少しグローバルに考えるという方法もあると言いたかったのです。

自作のAPIをオープンデータで公開しました

2015年5月27日

Xingle 氏が、ブログ「オープンデータ先進県「福井」の残念なデータに思う」で、次のようなことを書いていました。

2 年前このデータを見たとき、ついカッとなって上記のデータを良い感じの形式に変換する API を作ったりしました。が、公開を目前にして「どう考えても元々のデータを直すべきで、万が一にも自分の API を使ってアプリを作るような人が出ても困る」と我に返り、踏み留まりました。

「万が一にも自分の API を使ってアプリを作るような人が出ても困る」ということですが、なぜ困るのか疑問に感じていました。そもそもアプリを作る人がいないのであれば、県や市町村としてオープンデータとして公開するのは無駄な作業になるし、まして手間をかけて「元々のデータを直す」ことは税金の無駄遣いだと思います。

最近公開された徳島県のオープンデータポータルサイト(Our Open Data)では、個人でもデータカタログに登録できるようになっています。そこで、APIを作ってデータカタログに登録して公開することにしてみました。公開しているAPIは、徳島県県土防災情報システムの道路気象、雨量、水位のデータを加工したもので、以下の2種類の API です。

徳島の気温、雨量、水位 GeoJSON

徳島の気温、風速、風向、雨量の10分データ

下の図がそのAPIを使って作成したサンプルです。

image

このAPIの作成に要した日数は6日間です。時系列データを作ったり時間雨量の計算をしたりする方に時間がかかっているので、APIの作成だけであれば3日でできると思います。今後、このAPIを使ったアプリを作ろうと思っているのですが、アプリの作成には10日以上かかると思います。それで今すぐに作るのは、かなり負担になるので将来 d3.js でグラフを描く機会に作成しようと思っています。

今回のAPIの作成の開発費がどうなるかというと、人件費を考慮すると日当5万円で30万円です。でも、自分でやっているので、自分の人件費を除いて計算すると電気代とパソコンの消耗費ぐらいでほぼゼロに近いと思います。

今後の運営経費に関して計算してみると、今回の公開には Amazon の S3 を使っています。単価は、1000回のGETのリクエスト使用料が$0.0037、ネットワークの下り側の使用料金が1GBで$0.14となっています。APIのファイルサイズで一番大きいのは雨量データで32KBです。1000PV当たりで計算すると、リクエスト使用料が$0.0037、ネットワークの使用量が32MBなので料金が$0.0045になります、合計で$0.0082で1ドルを120円とすれば約1円です。S3ではなく普通のサーバーを使っても同じようなものだと思います。公開以外に、データの処理コストが必要になります。今回のAPIの処理は10分毎の処理で処理時間は2.5秒なので、サーバーに少し負荷がかかるので無料ということはないですが月何百円の単位だと思います。こうして計算してみると運営経費は本当に僅かな額です。

次に収益の方ですが、現状では収益は見込めないです。もし、Webアプリを作った場合どうなるかというと、広告収入は可能だと思います。イケダハヤト氏がブログで収入を公開していますが、今年の4月分だと129万PVで、バナー、記事広告アフィリエイトで59万円なので、1000PV当たり457円ということになります。自分のWebサイトの場合は Google アドセンスしか貼っていないのでそれよりは低いですがそれでも半分以上の単価になっています。地域限定で日常的に使うアプリの場合、スポンサーは結構取りやすいと思うので457円の単価は難しくないと思います。

しかし、地域対象のアプリで問題なのはアクセス数を稼ぐのが非常に難しいということです。徳島県の場合人口が76万人しかいないので100万PVというのは夢のまた夢です。それに、アプリを作るのに10日とか書ましたが一人で作ってかつ業務の内容も分かっているからできる話であって、普通に開発会社が開発するのであればフロントエンドのエンジニア、サーバー側エンジニア、Webデザイナー等3~4人でチームを組んで、ヒアリング等も必要になってくると思います。そうなれば数百万円のコストが必要になってくるので、自治体から委託料をもらわずに自社開発するのは無理だと思います。

それだったらなぜ「オープンデータ」という話になるかというと、stackoverflowの調査だと、開発者の70%が週に2時間以上趣味やオープンソースの開発でプログラミングをしており、週10時間以上している人も20%います。そういう開発者の力を活用しようというのがオープンデータです。確かに、今回のAPIの作成はテストにも使っているので、自分としてもさほど負担には感じていないです。また、オープンデータはアプリのプロトタイプをテストするのには便利だと思っています。

海外ではソフトウェア開発者は比較的給料もよくて恵まれている職種なのでOSSの開発をする余裕がある人が多いと思います。日本では、そういう開発者の層は薄いので、オープンデータの活用が本当に進むかどうか不透明な部分がありますが、日本でもOSSの開発経験がエンジニアの採用時に実績として重視されたり、GitHub がポートフォリオになるような時代になっていくと思うので、将来的には海外と同じようになると思います。

また、日本ではXingle氏のように行政がきちんとしたデータを提供すべきだと考える人が多いと思います。確かに、XMLやRDF等で提供されていれば形式を勝手に変更されることがないだろうという安心感があります。一方Excelで作ったデータであれば、自治体の職員がすぐに様式を変更できるので、その対応を考えておかないといけないのが結構煩わしいと思います。

でも逆にいえば、XMLやRDFの場合、修正の必要が生じたときに自治体としてすぐに対応できるのかということがあります。また、経費や手間をかけてXMLやRDFで提供している場合、利用者が少ない場合でも提供を継続してくれるのかという不安もあります。現実に日本のオープンデータで最も規模の大きいものの一つである「政府統計のAPI機能」で、総務省以外の省庁の統計データは更新がほとんどされていません。恐らく各省庁は別のシステムで統計を作っていて、政府統計のシステムにデータを手入力するのはあまりにも手間がかかるし、一方でシステム化をするにはコストが必要ですがそのコストの説明ができないため、従来通りExcel形式での公開ということになっているのではないかと思います。

そういうことを考えれば、自治体ではできるだけ手間をかけずに内部で使っているデータをそのまま公開した方がいいと思います。そして、エンジニアの方が便利なAPIを作ったら、「万が一にも」とか言わずにどんどん公開したらいいと思います。公開するための経費はほとんど必要ないし、オープンデータを使ってアプリを作るということは自己責任で作るということなので、APIの提供者は運用についてあまり気にする必要はないと思います。それに、個人が開発したAPIを使うことに対するアプリ開発者側の不安は、APIの作成ルーチンをOSSで公開することではかなり緩和されると思います。そういうことで今回のAPIを作成するプログラムは、GitHubで公開しています。長くなったのでAPIの作成の話は次回にします。

5374 徳島市版を作成してみました

2015年5月17日

Windows 10 Insider Preview と Visual Studio 2015 RC のテストを兼ねて、Code for Kanazawa が作った「いつ、どのゴミが収集されているのか」をわかるWebアプリ 5374.jp の徳島市版を作ってみました。

Windows 10 も VS 2015 も自分の使った限りでは、エラーが発生することなく使えています。今年の夏に発売予定ですが、準備の方は順調に進んでいるようです。VS 2015 で、ASP.NET 5 については、あまり使っていませんが、ASP.NET 4.6 では製品版といってもいい状況で、実際の運用環境で使ってもいいという "Go-Live" ライセンスになっているというのもうなづけます。

5374.jp については、徳島市の場合は隔週及び4週毎のごみの収集があるのに、それに対応していないため、カスタマイズをしてみました。詳しくは、GitHub の方に記載しています。

徳島市版を作成した理由の一つには、JavaScript をどこまで使うのがいいのかということに対するテストという意味合いもあります。結局は、JavaScriptにどれぐらい慣れているのかということが一番大きな要素になると思いますが、自分の場合はロジックについてはC#で書いた方が楽です。JavaScript は一般的には手軽なのですが、Date を使うのは結構ややこしいです。自分の場合は、メンテナンスまで考えると今までどおり JavaScript は、UI 部分だけで使った方がいいと思いました。

5374.jp の場合、収集日を通知してくれる機能が欲しいと思うので、Cordova で作るのがいいのか、Xamarin で作るのがいいのか試してみたいと思っています。1月にアプリを作りかけたときは、表示の項目数が多かったので、Xamarin.Forms ではレイアウトの処理に時間が掛かりすぎました。5374.jp の場合は、それと比較するとかなり簡素なので Xamarin.Forms でも余り問題がないと思うので、比較するのには丁度いいと思っています。