2016年8月2日火曜日

「履歴情報つきinteger試作」をMySQLで

nuko_yokohamaさんの記事「履歴情報つきinteger試作」が面白い.PostgreSQLのJSON機能を用いてSQLだけで履歴情報を管理している.こうした機能を考えていたので試してみたくなった.JSON機能についてはMySQLでもバージョン5.7からサポートしているらしい.せっかくなのでMySQLのJSON機能の勉強もかねてMySQLでの実装を試みてみた.

関数定義

「履歴情報つきinteger試作」では色々と関数を定義しているが,ここでは最低限の「create_tt_int」「add_tt_int」「value(実際にはgetValueByUnixTimeとgetValueByNum)」の実装を試みた.

履歴つきinteger作成

履歴つきinteger作成関数.時間はUNIX_TIMESTAMPで表現する.

DROP FUNCTION IF EXISTS create_tt_int;
delimiter //
CREATE FUNCTION create_tt_int(value integer)
 RETURNS JSON DETERMINISTIC
BEGIN
  DECLARE t INT UNSIGNED;
  set t = UNIX_TIMESTAMP();
 RETURN (SELECT JSON_OBJECT('header',JSON_OBJECT('nums',1,'newest',t,'oldest',t),'values',JSON_ARRAY(JSON_OBJECT('value',value,'timestamp',t,'num',1))));
END//
delimiter ;

履歴つきinteger更新

履歴つきinteger更新関数.JSON_ARRAYのマージに手間取った.JSON_MERGEでよかった.

DROP FUNCTION IF EXISTS add_tt_int; delimiter // CREATE FUNCTION add_tt_int(src json, value integer) RETURNS JSON DETERMINISTIC BEGIN DECLARE t INT UNSIGNED; SET t = UNIX_TIMESTAMP(); RETURN (SELECT JSON_OBJECT("header",JSON_OBJECT("nums",JSON_EXTRACT(src,"$.header.nums")+1,"oldest",JSON_EXTRACT(src,"$.header.oldest"),"newest",t),"values",JSON_MERGE(JSON_ARRAY(JSON_OBJECT("value",value,"num",JSON_EXTRACT(src,"$.header.nums")+1,"timestamp",t)),JSON_EXTRACT(src,"$.values")))); END// delimiter ;


UnixTimeを指定して値を取得

UnixTimeを指定して値を取得.

DROP FUNCTION IF EXISTS getValueByUnixTime;
delimiter //
CREATE FUNCTION getValueByUnixTime(src json,t INT UNSIGNED)
 RETURNS JSON DETERMINISTIC
BEGIN
 DECLARE i int;
 DECLARE x int;
 DECLARE t2 JSON;
 DECLARE value JSON;
 IF src->'$.header.oldest' > t THEN RETURN JSON_OBJECT();
 ELSEIF src->'$.header.newest' < t THEN RETURN JSON_EXTRACT(src,CONCAT("$.values[0].value"));
 END IF;
 SET x = src->'$.header.nums';
 SET i = 0;
 set value = JSON_OBJECT();
 WHILE i < x DO
  SET t2 = JSON_EXTRACT(src,CONCAT("$.values[",i,"].timestamp"));
  IF t2<=t THEN RETURN JSON_EXTRACT(src,CONCAT("$.values[",i,"].value"));
  END IF;
  SET i = i + 1;
 END WHILE;
 RETURN value;
END//
delimiter ;


Numを指定して値を取得

履歴番号Numを指定して値を取得.

DROP FUNCTION IF EXISTS getValueByNum;
delimiter //
CREATE FUNCTION getValueByNum(src json,num INT UNSIGNED)
 RETURNS JSON DETERMINISTIC
BEGIN
 DECLARE i int;
 DECLARE x int;
 DECLARE num2 INT UNSIGNED;
 DECLARE value JSON;
 SET x = src->'$.header.nums';
 IF (num < 0 ) THEN RETURN JSON_OBJECT();
 ELSEIF (num > x) THEN RETURN JSON_OBJECT();
 END IF; 
 SET i = 0;
 set value = JSON_OBJECT();
 WHILE i < x DO
  SET num2 = JSON_EXTRACT(src,CONCAT("$.values[",i,"].num"));
  IF (num=num2) THEN RETURN JSON_EXTRACT(src,CONCAT("$.values[",i,"].value"));
  END IF;
  SET i = i + 1;
 END WHILE;
 RETURN value;
END//
delimiter ;

使い方

テーブルを作成,履歴つきintegerを作成.2回ほど更新.

DROP TABLE test2;
CREATE TABLE test2 (id INT UNSIGNED, data JSON);
INSERT INTO test2 VALUES (1, create_tt_int(100));
INSERT INTO test2 VALUES (2, create_tt_int(300));
SELECT SLEEP(60);
UPDATE test2 SET data = add_tt_int(data, 200) WHERE id = 1;
UPDATE test2 SET data = add_tt_int(data, 500) WHERE id = 2;
SELECT SLEEP(60);
UPDATE test2 SET data = add_tt_int(data, 300) WHERE id = 1;
UPDATE test2 SET data = add_tt_int(data, 600) WHERE id = 2;
SELECT * FROM test2;

中身は以下のとおり.履歴情報がJSON形式で記録されている.

