Webアプリを創る

Intel D510MO + AOpen S110 自宅サーバー ハードディスクが故障

2014年2月9日

2010年4月から使ってきた自宅サーバーが起動しなくなった。ハードディスクの故障と思われるけど、HDDは、2.5インチ SATA 250GB HTS545025B9A300 なので、24時間稼働で4年近くも故障せずによく動いてくれたと思っている。Intel NUC D54250WYK を購入して自宅サーバーを立ち上げたばかりなので、しばらくは Intel NUC の方だけで作業しようと思っている。Intel NUC の方は今のところ快調に動作しているし、データも基本的にはそちらに移していたので故障してもあまり問題はなかったのはよかった。故障した Intel D510MO の自宅サーバーは、しばらくして時間ができたらハードディスクの交換をしてみようと思っている。

Web アプリをスマフォのホーム画面に登録してもらうためのメモ 1

2014年2月6日

Web アプリでもネイティブアプリのように iPhone や Android のホーム画面に登録できるし、オフラインで動作させることもできるということなので、実際にやってみて、まとめてみました。

まず、一番最初に準備するのがホーム画面に登録するためのアイコンで、そのサイズは以下のとおりです。

  • iPhone (iOS7) 120px × 120px
  • iPhone(iPhone 4以降でiOS6まで)114px × 114px
  • iPhone(iPhone 3 まで)57px × 57px
  • iPad (iOS7)152px × 152px 
  • iPad (iOS6までのRetina)144px × 144px
  • iPad (iOS6までの普通)72px × 72px
  • Android 48dp × 48dp

Android の場合は、Developers の Iconography をみると1x、1.5x、2x、3x、4x の機種があるので、48px, 72px, 96px, 144px, 192px のものになりますが、4x の XXXHDPi の機種は現実にはまだ殆ど存在しないはずで、3x と 2x が主流です。

これだけたくさんの解像度のアイコンを作るのは大変なので、取りあえずは152pxのアイコンを作っておけば、スマートフォン側で自動的に縮小、拡大してくれるので、それで対応することにしました。

作成したアイコンを表示させるためには、iPhone の場合は、それをPNG画像にして apple-touch-icon.png というファイル名でサイトのルートディレクトリに置いておけばいいだけです。apple-touch-icon-precomposed.png という名前で保存してもいいのですが、この場合は iPhone が自動でハイライト/シャドウを付けなくなります。iOS7からはフラットデザインになってiOS6以前のようなハイライト/シャドウはなくなったので、apple-touch-icon-precomposed.png を使う意味はあまりないと思います。

サイズを複数設置する場合は以下のようにアイコンのサイズを指定して設置すると、iPhone側で自動的に適当なサイズのものを選択してくれます。

apple-touch-icon-120x120.png

Android の場合は、ファイルを設置しただけでは認識してくれないので、以下のように link ダグで指定してやります。この指定の方法は、iOSの場合と同じです。

<link rel="apple-touch-icon" href="apple-touch-icon.png">

アイコンのサイズを指定したい場合は、以下のように sizes プロパティで指定することができます。この指定の方法も、iOSの場合と同じです。

<link rel="apple-touch-icon-precomposed" sizes="120x120" href="apple-touch-icon-120x120.png">

以上で、スマートフォンのホーム画面にアイコンを貼り付けることができるようになります。スマートフォン側でホーム画面にアイコンを貼り付ける操作をどうするかについては省略します。

Safari のスタンドアローンモード(フルスクリーンモード)について

Safari では、スタンドアローンモード(フルスクリーンモード、Webアプリモード)と呼ばれているモードがあります。このモードに設定して、ホーム画面から起動するとURLバーが無くなってネイティブアプリに近くなります。

設定は、metaタグを使って以下のようにします。

<meta name="apple-mobile-web-app-capable" content="yes" />

また、以下の設定をすると下側にある Safari のステイタスバーの色を自分のアプリの色に合わせて変更することができます。

<meta name="apple-mobile-web-app-status-bar-style" content="black">

しかし、このモードを実際に使ってみて、注意が必要だと思われる点がありました。具体的には以下のとおりです。

1. localStorage が mobile Safari とは別になってしまう。

