はじめに
InstaMapperは,iPhoneアプリ「GPS Tracker」で記録した位置情報へアクセスするための Web API(解説ページ,要ログイン)も提供しています.
APIキーを取得後(1つのAPIキーは1つのデバイスに対応するかと),特定のURLへ,このAPIキーやパラメータとともにリクエストを送信すると,対応する位置情報(のリスト)がCSV形式やJSON形式で返ってくるので,いろいろ加工して遊べそうです.
しかしながら,解説ページを読む限り,現状では,from_tsパラメータとnumパラメータとを組み合わせて「いついつから最大何個分の位置情報」といった感じにしか取得できないようです.
個人的には,作成した「track」に関連した位置情報群が取得できると幸せかも,と思っています.
せっかくこういった情報の表示や http://www.instamapper.com/trk?key=10390698753582733189 といったURLがあるのだから,track_keyパラメータで指定したり,from_tsパラメータとto_tsパラメータとの組み合わせで指定したり,とかできるべきだよね,ということですね.念のため,track_keyやto_tsを実際に指定してみましたが,あっさり無視されてしまいました.
そんなわけで,両端の時刻を指定して,その間の位置情報群を取得できるようなperlモジュールっぽいものを書いてみました.勝手にNet::InstaMapperとか名前をつけてます.
以下,使い方とかサンプルとかソースコードとかです.
使い方
まず,set_api_keyメソッドで,取得したAPIキーを設定します.
use Net::InstaMapper; Net::InstaMapper::set_api_key( '********************' );
get_positionsメソッドで指定した時刻間の位置情報群が得られます.
my $data = Net::InstaMapper::get_positions( '2009-08-14 18:18:14', '2009-08-14 19:08:33' );
また,get_positions_jsonメソッドで同様の情報をJSON形式(の文字列)で取得することもできます.
my $json = Net::InstaMapper::get_positions_json( '2009-08-14 18:18:14', '2009-08-14 19:08:33' );
できるのはこれだけです.
サンプル
時刻と標高(海抜?)のペアを取得するサンプルです.
#!/usr/bin/perl use strict; use warnings; use utf8; use Data::Dumper; use Net::InstaMapper; sub d { print Dumper @_; } Net::InstaMapper::set_api_key( '********************' ); Net::InstaMapper::hide_device_key( 1 ); my $data = Net::InstaMapper::get_positions( @ARGV ); $data = [ map { { t => $_->{timestamp}, h => $_->{altitude} } } @$data ]; d $data;
実行結果は次のようになります.
% ./instamapper-api.pl '2009-08-14 18:18:14' '2009-08-14 19:08:33'
$VAR1 = [
{
'h' => '74',
't' => 1250241494
},
{
'h' => '77',
't' => 1250241554
},
...
{
'h' => '78',
't' => 1250244453
},
{
'h' => '85',
't' => 1250244513
}
];
%あとはこれをグラフにしたり,とかですかね.
おわりに
以上,InstaMapperのちょっと使いにくいAPIをちょこっとだけラップする,Net::InstaMapperとかいうモジュールっぽいものを書いてみた,というお話でした.
ソースコードを以下に載せておしまいとします.
ソースコード
package Net::InstaMapper; use strict; use warnings; use utf8; use Time::Local; use LWP::UserAgent; use JSON::Syck; our $VERSION = 0.001001; my $NUM_DATA_MAX = 10000; my $HIDE_DEVICE_KEY = 0; my $API_KEY = ''; # set_api_key( $api_key ); sub set_api_key { return ( $API_KEY = shift ) ? 1 : 0; } # sub __get_time { my $datetime = shift || ''; my $re = qr/(\d{4})\D(\d{2})\D(\d{2}) \D? (?:(\d{2})\D(\d{2})(?:\D(\d{2}))?)?/x; my @t = reverse $datetime =~ $re; if( @t ) { $t[5] -= 1900; $t[4] -= 1; } else { @t = localtime time; } return timelocal @t; } # $arrayref = get_positions( $from, $to, $limit ); sub get_positions { my ( $from, $to, $limit ) = @_; my $from_ts = __get_time($from); my $to_ts = __get_time($to); return [] unless $API_KEY; # refer http://www.instamapper.com/fe?page=api for details my $api_uri = sprintf 'https://www.instamapper.com/api?action=getPositions&key=%s&num=%d&from_ts=%s&format=json', $API_KEY, $limit || $NUM_DATA_MAX, $from_ts, ; my $ua = LWP::UserAgent->new; my $res = $ua->get( $api_uri ); my $data = JSON::Syck::Load( $res->content || {} )->{positions} || []; $data = [ map { $_->{device_key} = '*' x 13 if $HIDE_DEVICE_KEY; $_; } grep { $_->{timestamp} <= $to_ts; } @$data ]; return $data; } # $json = get_positions_json( $from, $to, $limit ); sub get_positions_json { my $data = get_positions( @_ ); return JSON::Syck::Dump( $data ); } # hide_device_key( $1_or_0 ); sub hide_device_key { return defined ( $HIDE_DEVICE_KEY = shift ) ? 1 : 0; } 1; __END__