mysql> select * from test2\G;
*************************** 1. row ***************************
  id: 1
data: {"header": {"nums": 3, "newest": 1470061025, "oldest": 1470060905}, "values": [{"num": 3, "value": 300, "timestamp": 1470061025}, {"num": 2, "value": 200, "timestamp": 1470060965}, {"num": 1, "value": 100, "timestamp": 1470060905}]}
*************************** 2. row ***************************
  id: 2
data: {"header": {"nums": 3, "newest": 1470061025, "oldest": 1470060905}, "values": [{"num": 3, "value": 600, "timestamp": 1470061025}, {"num": 2, "value": 500, "timestamp": 1470060965}, {"num": 1, "value": 300, "timestamp": 1470060905}]}
2 rows in set (0.00 sec)

ERROR: 
No query specified

ここから値を取り出すにはgetValueByUnixTimeを使う.

mysql> SELECT getValueByUnixTime(data,UNIX_TIMESTAMP('2016-08-01 23:15:00')) AS value FROM test2;
+-------+
| value |
+-------+
| {}    |
| {}    |
+-------+
2 rows in set (0.00 sec)

mysql> SELECT getValueByUnixTime(data,UNIX_TIMESTAMP('2016-08-01 23:15:05')) AS value FROM test2;
+-------+
| value |
+-------+
| 100   |
| 300   |
+-------+
2 rows in set (0.00 sec)
mysql> SELECT getValueByUnixTime(data,UNIX_TIMESTAMP('2016-08-01 23:50:00')) AS value FROM test2;
+-------+
| value |
+-------+
| 300   |
| 600   |
+-------+
2 rows in set (0.00 sec)

ちゃんと履歴から値をとってこれている.

2016年8月1日月曜日

Mirador Viewerを試す

Mirador Viewer は International Image Interoperability Framework (IIIF) プロトコルへの完全対応を謳ったオープンソースのイメージビューワ.アノテーション機能も実装されている.

  • http://projectmirador.org/
  • https://github.com/IIIF/mirador  


Mirador Viewer にはサンプルファイルへのリンクが含まれているので,インストール後すぐにIIIF Viewer としての機能を試すことができる.

インストール


動作に必要なパッケージをインストールする.


sudo yum install nodejs
sudo yum install npm
sudo npm install -g grunt-cli
sudo npm install bower -g

mirador リポジトリを clone する.

git clone https://github.com/IIIF/mirador.git

依存ライブラリをインストールする.

cd mirador/
npm install
bower install

ビルドする.

grunt

エラーがでなければビルド完了.

簡易実行


手軽に試したいのであれば grunt server を実行する.

$ grunt server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:8000

web server が起動するので http://localhost:8000 にアクセスする.



Mirador Viewer は javascript で書かれているので,web server から見える適当な場所に置いても動作する.

以上.

CATCH-Aを試す

  • https://github.com/annotationsatharvard/catcha 

インストール


Java 1.7系をインストールし,環境変数 「JAVA_HOME」を設定する.※1.7系でないとgrails関係でこけるので注意