mobile Safari で設定した内容が使えなくなるので、結構不便だと思いました。

2. 普通のリンクだと mobile Safari が起動してしまう

普通にリンクすると mobile Safari が起動して、mobile Safari の該当のページが表示されます。だから、最早スタンドアローンモードはなくなってしまって、簡単に戻ることもできなくなります。これを防ぐためには、リンクをページ内リンクにするか、JavaScript での移動にします。

下の参考に記載した stackoverflow の Q&A によると下のようなスクリプトを書いてやればいいようです。

var a=document.getElementsByTagName("a");
for(var i=0;i<a.length;i++)
{
a[i].onclick=function()
{
window.location='this.getAttribute("href");
return false
}
}

http://d.hatena.ne.jp/izit_kosuke/20110219/1298073430

http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window

3. 処理速度が遅くなる

スタンドアローンモードにすると、どうも起動時間が遅くなるように感じます。stackoverflow の Q&A にもあって、セキュリティの関係で Nitro という高速のJavaScriptエンジンが使えなくなるためのようです。

http://stackoverflow.com/questions/13413984/slow-initial-loadingscreen-ios-web-app

Android の場合にどうなるかを Nexus 5 で試してみました。Nexus 5 の場合は、localStorage は同じものを使います。普通のリンクにしておいてもモードが変わることはありません。その代わり、普通のリンクでは外部リンクであっても全画面表示のままになってしまいます。そして、ホーム画面のアイコンから立ち上げた場合、登録したページが表示されるのではなく、直近に表示されていたページがそのまま表示されます。

スタンドアローンモードを使うと見かけはアプリらしくなるのですが、採用するのがいいのかどうかは結構微妙です。localStorage が mobile Safari とは別になってしまうというのは、利用者にとっては結構戸惑うと思います。自分の場合は、アプリとしての完成度が低いので、当面はスタンドアローンモードを使わないことにしました。

次回は、Web アプリをオフラインで動作させることに挑戦したいと思っています。

Haswell版Core i5を搭載したIntel NUC D54250WYK を自宅サーバーにしました

2014年2月3日

NUC の本命といわれている Haswell版Core i5 4250U を搭載した Intel NUC D54250WYK を購入して自宅サーバーにしました。Haswell版CPUは低消費電力で発熱を押さえることができるので小さな筐体のNUCでも問題は少ないのではないかと思って購入しました。

どの程度の期間故障せずに使えるかは運の要素が強いのですが、2010年4月に購入した Intel D510MO+ケースAOpen S110 の自宅サーバーは3年半を経過しても利用できています。このことからNUCもある程度の実用性はあると思っています。

自宅サーバーの D54250WYK の構成は以下の通りです。

本体 D54250WYB 46,980円
mSATA SSD 240GB プレクスター PX-256M5M 22,980円
メモリー 8GB Kingston DDR3-1600 SODIMM 1.35V  8,655円
FILCO 直角ケーブル3号 482円
PLANEX Mini Displayport - DVI端子変換アダプタ 1,318円
Microsoft Windows 8.1 Pro (DSP版) 64bit 15,981円

メモリーはノート用で、1.35V のものしか動作しないので注意が必要です。また、ディスプレイへの接続は、miniHDMI と miniDisplayPort の端子が装備されているので、Mac用の変換ケーブルを購入しました。

合計で96,396円でした。結構な値段になりますが、Mac Book Air 及び Surface Pro 2 とほぼ同じスペックで、ディスプレイがない分やや安価になっているので、まあ妥当な価格だと思っています。実際のところ、安価なノートパソコンよりはずっと早く動作します。

性能がどれぐらい向上しているかということで cpuboss を見てみると、PassMark スコアで旧の D510 の約5倍早くなっています。

写真の上側が D54250WYK で、下側が 2010年4月に購入した Intel D510MO+AOpen S110 ケースのものです。写真を見るとD54250WYK の小ささがよく分かると思います。

IntelNuc 

