全国各地に散らばるチームや国際チーム、そしてフレックス制の勤務時間と週 4 日制勤務のすべてによって、チームが共同で作業する時間と場所は変わってきます。この記事では、さまざまな場所にいるチームのメンバーと連絡を取るのに最適な時間を調べるために Google Earth を利用する方法を紹介します。また、メッセージの送信時刻を追跡する一般的な手法 (E メール・ヘッダー)、そして適切な設定で KML (Keyhole Markup Language) を生成するプログラムと併せて Google Earth の TimeSpan 機能と「時間スライダー」を使用した、実用的な視覚化手法を具体的な例で説明します。
Google Earth を実行可能な 3D アクセラレーション機能を備えたハードウェアであれば、この記事に記載するコードを処理するのに十分です。この記事で説明する KML は、米国 1 つをとっても何万ものポリゴン頂点を使用するので、地球規模のレンダリングや州レベルよりも詳細なレンダリングを行うには、処理速度に優れたプロセッサーが必要となる可能性があります。
Google Earth V4 以降でないと、ここで説明する視覚化に不可欠な TimeSpan 機能はサポートできません。KML の作成と E メール・ヘッダー情報の抽出には、Perl が必要です。また、CPAN から Mail::IMAPClient モジュールおよび IO::Socket::SSL モジュールを入手してください (「参考文献」を参照)。
この記事に記載するコードは特定のプラットフォームに依存しないため、Google Earth と Perl を実行するあらゆるプラットフォームで実行できるはずです。
連絡可能時間マップでは、特定の場所で特定の時間に連絡が取れる可能性の高いメンバーのリストが提供されます。例えば図 1 と図 2 には、特定の時間範囲内にメッセージを受信する可能性があるユーザーの数が州別に示されています。このような連絡可能時間マップを作成するのに適しているのは、インスタント・メッセージのログ、電話の使用記録、グループ・カレンダー、バッジ・リーダー・アクセス、そしてその他の時間関連のデータ・レコードなどです。
この記事では、連絡が取れることを表す上でおそらく最も一般的なデータである、E メール・ヘッダーを抽出することに焦点を絞ります。個人に最も連絡を取りやすいのは、その個人が盛んにメッセージを送信している時間帯だからです。それぞれのユーザーには対応する地理区画を割り当て、1 時間あたりのメッセージ数に応じた色の透明度の指定を使って KML を作成します。アニメーションや合計時間範囲の選択などを含め、Google Earth の時間スライダー機能を利用して、地域全体のユーザーの最終的な連絡可能時間マップを表示します。図 1 を見てください。これは、朝早い時間のマップの表示例です。
図 1. 表示例 - 開始時
図 2 では、その日の時間を進めて拡大した時間範囲を表示しています。この表示から、米国全体のなかで、どの地域のユーザーに連絡を取りやすいかを特定することができます。
図 2. 表示例 - その後
Google が提供している数多くの優れた KML マニュアル・ページの 1 つに、KML で米国内の州を大まかに枠取りした例が記載されています。約 13,000 ポイントからなるこれらの大まかな外枠は、各州の境界を明示にするには最適です。Google が提供している米国の州のサンプル・ファイルを入手して、extractStates.pl プログラムがどのように州情報を切り分けるかについての詳細を読んでください。
リスト 1. 完全な extractStates.pl プログラム
#!/usr/bin/perl -w
# extractStates.pl write each state coordinates into a separate file
use strict;
my $str = ""; # built output string
my $fname = ""; # current filename
my $cmd = `mkdir states/`;
while( my $line = <STDIN> )
{
if( $line =~ /<name>/ )
{
# extract the state for file name
$fname = substr( $line, index($line,"CDATA[")+6 );
$fname = substr( $fname, 0, index($fname," (") );
}elsif( $line =~ /<TimeSpan>/ )
{
# change the TimeSpan designator for later processing
$line = <STDIN>; # begin tags
$line = <STDIN>; # close TimeSpan
$line = qq{ <TimeSpan></TimeSpan>\n};
}elsif( $line =~ /<\/Placemark/ )
{
# write out the file, reset variables after closing tag
open( OUTFILE, "> states/$fname ") or die "Can't write state file";
print OUTFILE $str;
print OUTFILE $line;
close(OUTFILE);
$str = "";
}#if closing tag
# add a line if it's at the start or the built string is not blank
if( $line =~ /<Placemark/ || $str ne "" ){ $str .= $line }
}#line in
|
変数を宣言して states ディレクトリーを作成した後、extractStates.pl プログラムは STDIN からすべての行を読み取ります。us_states.kml ファイルには大まかな州境ジオメトリーが含まれており、extractStates.pl プログラムはこれらのジオメトリーをそれぞれ個別のファイルに書き込みます。us_states.kml ファイル固有の TimeSpan エントリーを変更しやすいプレースホルダーに置換した上で、各州の情報全体を states ディレクトリーに書き出します。
上記のリスト 1 のコードを extractStates.pl という名前を付けたファイルに保存してください。次にこのプログラムをコマンド、command cat us_states.kml | perl extractStates.pl で実行し、states ディレクトリーに以下に記載したようなファイルがあることを確認します。
リスト 2. states ディレクトリーのリスト
ls -la states/* | head -rw-r--r-- 1 nathan nathan 6708 2008-07-08 17:11 states/Alabama -rw-r--r-- 1 nathan nathan 85426 2008-07-08 17:11 states/Alaska ... -rw-r--r-- 1 nathan nathan 15804 2008-07-08 17:11 states/West Virginia -rw-r--r-- 1 nathan nathan 11536 2008-07-08 17:11 states/Wisconsin -rw-r--r-- 1 nathan nathan 3298 2008-07-08 17:11 states/Wyoming |
E メール・ヘッダーを抽出して送信時刻のエントリーを処理する作業は、CPAN の Mail::IMAPClient モジュールと IO::Socket:SSL モジュールを使用すると比較的簡単に行えます。以下の例では Google IMAP (Internet Message Access Protocol) インターフェースを使っています。ここに記載するコードは、対象のメール・サーバーがいくつあっても機能するはずです。ただし、サーバーのセットアップによっては SSL 接続を削除する必要があります。
リスト 3. extractEmails.pl モジュール、接続のセットアップ
#!/usr/bin/perl -w
# extractEmails.pl get all e-mails, print listing of from at what hour
use strict;
use Mail::IMAPClient;
use IO::Socket::SSL;
my %timeHash = (); # data structure for whom at what time
# create a SSL socket to the imap server
my $socket = IO::Socket::SSL->new( PeerAddr => 'imap.gmail.com',
PeerPort => 993
) or die "can't create socket";
# create an imap connection through the ssl socket
my $imap = Mail::IMAPClient->new( Socket => $socket,
User => 'yourEmailID@gmail.com',
Password => 'yourPassword'
) or die "can't connect imap";
$imap->select("INBOX");
my @messages = $imap->search('ALL');
|
ソケットと IMAP 接続を作成するのは簡単です。リスト 4 のように、E メールと時刻のデータ構造を作成して出力します。
リスト 4. 時刻の抽出、データ構造の出力
my $msgCount = 0;
for my $msg ( @messages )
{
my $from = $imap->get_header($msg,"From");
my $date = $imap->get_header($msg,"Date");
# set date to main hour
$date = substr($date, index($date,":")-2,2);
# increment the hour's count for that id
$timeHash{$from}{$date}++;
$msgCount++;
if( $msgCount % 10 == 0 ){ print STDERR "$msgCount\n" }
}#for each message
$imap->logout();
# print all of the hour/from combinations for later processing
for my $from( keys %timeHash )
{
for my $time( keys %{ $timeHash{$from} } )
{
print "$from TIME $time $timeHash{$from}{$time}\n";
}#for time
}#for id
|
この例で選択している時刻は、各 E メールの送信時刻であることに注意してください。連絡可能時間マップのシナリオによっては、時、分、曜日、または週を選択したほうが有効な場合もあります。コマンド perl extractEmails.pl > emailHours で extractEmails.pl プログラムを実行してください。このコマンドによって、10 件のヘッダーごとに進行状況表示が STDERR に出力された後、以下のような emailHours ファイルが生成されます。
リスト 5.
emailHours ファイルの例Dave <dave@ibmdevworks.com> TIME 11 6 Dave <dave@ibmdevworks.com> TIME 21 8 ... Bob <bob@ibmdevworks.com> TIME 07 6 Bob <bob@ibmdevworks.com> TIME 11 36 |
emailHours ファイルのフォーマットは、名前 (取得できる場合)、E メール・アドレス、TIME という区切り文字、そして時刻です。
この時点で、emailHours ファイルにはすべての E メール・アドレスと、特定の時間にそれぞれのアドレスからメッセージが送信された回数が一覧にされています。このファイルを使って、連絡先をいくつか選択した処理をすることも、送信回数が多い上位 10 人の E メール送信者のリストを作成することもできます。ここでは以下の 1 行のコードを使って、emailHours ファイルから送信回数が多い上位 50 人の E メール送信者リストを作成します。
リスト 6. 送信回数が多い上位 50 人の E メール送信者リストを作成するコマンド
cat emailHours | \
perl -lane '@a=split "TIME";$h{$a[0]}+=$F[@F-1]; \
END{for(keys %h){print "$h{$_} $_"}}' | sort -nr | head -n50 > top50emails
|
リスト 6 の \ 文字は見やすくするために記載しているだけなので、コマンドを実行するときには含めないでください。上記のコマンドを実行すると、以下のような内容のファイルが生成されます。
リスト 7.
top50emails ファイルの例44 Bob <bob@ibmdevworks.com> 38 Dave <dave@ibmdevworks.com> 34 Tom <tom@ibmdevworks.com> 30 Mike <mike@ibmdevworks.com> ... |
この top50emails ファイルを変更して、各ファイルの先頭に州名、続いて STAT という区切り文字を挿入します。この作業は手動で行うことも、州指定子に geo-ip ロケーター、従業員アドレス・データベース、あるいはその他の地理特定データのソースをリンクさせることもできます。変更後のファイルは以下のようになります。このファイルは stateMapping という名前で保存してください。
リスト 8.
stateMapping ファイルの例New York STATE 44 Bob <bob@ibmdevworks.com> North Carolina STATE 38 Dave <dave@ibmdevworks.com> Virginia STATE 34 Tom <tom@ibmdevworks.com> Georgia STATE 30 Mike <mike@ibmdevworks.com> ... |
createKml.pl による KML マークアップの生成
州の座標を抽出し、完全な E メール・ヘッダーと時刻をカウントし、該当する E メール ID のそれぞれに州名を関連付けた後は、KML ファイルを生成して目的の表示を作成することができます。リスト 9 に、createKml.pl プログラムの開始部分を記載します。
リスト 9. createKml.pl プログラム・ヘッダー、メイン・ループ
#!/usr/bin/perl -w
#createKml.pl build google earth kml, fade states based on entries per hour
use strict;
die "specify state mapping file, maximum, intervals " unless ( @ARGV == 3 );
my( $inFile, $max, $interval ) = @ARGV;
my %state = ();
loadStateMapping();
kmlHeader();
kmlStyles();
while( my $line = <STDIN> )
{
# for bogus entry elimination
next unless length( $line) > 20 ;
chomp($line);
#change person@ibm.com TIME 11 2 into components
my( $mail, $time ) = split "TIME ", $line;
my( $stHour, $countVal ) = split " ", $time;
# continue if a state defined for that mail
next unless exists($state{$mail});
open( INFILE,"states/$state{$mail}") or die "no state input file";
while( my $line = <INFILE> )
{
if ( $line =~ /<name>/ ){ print "<name><![CDATA[$mail]]></name>\n" }
elsif( $line =~ /<TimeSpan>/ ){ getTimes( $stHour ) }
elsif( $line =~ /Style_/ ) { getStyle( $countVal ) }
else { print $line }
}#while line in
close(INFILE);
}#line in
print qq{</Document>\n</kml>\n};
|
正しい使用方法を確認して変数を宣言した上で、loadStateMapping サブルーチンが呼び出されます。それぞれの E メール・アドレスについて割り当てられた州が読み取られ、kmlHeader サブルーチンと kmlStyles サブルーチンが呼び出されて、指定されたしきい値と間隔に対応する KML マークアップが出力されます。
メイン・ループ内では STDIN のすべての行が読み取られて関連情報が抽出されます。E メール・アドレスがプレース・マーク名として指定され、TimeSpan の開始点と終了点が計算されて、指定されたしきい値と間隔に応じて適切なスタイルが完全に書き込まれます。
リスト 10 に上述の 3 つのサブルーチンのうち、最初の loadStateMapping の詳細を記載します。
リスト 10.
kmlHeader のサブルーチン、loadStateMapping
sub loadStateMapping
{
# create a hash storing which mail corresponds to which state
open( INFILE,"$inFile" ) or die "no in state file";
while( my $line = <INFILE> )
{
chomp($line);
my( $sname, $mail ) = split "STATE ", $line;
# skip the total count
$mail = substr($mail, index($mail," ")+1);
$state{$mail} = $sname;
}#stateMapping lines
close(INFILE);
}#loadStateMapping
sub kmlHeader
{
print qq{<?xml version="1.0" encoding="UTF-8"?>\n};
print qq{<kml xmlns="http://earth.google.com/kml/2.2">\n};
print qq{<Document>\n};
print qq{ <name><![CDATA[Time Availability]]></name>\n};
print qq{ <open>1</open>\n};
}#kmlHeader
|
処理速度を上げるため、loadStateMapping ファイルは州割り当てファイルを読み取り、州名と E メール・アドレスを対応させたハッシュを作成します。メイン・プログラム・ループでは、このハッシュがチェックされます。このようにして、州が割り当てられていないエントリーはスキップできるようにしています。この kmlHeader のサブルーチンが出力するのは、KML 文書のメイン・ヘッダー・マークアップです。続いてリスト 11 に getTimes サブルーチンを記載します。
リスト 11.
getTimes サブルーチン
sub getTimes
{
my $endHour = $inHour + 1;
if( length($endHour) == 1 ){ $endHour = "0$endHour" }
print qq{ <TimeSpan>\n};
print qq{ <begin>2008-07-01T$inHour:00Z</begin>\n};
print qq{ <end>2008-07-01T$endHour:00Z</end>\n};
print qq{ </TimeSpan>\n};
}#getTimes
|
正しい TimeSpan マークアップを指定するという作業は、上記の getTimes サブルーチンに記載されたコードによって行われます。複雑になってくるのは、以下のリスト 12 に記載する getStyle サブルーチンです。
リスト 12.
getStyle サブルーチン
sub getStyle
{
# find the appropriate style based on the input value
my $inputVal = $_[0];
my $decInc = $max / $interval;
my $count = $decInc;
my $styleCount = 0;
# move through each interval, exit when the input value no longer fits
while( $count <= $max )
{
if( $count > $inputVal ){ last }
$styleCount++;
$count += $decInc;
}#While count less than max
# default to the last style if interval is outside the boundary
if( $styleCount >= $interval ){ $styleCount-- }
print qq{ <styleUrl>#style} . $styleCount . qq{</styleUrl>\n};
}#getStyle
|
以下に記載する kmlStyles サブルーチンと同様、getStyle サブルーチンはまずインクリメンターを作成します。インクリメンターの値は、最大指定値を間隔で割ったものです。例えば最大値が 100 で、間隔が 5 の場合、20 を単位に区分した一連の「バケット」が作成され、これらのバケットにそれぞれの入力値が分類されます。入力値が 40 だとすると、この値は上から 2 番目に透明な透明度に相当し、値が 80 以上だとすると、最も不透明な透明度が設定されます。リスト 13 は、これと同じような機能を持つ kmlStyles サブルーチンです。
リスト 13.
kmlStyles
sub kmlStyles
{
# create a incremented "fade range" according to the number of intervals
my $hexInc = 255/$interval;
my $count = $hexInc;
my $styleNum = 0;
while( $count <= 255 )
{
my $fade = sprintf("%X", $count );
print qq{ <Style id="style} . $styleNum . qq{">\n};
print qq{ <IconStyle>\n};
print qq{ <scale>0.4</scale>\n};
print qq{ <Icon>\n};
print qq{ <href>http://maps.google.com/mapfiles/kml/};
print qq{shapes/star.png</href>\n};
print qq{ </Icon>\n};
print qq{ </IconStyle>\n};
print qq{ <LabelStyle>\n};
print qq{ <color>9900ffff</color>\n};
print qq{ <scale>1</scale>\n};
print qq{ </LabelStyle>\n};
print qq{ <LineStyle>\n};
print qq{ <color>99FFFF99</color>\n};
print qq{ <width>2</width>\n};
print qq{ </LineStyle>\n};
print qq{ <PolyStyle>\n};
print qq{ <color>} . $fade . qq{FF9933</color>\n};
print qq{ <fill>1</fill>\n};
print qq{ <outline>1</outline>\n};
print qq{ </PolyStyle>\n};
print qq{ </Style>\n};
$styleNum++;
$count += $hexInc;
}#while count
}#kmlStyles
|
指定された最大値や間隔の値に関わらず、定義されたそれぞれの透明度のパーセンテージは 00-ff でなければなりません。10 進数の間隔から 16 進数の透明度のパーセンテージに適切に変換する作業は、sprintf コマンドの %X 指定子によって行われます。上記のコードは、createKml.pl という名前を付けたファイルに保存し、この後の使用方法についてのセクションを読んでください。
適切な最大値と間隔の変数は、主に使用する特定のデータに応じて選択するものですが、最大値には、top50emails に記録された最大の値より 20 から 40 パーセント低い値を試してください。間隔の選択は主に、間隔を長くして過剰な情報を表示するか、あるいは短い間隔を選んで変更をほとんど表示しないかのトレードオフです。まずは単純明快な例として、コマンド cat emailHours | perl createKml.pl stateMapping 20 2 > timeMap.kml を実行してみてください。
Google Earth を開いて timeMap.kml ファイルをロードすると、画面中央の上部に「時間スライダー」が表示されます。このスライダーをドラッグすると、時間軸に沿って表示を変更することができます。また、再生ボタンを押してアニメーションを表示することもできます。さらに、表示時間範囲を拡大して、特定の州が表示される時間範囲を広げてみてください。
素晴らしい Google Earth インターフェース、そして記事で紹介した KML を作成するためのカスタム・コードを使用すれば、さまざまなアプリケーションに合わせて独自の連絡可能時間マップを作成することができます。例えば、インスタント・メッセージのログや電話記録、そしてその他のソースからログイン時間とアクティビティー時間を抽出して、時間が重なり合うデータ・セットを追加で作成してみてください。時間範囲を拡大したり、あるいは会社やカスタマー全体を網羅した分刻みの情報に重点を置いたりするのも一考です。また、Web サーバーから訪問者に関する情報を抽出し、地方自治体固有のプレース・マークと指定子を作成して、Web サイトの訪問者がいつ、どこでコンテンツを表示したかを調査することもできます。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample code | os-google-earth-perl.timeAvailabilityMaps.zip | 4KB | HTTP |
学ぶために
- Google では素晴らしい KML ドキュメントを用意しています。
- この記事では、Brian Flood による us_states.kml のサンプル KML ファイルを使用しています。
- ソフトウェア開発者を対象とした興味深いインタービューや討論については、developerWorks ポッドキャストをチェックしてください。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- 世界中で近日中に予定されている IBM オープン・ソース開発者を対象とした会議、見本市、ウェブ放送やその他のイベントをチェックしてください。
- オープンソース技術を使用して開発し、IBM の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、developerWorks Open source ゾーンを参照してください。
- 無料の developerWorks On demand demos で、IBM およびオープンン・ソースの技術と製品機能を調べて試してみてください。
製品や技術を入手するために
- この記事のマップを表示するには、Google Earth アプリケーションが必要になります。
- Perl、CPAN の Mail::IMAPClient モジュールと IO::Socket::SSL モジュールも必要です。
- IBM ソフトウェアの試用版を使用して、次のオープン・ソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。
- IBM 製品の評価版をダウンロードして、DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を使ってみてください。
議論するために
- developerWorks blogs から developerWorks コミュニティーに加わってください。