sudo yum install java-1.7.0-openjdk-devel
pathtojava=$(readlink -e $(which javac));export JAVA_HOME=${pathtojava%/*/*}


Java のバージョンおよび環境変数を確認する.

$ java -version
java version "1.7.0_101"
OpenJDK Runtime Environment (rhel-2.6.6.1.el7_2-x86_64 u101-b00)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)
$ echo $JAVA_HOME
/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.101-2.6.6.1.el7_2.x86_64


GVM(sdkman)をインストールする.最新のもので問題ない模様.


  •  http://sdkman.io/


curl -s "https://get.sdkman.io" | bash
source /home/vagrant/.sdkman/bin/sdkman-init.sh 


sdkman のバージョンを確認する.

$ sdk version
SDKMAN 4.0.37


MySQL をインストールする.

sudo yum install mariadb-server

MySQL のバージョンを確認する.
$ mysql --version
mysql  Ver 15.1 Distrib 5.5.47-MariaDB, for Linux (x86_64) using readline 5.1


ディレクトリを作成し,catcha リポジトリを clone する.

mkdir Catcha
cd Catcha
git clone https://github.com/annotationsatharvard/catcha.git


必要なライブラリも clone する.

mkdir annotationframework
cd annotationframework
git clone https://github.com/annotationframework/AfPersistence.git
git clone https://github.com/annotationframework/AfSecurity.git
git clone https://github.com/annotationframework/AfShared.git


CATCH-A 用のデータベースおよびデータベースユーザを作成する.

sudo mysql -u root -e 'create database catch default charset utf8;'
sudo mysql -u root -e 'grant all on catch.* to "catch"@"localhost" identified by "catch";'


設定ファイルをコピーする.

cd ../catcha
cp Catch-config.properties catch-config.properties 


catch-config.properties を編集する.データベースの設定は以下のあたり.

dataSource.url=jdbc:mysql://localhost:3306/catch?useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true
dataSource.username=catch
dataSource.password=catch


CATCH-A が使っている grails のバージョン確認する.

$ cat application.properties | grep grails
app.grails.version=2.2.5


確認したバージョンの grails をインストールする.

gvm install grails 2.2.5


catcha/grails-app/conf/BuildConfig.groovy を編集する.

diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.gr
index 0c32ab1..83193e1 100644
--- a/grails-app/conf/BuildConfig.groovy
+++ b/grails-app/conf/BuildConfig.groovy
@@ -74,6 +74,7 @@ grails.project.dependency.resolution = {
         //runtime "org.semweb4j:rdf2go.impl.base:4.6.2"
                //compile "org.openrdf:openrdf-sesame-onejar-osgi:2.1.2"
                //compile "org.openrdf.sesame:sesame-query:2.7.2"
+       compile "com.nimbusds:nimbus-jose-jwt:2.26.1"
     }
 
     plugins {


nimbus-jose-jwt は 2.x 系じゃないと動かない. 準備が整ったらプロジェクトをビルド&実行する.

grails run-app


ビルドが無事終了し,以下メッセージが表示されるまで待つ.

| Server running. Browse to http://localhost:8080/catch


表示されたら http://localhost:8080/catch にアクセスする.

ユーザ名「admin」,パスワード「password」でログインできる.

2015年5月15日金曜日

XML文書に電子署名をしてみる

いまさらながらXML署名について調べてみた。

感覚的には理解できたけど、実際の処理に興味があったので、特殊なツールを使わずにXML文書に電子署名をしてみる。

目的は、Online XML Digital Signature Veriferで検証可能なXML署名を作成すること。

参照要素の作成

まず、署名対象のXML文書のダイジェスト値を求める。

以下が今回の署名対象となるXML文書(target.xml)。かなり、適当なXML文書である。

<?xml version="1.0" encoding="UTF-8"?>
<sample>
<!-- comment -->
<msg lang ="ja">hello</msg>
</sample>

つぎに、このXML文書を正規化(Canonicalization)する。

正規化の手順は、http://www.w3.org/TR/xmldsig-core/#sec-c14nAlgにある。

参考:Canonical XML

色々と定義があるようだが、ここではXML宣言とコメント、そして改行コード「\n」を削除する。要素属性の余計な空白も取り除く。

こんな感じ。

$ cat target.xml | tr -d '\012' > target_c14n.xml
$ cat target_c14n.xml
<sample><msg lang="ja">hello</msg></sample>
バイナリダンプは以下の通り。
$ hexdump target_c14n.xml
0000000 3c 73 61 6d 70 6c 65 3e 3c 6d 73 67 20 6c 61 6e
0000010 67 3d 22 6a 61 22 3e 68 65 6c 6c 6f 3c 2f 6d 73
0000020 67 3e 3c 2f 73 61 6d 70 6c 65 3e 
正規化できたら、XML文書のダイジェスト値を計算する。
 
$ openssl dgst -sha1 -binary target_c14n.xml | base64
21hWqJrA9IIsNLbKwiMH2xrD4R0=

このダイジェスト値を用いてDigestValue要素を定義して、

<DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>

この要素を含めた参照(Reference)要素を作成する。

<Reference URI="">
   <Transforms>
   <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
   </Transforms>
   <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
   <DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>
</Reference>
<Reference URI="">は署名対象の参照先を意味しており、envelopedタイプ(署名対象XML文書に署名自体も含む)はURI=""とかになる模様。

<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>は作成するXML署名がenvelopedタイプであることを示す。

また、<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>はダイジェスト値をもとめたときのアルゴリズムを示している。

以上で参照要素が完成した。

署名情報要素(SignedInfo)の作成


署名情報要素(SignedInfo)は、先ほどの参照要素(Reference)に加え、CanonicalizationMethod要素、SignatureMethod要素が必要になる。
 
signedinfo.xml

<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>
</Reference>
</SignedInfo>

これを正規化する。

$ cat signedinfo.xml | tr -d '\012' > signedinfo_c14n.xml
正規化後は以下のようになる。

signedinfo_c14n.xml


<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue></Reference></SignedInfo>

改行コードやEOFも削除する。これで署名情報要素ができた。

バイナリダンプは以下のとおり。

$ hexdump signedinfo_c14n.xml
0000000 3c 53 69 67 6e 65 64 49 6e 66 6f 20 78 6d 6c 6e
0000010 73 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33
0000020 2e 6f 72 67 2f 32 30 30 30 2f 30 39 2f 78 6d 6c
0000030 64 73 69 67 23 22 3e 3c 43 61 6e 6f 6e 69 63 61
0000040 6c 69 7a 61 74 69 6f 6e 4d 65 74 68 6f 64 20 41
0000050 6c 67 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f
0000060 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 31
0000070 2f 31 30 2f 78 6d 6c 2d 65 78 63 2d 63 31 34 6e
0000080 23 22 3e 3c 2f 43 61 6e 6f 6e 69 63 61 6c 69 7a
0000090 61 74 69 6f 6e 4d 65 74 68 6f 64 3e 3c 53 69 67
00000a0 6e 61 74 75 72 65 4d 65 74 68 6f 64 20 41 6c 67
00000b0 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f 2f 77
00000c0 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30 2f 30
00000d0 39 2f 78 6d 6c 64 73 69 67 23 72 73 61 2d 73 68
00000e0 61 31 22 3e 3c 2f 53 69 67 6e 61 74 75 72 65 4d
00000f0 65 74 68 6f 64 3e 3c 52 65 66 65 72 65 6e 63 65
0000100 20 55 52 49 3d 22 22 3e 3c 54 72 61 6e 73 66 6f
0000110 72 6d 73 3e 3c 54 72 61 6e 73 66 6f 72 6d 20 41
0000120 6c 67 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f
0000130 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30
0000140 2f 30 39 2f 78 6d 6c 64 73 69 67 23 65 6e 76 65
0000150 6c 6f 70 65 64 2d 73 69 67 6e 61 74 75 72 65 22
0000160 3e 3c 2f 54 72 61 6e 73 66 6f 72 6d 3e 3c 2f 54
0000170 72 61 6e 73 66 6f 72 6d 73 3e 3c 44 69 67 65 73
0000180 74 4d 65 74 68 6f 64 20 41 6c 67 6f 72 69 74 68
0000190 6d 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33
00001a0 2e 6f 72 67 2f 32 30 30 30 2f 30 39 2f 78 6d 6c
00001b0 64 73 69 67 23 73 68 61 31 22 3e 3c 2f 44 69 67
00001c0 65 73 74 4d 65 74 68 6f 64 3e 3c 44 69 67 65 73
00001d0 74 56 61 6c 75 65 3e 32 31 68 57 71 4a 72 41 39
00001e0 49 49 73 4e 4c 62 4b 77 69 4d 48 32 78 72 44 34
00001f0 52 30 3d 3c 2f 44 69 67 65 73 74 56 61 6c 75 65
0000200 3e 3c 2f 52 65 66 65 72 65 6e 63 65 3e 3c 2f 53
0000210 69 67 6e 65 64 49 6e 66 6f 3e                
000021a

署名準備

XML署名に用いる秘密鍵、証明書を作成する。

まず、2048ビット長のRSA秘密鍵を作成する

$ openssl genrsa -out private-key.pem 2048
秘密鍵の内容を確認する。※秘密鍵は絶対に公開してはならない。意味がなくなるから。今回はあくまで練習のため。
 
$ openssl rsa -in private-key.pem
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAmlg5wx9jWcdPYB54zH+kIsZ5geFalcawV4cOg1M6n11fDikt
aViTTY3yPtzjJGVc+coqoARenRqg27NkYj32ofxc0e9k9+dlK0BXl/toBmRenSuR
xvyO3iVTtN1z3AHZDMpmhj2obs72KzFg+XnNJ47MYBQx3oL6o30wcSNmj/J2vUr1
Jnex2Z5dn189eXadEsxYKLGmwsO5Ocs0yyYj6ua8i+/CWmLA2fzVdid0tfe+ArTx
VLqA6jOBdrUMcJw5Dn5VLYObyUndVga47k3++fy299hARvX8CODGhddQeDuhb0iz
9tiQiImrTRIUyke7Vp1yHCHKzf6E2W2fKLKH/QIDAQABAoIBADPkSbdSjEKZAhTc
6dxHZdXTSPLj42LL5GnpHHYGu4TtDZJjQcNTZmMCwFlmRm/sLHBHCkG2dmD3nPGA
xNVK4+reQA7NH/NBNwBtp4WPnw/XGwBYr7BpJVeG0TfT5KopbOIiAopLnJ90scsf
1OzLiLAuEISVBZc8Dix9YJYJQuhOJPEB4cqFmvag+W71PrmVozpFKWjMhWHtL2Dn
VEfWEtlv0QyKQdHTtcONnGGvRFTkA5z5iziQ/mh7skP5Ks92VoZTeQlHZTGcEPIr
9G1/8PUCRAFCZSSn7yVHdzv8MedAKSx4KZk9gvgbYTyOW93sHQH06zl4RQZX0/U+
VAix5HkCgYEAyucZBC8vOsEbboXMTtZ9LAXdfNyZEt8ev7Nw22B78aeGxWw2F/sn
PJKKqdgRsm7hbyOeydZQ/mqBQE3Ri6kp1I4qvpQ+aK6XjGIjYYymZgaWE6/uQAJU
U8fS4TtG7t0BuCfgQ8fsS95g9mg6zMyV+4OM2oqaUWPh6NU0toUInisCgYEAwrwd
IpJlVNGX6oXlZz/RlL5LjVCgxD1m0wU3vGRXHePjFcTmjgub0Jjr6Kg+WnocdcIk
rM1YWYPgsjvhN3ucnTD+/Y1kKzcfr3ovtrp8F8QrZTiMxTAZ0S7sJlxYxuD7fgKu
YVeHKZMybV8qC7wS5EJM4LyXx+DLphyv9Zf0BncCgYAM+BqMPuvY6JD1To4Rl/om
PzW6DmumXiacAD89dnxVpOyjX9hRThdi8sb0NkBjVF0Keo9ivVUt/ebHEnJLaAOp
d3DZ/6XBkS9UpM04JgJY0SD0nzEuXDfBpysehGhzSiMa/0mBa5z5+HvgJCdmAcmw
aucs7OESRL0i4cXdyMEVQwKBgAoqQacVVz7HNhPi62epWCpYiJ8Wz12PCvgG9LLb
1gRUaf0v6w0NJBQOd3oMljyo1SV8feebTHpXvPnw0D/SLwmxjg30PH9ZAElrqmPy
dhnTfqRpAEgmy6I0vdT+yw+OnPIl965TIFYWPfKhnhNAvQe3QkYU8iNX46mHI9RB
G1bfAoGAEaSnaFbUJTDipC2aJldGx+iNAtKu/QTZLS6FPjSewRdMGNBvhxVfygpc
EBtwbGpSXyysyg3vdDZjWygjLFHnWS1gy+YLZ9A56Ha+cGvazPQ1ZAEes0tjmL6V
gT/EgCkYcBseVUFROhfkTi/jbvD+kS8tuPB8G1plbfWJ1HCXZRQ=
-----END RSA PRIVATE KEY-----
秘密鍵から公開鍵を作成する。(今回は使わないけど)

$ openssl rsa -pubout -in private-key.pem -out public-key.pem

公開鍵の中身を確認する。
   
$ openssl rsa -pubin -in public-key.pem
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmlg5wx9jWcdPYB54zH+k
IsZ5geFalcawV4cOg1M6n11fDiktaViTTY3yPtzjJGVc+coqoARenRqg27NkYj32
ofxc0e9k9+dlK0BXl/toBmRenSuRxvyO3iVTtN1z3AHZDMpmhj2obs72KzFg+XnN
J47MYBQx3oL6o30wcSNmj/J2vUr1Jnex2Z5dn189eXadEsxYKLGmwsO5Ocs0yyYj
6ua8i+/CWmLA2fzVdid0tfe+ArTxVLqA6jOBdrUMcJw5Dn5VLYObyUndVga47k3+
+fy299hARvX8CODGhddQeDuhb0iz9tiQiImrTRIUyke7Vp1yHCHKzf6E2W2fKLKH
/QIDAQAB
-----END PUBLIC KEY-----
証明書署名要求(CSR, Certificate Signing Request)を作成する。  
     
$ openssl req -new -key private-key.pem -out csr.pem -subj '/C=JP/ST=Tokyo/L=Hino/O=Sheepcloud org./OU=Dept/CN=sheepcloud.org'

つぎに、
Online XML Digital Signature Veriferから認証局証明書と秘密鍵(passphraseは"secret")をダウンロードしてくる。検証を成功させるために必要。

$ curl -O https://www.aleksey.com/xmlsec/tests/keys-certs/cacert.pem
$ curl -O https://www.aleksey.com/xmlsec/tests/keys-certs/cakey.pem

Online XML Digital Signature Veriferの認証局証明書でCSRを署名する。

$ openssl x509 -req -in csr.pem -days 3650 -CA cacert.pem -CAkey cakey.pem -set_serial 123 -out cert.pem
Signature ok
subject=/C=JP/ST=Tokyo/L=Hino/O=Sheepcloud org./OU=Dept/CN=sheepcloud.org
Getting CA Private Key
Enter pass phrase for cakey.pem:secret

署名

 作成した秘密鍵で署名情報要素(SignedInfo)に署名し、Base64でエンコードする。

$ openssl dgst -sha1 -sign private-key.pem signedinfo_c14n.xml|base64
FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==
 
エンコード結果をSignatureValue要素の値にする。  
 
<SignatureValue>FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==</SignatureValue>

署名のバイナリダンプは次のとおり。

$ openssl dgst -sha1 -sign private-key.pem signedinfo_c14n.xml|hexdump
0000000 16 49 cf 99 69 87 15 e2 36 81 25 f5 16 83 68 91
0000010 10 eb f5 6d ba 35 b3 a1 63 ac 45 c5 3d c0 27 08
0000020 bd 46 9e 2e cc 2c c0 fe 9b 54 fa 71 b9 a1 03 87
0000030 30 57 38 df d3 4c b9 98 27 7f af 6d b4 26 cf 01
0000040 d8 db 2e 80 70 6d d7 72 74 54 0d 29 9c 03 ab 60
0000050 47 da 1d 1c 2a 34 1c 46 bf be f7 9b c5 f4 7f 5e
0000060 b1 9f 76 52 54 95 2b 62 4f 9b 8c 40 e3 73 40 ce
0000070 f9 b4 00 fb da ae 41 91 33 56 70 04 a5 cf f8 b1
0000080 5e a0 44 55 d5 9c 87 43 e7 88 96 8c 9e 24 10 36
0000090 97 23 6d 62 5d 2a 20 3f 53 6d d9 e4 f4 91 f6 eb
00000a0 3e d0 ab d3 37 c0 a7 3a 3f 3c da 61 47 25 01 ec
00000b0 c6 eb 5c 88 49 17 1c 0f 41 bb 58 81 ce 9c bc ab
00000c0 39 20 fe 40 2d fe 83 85 bb 6d f7 f1 47 5f b6 14
00000d0 a4 26 b7 4d 2a 1b ac e3 8a 4e 68 7d 57 c7 4e fd
00000e0 6e 82 92 97 70 b7 36 a7 e0 1e b1 25 e9 8f c1 01
00000f0 f7 2c 3b c5 a4 8e ca 95 2b fd 60 0a b0 99 b0 d7
0000100

証明書からSubject DNを取得し、X509SubjectName要素を定義する。
 
$ openssl x509 -in cert.pem -text | grep Subject:
Subject: C=JP, ST=Tokyo, L=Hino, O=Sheepcloud org., OU=Dept, CN=sheepcloud.org
取得し、
<X509SubjectName>C=JP, ST=Tokyo, L=Hino, O=Sheepcloud org., OU=Dept, CN=sheepcloud.org</X509SubjectName>
定義する。

証明書をX509Certificate要素に設定する。

$ openssl x509 -in cert.pem
-----BEGIN CERTIFICATE-----
MIIDHjCCAocCAXswDQYJKoZIhvcNAQELBQAwgbwxCzAJBgNVBAYTAlVTMRMwEQYD
VQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFyeSAo
aHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMR4wHAYDVQQLExVUZXN0IFJv
b3QgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAfBgkqhkiG
9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTAeFw0xNTA1MTMxNTEyMzBaFw0yNTA1
MTAxNTEyMzBaMG4xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzENMAsGA1UE
BwwESGlubzEYMBYGA1UECgwPU2hlZXBjbG91ZCBvcmcuMQ0wCwYDVQQLDAREZXB0
MRcwFQYDVQQDDA5zaGVlcGNsb3VkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAJpYOcMfY1nHT2AeeMx/pCLGeYHhWpXGsFeHDoNTOp9dXw4pLWlY
k02N8j7c4yRlXPnKKqAEXp0aoNuzZGI99qH8XNHvZPfnZStAV5f7aAZkXp0rkcb8
jt4lU7Tdc9wB2QzKZoY9qG7O9isxYPl5zSeOzGAUMd6C+qN9MHEjZo/ydr1K9SZ3
sdmeXZ9fPXl2nRLMWCixpsLDuTnLNMsmI+rmvIvvwlpiwNn81XYndLX3vgK08VS6
gOozgXa1DHCcOQ5+VS2Dm8lJ3VYGuO5N/vn8tvfYQEb1/AjgxoXXUHg7oW9Is/bY
kIiJq00SFMpHu1adchwhys3+hNltnyiyh/0CAwEAATANBgkqhkiG9w0BAQsFAAOB
gQBrX5gnLIEZFdI7A5ywZpaw5M5PdUR1pKEnKA9ARkPWkNcGC/Is1Qn1DpUHpIE7
by6zOulby6Grn8j9zfj9XG8ujyzIqtzNJkdyWXROa1BBOxkLu1XnyXYU7LVNi7x3
5BGZT5SK6MclYIzuoAfTACiume5Jr88GeV/QcsPdWTJ+GQ==
-----END CERTIFICATE-----
あとはこれらの情報を以下のXML署名雛形に埋めていく。

<?xml version="1.0" encoding="UTF-8"?><sample><msg lang="ja">hello</msg><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue></DigestValue></Reference></SignedInfo><SignatureValue></SignatureValue><KeyInfo><X509Data><X509SubjectName></X509SubjectName><X509Certificate></X509Certificate></X509Data></KeyInfo></Signature></sample>
完成したXML署名は以下のとおり。
<?xml version="1.0" encoding="UTF-8"?><sample><msg lang="ja">hello</msg><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue></Reference></SignedInfo><SignatureValue>FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=test,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU</X509SubjectName><X509Certificate>MIIDhjCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBvDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFs
ZWtzZXkuY29tL3htbHNlYykxHjAcBgNVBAsTFVRlc3QgUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UE
AxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4XDTE1
MDUxMzA4MzEyMloXDTE2MDUxMjA4MzEyMlowVDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUt
U3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEdGVzdDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJpYOcMfY1nHT2AeeMx/pCLGeYHhWpXGsFeH
DoNTOp9dXw4pLWlYk02N8j7c4yRlXPnKKqAEXp0aoNuzZGI99qH8XNHvZPfnZStAV5f7aAZkXp0r
kcb8jt4lU7Tdc9wB2QzKZoY9qG7O9isxYPl5zSeOzGAUMd6C+qN9MHEjZo/ydr1K9SZ3sdmeXZ9f
PXl2nRLMWCixpsLDuTnLNMsmI+rmvIvvwlpiwNn81XYndLX3vgK08VS6gOozgXa1DHCcOQ5+VS2D
m8lJ3VYGuO5N/vn8tvfYQEb1/AjgxoXXUHg7oW9Is/bYkIiJq00SFMpHu1adchwhys3+hNltnyiy
h/0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
Q2VydGlmaWNhdGUwHQYDVR0OBBYEFMx99EfHBvUhCn6Q+ByacE1jkXVQMB8GA1UdIwQYMBaAFNpG
6Wvmr9M9quUhS1LtymYo4P6FMA0GCSqGSIb3DQEBCwUAA4GBAEdZ6Bidq3ZGURdRkCiU+rKYpQx/
HkW/ibIbrIZowaAIcqC8AkmLB4nrPX+DODU6huiwzPrTk4JyHwEnHhtJRJh3cknAwVTDz6slbEpa
eT7Biv5klcoOAljRF3NZKwVJGqDZMEPdK0ofGhp6i5JlZ7dwzXir57+JVGxwhyRikl/u</X509Certificate></X509Data></KeyInfo></Signature></sample>

検証

Online XML Digital Signature Veriferで検証する。

無事、検証終了。

RESULT: Signature is OK
---------------------------------------------------
= VERIFICATION CONTEXT
== Status: succeeded
== flags: 0x00000000
== flags2: 0x00000000
== Key Info Read Ctx:
= KEY INFO READ CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: rsa
==== keyType: 0x00000001
==== keyUsage: 0x00000002
==== keyBitsSize: 0
=== list size: 0
== Key Info Write Ctx:
= KEY INFO WRITE CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: NULL
==== keyType: 0x00000001
==== keyUsage: 0xffffffff
==== keyBitsSize: 0
=== list size: 0
== Signature Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: exc-c14n (href=http://www.w3.org/2001/10/xml-exc-c14n#)
=== Transform: rsa-sha1 (href=http://www.w3.org/2000/09/xmldsig#rsa-sha1)
=== Transform: membuf-transform (href=NULL)
== Signature Method:
=== Transform: rsa-sha1 (href=http://www.w3.org/2000/09/xmldsig#rsa-sha1)
== Signature Key:
== KEY
=== method: RSAKeyValue
=== key type: Private
=== key usage: -1
=== key not valid before: 1431505882
=== key not valid after: 1463041882
=== rsa key: size = 2048
=== list size: 1
=== X509 Data:
==== Key Certificate:
==== Subject Name: /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=test
==== Issuer Name: /C=US/ST=California/O=XML Security Library (http://www.aleksey.com/xmlsec)/OU=Test Root Certificate/CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com
==== Issuer Serial: 1
==== Certificate:
==== Subject Name: /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=test
==== Issuer Name: /C=US/ST=California/O=XML Security Library (http://www.aleksey.com/xmlsec)/OU=Test Root Certificate/CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com
==== Issuer Serial: 1
== SignedInfo References List:
=== list size: 1
= REFERENCE VERIFICATION CONTEXT
== Status: succeeded
== URI: ""
== Reference Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: enveloped-signature (href=http://www.w3.org/2000/09/xmldsig#enveloped-signature)
=== Transform: c14n (href=http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
=== Transform: sha1 (href=http://www.w3.org/2000/09/xmldsig#sha1)
=== Transform: membuf-transform (href=NULL)
== Digest Method:
=== Transform: sha1 (href=http://www.w3.org/2000/09/xmldsig#sha1)
== Manifest References List:
=== list size: 0
ポイントはダイジェスト値、署名を行う対象となるXML文書の正規化。

署名前、署名後のXML文書からは改行やEOFを削除する。
 

参考文献


  • http://www.w3.org/TR/xmldsig-core/
    • 仕様。拾い読みしただけ。ちゃんと読まないと。 
  • https://www.aleksey.com/xmlsec/xmldsig-verifier.html
    • XMLSec Cライブラリのサイト。ここのOnline Validatorにはお世話になった。
  • http://www.atmarkit.co.jp/ait/articles/0207/24/news001.html
    • 日本語。わかりやすい。 
  • http://www.di-mgt.com.au/xmldsig.html
    •  一番お世話になったサイト。SignedInfo要素へ署名する際、改行コードやEOFがあるといけないようなのだが、このサイトのバイナリダンプをみるまでそれがわからなかった。
  • http://www.w3.org/TR/xml-c14n11/
    • XML正規化仕様。ちゃんと読んでいない。  

2014年11月22日土曜日

OAICatMuseum 1.1のインストール

LIDO対応のOAI-PMHプロバイダを探していたところOAICatMuseumを見つけたので、試してみた。

OAICatMuseum now supports the LIDO XML Schema
http://hangingtogether.org/?p=1730

OAICatMuseum 1.0
http://oclc.org/research/activities/oaicatmuseum.html


インストール環境

インストール環境は以下のとおり。

# cat /etc/redhat-release
CentOS release 6.6 (Final)
# yum install tomcat6
# yum install mysql-connector-java
# yum install mysql-server

tomcat のバージョンはtomcat6-6.0.24-80

mysqlサーバのバージョンはmysql-server-5.1.73-3


インストール

OAICatMuseumのダウンロードサイトより、oaicatmuseum_1.1.warとoaicatdb.sqlを取ってくる。

    # curl -o oaicatmuseum_1.1.war http://www.oclc.org/content/dam/research/activities/oaicatmuseum/oaicatmuseum_1.1.war
    # curl -o oaicatdb.sql http://www.oclc.org/content/dam/research/activities/oaicatmuseum/oaicatdb.sql
 
oaicatmuseum_1.1.warをtomcat webappsディレクトリに置く。
 
    # cp /usr/local/src/oaicatmuseum_1.1.war /usr/share/tomcat6/webapps/
 
mysqlにデータベースを作成し、oaicatdb.sqlをインポートする。

    # mysqladmin -u root create oaicatdb
    # mysql -u root oaicatdb < /usr/local/src/oaicatdb.sql
    # cd /usr/share/tomcat6/webapps/oaicatmuseum_1.1
 
作成したデータベースにアクセス可能なユーザを用意する。
 
    mysql> GRANT SELECT ON oaicatdb.* TO 'oaicatdb'@'localhost' IDENTIFIED BY 'oaicatdb!';
 

mysql-connector-java.jarをoaicatmuseum_1.1/WEB-INF/lib/にコピーする。
 
    # cp /usr/share/java/mysql-connector-java.jar /usr/share/tomcat6/webapps/oaicatmuseum_1.1/WEB-INF/lib/
 
oaicat.properties.lidoをリネームする。
 
    # cp /usr/share/tomcat6/webapps/oaicatmuseum_1.1/WEB-INF/classes/oaicat.properties.lido /usr/share/tomcat6/webapps/oaicatmuseum_1.1/WEB-INF/classes/oaicat.properties
 
oaicat.propertiesのデータベース設定を修正する。

    # vi /usr/share/tomcat6/webapps/oaicatmuseum_1.1/WEB-INF/classes/oaicat.properties
    JDBCLimitedOAICatalog.jdbcDriverName=com.mysql.jdbc.Driver
    JDBCLimitedOAICatalog.jdbcURL=jdbc:mysql://localhost:3306/oaicatdb
    JDBCLimitedOAICatalog.jdbcLogin=oaicatdb
    JDBCLimitedOAICatalog.jdbcPasswd=oaicatdb!
    JDBCLimitedOAICatalog.isPersistentConnection=true

tomcatを(再)起動する。

    /etc/init.d/tomcat6 start
 
あとは以下URLにアクセスするだけ。

    http://host:8080/oaicatmuseum_1.1/


GetReord URLの例。

    http://host:8080/oaicatmuseum_1.1/OAIHandler?verb=GetRecord&identifier=oai:oaicat.oclc.org:oai/1&metadataPrefix=lido

結果


基本は上記手順でLIDO XMLを出力できるはずなのだが、なぜかCDWA LITE形式で出力されてきた。

設定が他にあるのかもしれないが、ドキュメントにはとくに記されていなかったので、直接oaicatdb.sqlを書き換えてLIDO XMLを出力できるようにした。

コンテンツとしてはwww.lido-schema.orgのexamplesを利用した。


  • http://www.lido-schema.org/documents/examples/LIDO-Example_FMobj00154983-LaPrimavera.xml
  • http://www.lido-schema.org/documents/examples/LIDO-Example_FMobj20344012-Fontana_del_Moro.xml

   
修正後のファイルはこちら。単に格納するXMLファイルをLIDOのものにしただけ。5レコードあるが内容は重複している(サンプルが2種類しかないため)。

http://goo.gl/0fFmnS

これをインポートして、
    mysql -u root oaicatdb < /usr/local/src/oaicatdb2.sql
 
再度GetReord URLにアクセスすると無事LIDO XMLが出力されてきた。

    http://host:8080/oaicatmuseum_1.1/OAIHandler?verb=GetRecord&identifier=oai:oaicat.oclc.org:oai/1&metadataPrefix=lido
これでLIDOハーベスタの試験ができる。

plotKMLのメモ

plotKML(http://plotkml.r-forge.r-project.org/)が面白い。

RでKMLを処理するためのパッケージ、簡単にKMLを生成できてしまう。

たとえば、こんな感じの可視化が簡単にできる。



Rスクリプトはこんな感じ。


library(maptools)
library(plotKML)
shp<-readShapePoly("h22ka18207.shp")
proj4string(shp) <- CRS("+proj=longlat +datum=WGS84")
z<-shp@data$JINKOz[z==0<-1
kml(shp,labels=iconv(shp@data$MOJI,to="UTF8",from="SJIS"),altitude=z,colour="#ff00ff",alpha=0.75,plot.lab=TRUE)




Shapefileはe-Statからダウンロードしてきたもの使った。

バブルチャートっぽく表示する場合はこんな感じ。

data <- data.frame(x=shp@data$X_CODE,y=shp@data$Y_CODE,id=shp@data$KEY_CODE,label=iconv(shp@data$MOJI,to="UTF8",from="SJIS"),jinko=shp@data$JINKO)
coordinates(data) <- ~x+y
proj4string(data)<-CRS("+proj=longlat +datum=WGS84")
kml(data,shape="http://maps.google.com/mapfiles/kml/pal2/icon18.png",color="#ff0000",size=jinko,labels=label)




公式ページをみるとアニメーションにも対応してる模様。


KMLを書き起こすのは面倒だけど、これなら簡単。

何かの時に役立つかもしれない。










2013年11月13日水曜日

WebGL Globeを利用した可視化実験

WebGL Globeはgoogleが作ったオープンソースの地理情報可視化プラットフォーム

本気で頑張るとこんなものも作れるらしい

とりあえず練習がてら、USGSのGeoJSONを可視化してみる。

ベースはwebgl globeのindex.html。
if(!Detector.webgl){Detector.addGetWebGLMessage();else {var container = document.getElementById('container');var globe = DAT.Globe(document.getElementById(‘container'), function(label) {return new THREE.Color([0x87e7b0,0x87e7b0,0x87e7b0,0x87e7b0,0xcbf299,0xfcd1d1,0xff2800,0x9a0079][label]);});var script = document.createElement('script');
script.src = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojsonp';document.getElementsByTagName('head')[0].appendChild(script);var eqfeed_callback = function(results){        var data = new Array();for (var i = 0; i < results.features.length; i++) {data.push(results.features[i].geometry['coordinates'][0]);data.push(results.features[i].geometry['coordinates'][1]);data.push(results.features[i].properties['mag']/30.0);data.push(Math.floor(results.features[i].properties['mag']));}globe.addData(data, {format: 'legend', name: 'earthquakes', animated: false});
globe.createPoints();globe.animate();document.body.style.backgroundImage = 'none'; // remove loading };}
こんな感じ。


いろいろと試してみよう!