Webサーバーについては、Windows Azure と AWS にすべて移したため、自宅サーバーは、現在はWebサーバーとしては利用していません。しかし、次世代統計利用システムの統計データAPIのようなオープンデータを利用する場合、処理が複雑で非常に重くなるものがあります。そういう処理を自宅サーバーでさせようと思っています。D54250WYK であれば、自宅でも 10台ぐらい動作させても消費電力や設置場所の問題はありません。そういう意味では、個人でもものすごい計算能力が簡単に使える時代になったなと実感します。

なお、D54250WYK は、実際には11月末に購入して、12月の中旬には動作させていたのですが、忙しくてメモをするのが遅れてしまいました。また、D54250WYK は結構人気で品薄のようです。

 

Linked Open Data を使って自治体コード表を作ってみた

2014年1月28日

前回のブログでは、次世代統計利用システムで都道府県・市区町村コード情報が LOD(Linked Open Data)で提供されるようになったので、実際に使ってみてその使い方をメモした。今回は、その LOD を使って、実際に自治体コード表(地方公共団体コード表)を作ってみた。(公開している場所 http://ecitizen.jp/sac

自治体コード表をLODを使って作ってみて感じたことは、LODはプログラマーにとっては確かに便利だと思う。でも、現在の政府統計窓口では、市町村コード表や廃置分合等情報がダウンロードできるようになっている。それを使ってプログラムする場合とLODを使ってプログラムをする場合の差はあまりないと思う。結局は、LODを使ってもデータの内容を把握しないとプログラムはつくれない。オープンデータの5つ星がいわれているが、自分の経験からいえば、星が0と1の間はものすごく大きいが、星1つと星5つの差はそれと比べるとかなり小さく、星5つというよりは星1.5だというのが正直な感想である。

以下は具体的にどうしたかをメモしておく。まず、自治体コード表を作るため、前回作成した埼玉県の市町村一覧を選択するクエリーを変更して、SELECT に「ふりがな表記」と「自治体コードの6桁目であるチェックディジットコード」を追加し、FILTERに「特別区」及び「政令指定都市の区」を追加して表示されるようにした。変更後のクエリーは以下のとおりである。

SELECT ?s ?name ?kana ?cd WHERE { 
  GRAPH ?g { ?s ?p ?o .
    ?s rdf:type sacs:CurrentStandardAreaCode.
    {{
      ?o dcterms:isPartOf sac:C11000-19700401.
    }UNION{
      ?o dcterms:isPartOf ?district.
      ?district dcterms:isPartOf sac:C11000-19700401.
    }}
    ?o sacs:administrativeClass ?ad.
    ?o rdfs:label ?name.
    ?o rdfs:label ?kana.
    ?o sacs:checkDigit ?cd.
  }
  FILTER( lang(?name) = "ja")
FILTER( lang(?kana) = "ja-hrkt") FILTER(?ad = sacs:DesignatedCity || ?ad = sacs:CoreCity || ?ad = sacs:SpecialCity || ?ad = sacs:SpecialWard || ?ad = sacs:Ward || ?ad = sacs:City || ?ad = sacs:Town || ?ad = sacs:Village) }

そのクエリーをベースにして、JavaScript を使ってWebブラウザーで自治体コードが表示されるようにしてみた。期限付きの都道府県コードは、CXX000-19700401で調べた範囲ではすべての都道府県が大丈夫のようだ。沖縄県の場合は1970年4月1日現在では琉球政府の時代で日本復帰は1972年5月15日であるが、C47000-19700401 となっていた。なお、沖縄県にある市町村の方の期限付き標準地域コードは1972年5月15日以降の分しかない。

このクエリーを処理する JavaScript のルーティンを書くことはそれほど難しいことはない。注意する点は、ブラウザーでの処理には、クロスドメインの制限があるということである。そのため、使うプロトコルは JSONP になるので、データとして jsonp/callback を送信する必要がある。また、その値がコールバックルーティンの名前なので、jQuery の場合であれば jsonpCallback にその名前を設定してやる必要がある。

なお、ソートは本来はクエリー側ですべきで、ORDER BY ?s をクエリーの最後につけてやればコード順のソートが出来るはずなのだが、理由はよくわからないが動作させられなかったので、JavaScript 側の方でソートをしている。

function makeTable(sacQuery){
  $.ajax({  
        url: http://statdb.nstac.go.jp/lod/sparql?,
        data: {
            query: sacQuery,
            output: "json",
            jsonp: "sacsac"
        },
        jsonpCallback: 'sacsac',
        dataType: "jsonp"
    })
    .done(function (data) {
        var mn = data.results.bindings;
        mn.sort(function (a, b) {
            if (a.s.value < b.s.value)
                return -1
            else
                return 1;
        });
        var html = "<table class=\"sactable\">";
        html += "<tr><th>団体コード</th><th>団体名</th><th>ふりがな</th></tr>";
        for (var n = 0; n < mn.length; n++) {
            html += "<tr><td>" + mn[n].s.value.substring(mn[n].s.value.length - 5) + mn[n].cd.value + "</td><td>" +
mn[n].name.value + "</td><td>" + mn[n].kana.value + "</td></tr>";
        }
        html += "</table>";
        return html;
    });
}

これで動作させてみると、下の図のように政令指定都市の区が二重になった。なぜか調べると、政令指定都市の区は dcterms:isPartOf で複数の期限付きの政令指定都市のコードを持つ場合があるということのためのようだ。

image

それで、期限付きの政令指定都市コードのうち現在の政令指定都市コードを選択してやらないといけないということで、ここでは、少し処理を簡単にするため、廃止年月日のない政令指定都市コードを選択することにした。

SPARQL 1.1 だと、dcterms:valid 値がないレコードを取得するののは NOT EXISTS を使えば簡単に記述できるが、NOT EXISTS は動作しなかった。それで、以下のように SPARQL 1.0 で記述してみると動作した。

SELECT ?s ?name ?kana ?cd WHERE { 
  GRAPH ?g { ?s ?p ?o .
    ?s rdf:type sacs:CurrentStandardAreaCode.
    {{
      ?o dcterms:isPartOf sac:C11000-19700401.
    }UNION{
      ?o dcterms:isPartOf ?district.
      ?district dcterms:isPartOf sac:C11000-19700401.
      OPTIONAL {?district dcterms:valid ?valid.}
    }}
    ?o sacs:administrativeClass ?ad.
    ?o rdfs:label ?name.
?o rdfs:label ?kana. ?o sacs:checkDigit ?cd.
}
FILTER( lang(?name) = "ja")
FILTER( lang(?kana) = "ja-hrkt") FILTER(?ad = sacs:DesignatedCity || ?ad = sacs:CoreCity || ?ad = sacs:SpecialCity || ?ad = sacs:SpecialWard || ?ad = sacs:Ward || ?ad = sacs:City || ?ad = sacs:Town || ?ad = sacs:Village)
FILTER (!BOUND(?valid))
}

次世代統計利用システムの都道府県・市区町村コード情報は、SPARQL 1.0 で動作しているように思われる。これから使うシステムなので、NOT EXISTS や MINUS が使える SPARQL 1.1 で動作させて欲しいと思う。

今回作った Webページは、統計メモ帳の以下にアドレスに公開しておきます。

http://ecitizen.jp/sac

もう少し手間をかければ、e-stat の「標準地域コードを探す」というページに近いものが作れると思っている。しかし、レスポンスや次世代統計利用システムのサーバー側の負荷を考えると、SPARQL を直接使うのはどうかなと思っていて、自分のサーバーで、データのキャッシュ等をして負荷の軽減をすべきだと思っている。それで、次はサーバー側での SPARQL の処理を試してみようと思っている。C#には、dotNetRDF というオープンスースの RDF 関連のライブラリーもあるので、そのライブラリーも試してみたいと思っている。

市区町村コード情報がLODで公開されたので使ってみた

2014年1月25日

次世代統計利用システムで、都道府県・市区町村コード情報が LOD(Linked Open Data)で提供されるようになったので使ってみた。使い方を少しメモしておく。

まず、SPARQLエンドポイントが用意されているので、そのページに行くと下の図のように画面でも検索できるようになっているので、この画面でSPARQLを試してみた。

image

?s ?p ?o というのは、?s(Subject 主語)、?p(Property 述語)、?o(Object 目的語)で、tuple ステートメントというようです。そのままで、Show results inline: にチェックをして、「Send Query」ボタンをクリックすると以下のように情報が表示される。

image

次に市区町村コードから市町村名等が表示されるか試してみた。?s を埼玉県川越市の市区町村コード11201に以下のように置き換えてクエリーしてみた。なお、sac:C11201は、<http://statdb.nstac.go.jp/lod/sac/C11201>の省略形であり、Prefex が登録されているので簡単に記述可能である。sac:C11201 の代わりに、<http://statdb.nstac.go.jp/lod/sac/C11201>と入力しても同じ結果になる。

SELECT * WHERE { 
  GRAPH ?g { sac:C11201 ?p ?o . }
}

クエリーの結果は、プロパティとしては、rdf:type と owl:sameAs のみを持つていて、owl:sameAs プロパティの結果として期間付き標準地域コード sac:C11201-20030401 が返されるだけで、市町村名等は取得できない。ここで取得した期間付き標準地域コードのプロパティを取得する必要がある。そこでクエリーを次のように変更して実行してみた。

SELECT * WHERE { 
  GRAPH ?g { sac:C11201 ?p ?o . ?o ?a ?b. }
}

こうするとマニュアルにある期限付き標準地域コード・クラスのプリパティの一覧が表示され、その中に川越市という名前も表示される。プロパティのうち、dcterms:valid は廃止年月日のプロパティなので、現時点では値がない。その場合には、RDBのようにNULLとかが表示されるのではなく、プロパティには何も表示されない。それでは市町村名だけを表示するのはどうしたらいいかというとプロパティを以下のように市町村の日本語表記である rdfs:label@js 等に指定すればよい。

SELECT ?b WHERE { 
  GRAPH ?g { sac:C11201 owl:sameAs ?o . ?o rdfs:label ?b. } FILTER( lang(?b) = "ja")
}

なお、マニュアルでは、日本語表記のプロパティは、rdfs:label@ja となっているが、そのままでは動作せずFILTER を使う必要があるようだ。

次に、埼玉県川越市の市区町村コードを取得してみる。一番簡単なクエリーは以下になる。

SELECT * WHERE { 
  GRAPH ?g { ?s ?p "川越市" . }
}

これで、?s に川越市の期間付き標準地域コードの一覧が表示されるので、一応 11201 ということがわかる。もう少し厳密に現在の川越市の市区町村コードをクエリーで得る例は以下のとおり。

SELECT * WHERE { 
  GRAPH ?g { ?s ?p ?o . ?s rdf:type sacs:CurrentStandardAreaCode. ?o rdfs:label "川越市". }
}

次に埼玉県の現在の市町村の一覧を取得してみる。そのコード例は以下のとおり。

SELECT ?s ?name WHERE { 
  GRAPH ?g { ?s ?p ?o . ?s rdf:type sacs:CurrentStandardAreaCode. {{
?o dcterms:isPartOf sac:C11000-19700401.
}UNION{
?o dcterms:isPartOf ?district.
?district dcterms:isPartOf sac:C11000-19700401.
}} ?o sacs:administrativeClass ?ad.
?o rdfs:label ?name. } FILTER( lang(?name) = "ja")
FILTER( ?ad = sacs:DesignatedCity || ?ad = sacs:CoreCity || ?ad = sacs:SpecialCity || ?ad = sacs:City || ?ad = sacs:Town || ?ad = sacs:Village )
}

埼玉県の1970年4月1日以降のどの日の市町村一覧とか市町村がどのように合併をしてきたか等をSPARQLを使えば取得可能である。そういう点では、LODは非常に便利である。自分の場合は、市町村の合併等を考慮して統計数字を比較したいと思っているので、都道府県・市区町村コード情報の LODを使いたいと思っている。

しかし、普通の人がSPARQLを使うのは、はっきりいって難しすぎるし、少し複雑なことをしようと思えばSPARQLがどんどん複雑になってしまう。今のSPARQLだとオープンデータの専門家のおもちゃにすぎないと思う。オープンデータでLODの評価が非常に高くなっているが、それは一部の専門家の評価であって、普通の人が使えるようなソフトウェアを作らなければLODの評価は過大評価だと思う。