Posted at 2012-06-17 15:51:04 under モータースポーツ (by key)

ボルボ のアダプティブクルーズコントロールに興味があって、セーフティパッケージ搭載の XC60 に試乗してきました。

ボルボは数年前までフォードのグループで、我が家のコンパクトカーKugaにもボルボ製直列5気筒をベースにしたエンジンが搭載されており、個人的にはわりと親近感のわくブランドです。 最近は中国資本になってしまったようですが、スカンジナビアデザインや安全性を優先するクルマ作りはきちんと継承されているみたい。

Volvo XC60
photo by Carcomparing
Continue reading
Posted at 2012-03-31 23:44:13 under ライフログ (by key)

3月末日でBeProudを退職しました。

2009年12月に前職の開発メンバや方針と合わなくなって退職し、 トンガッてて面白そうな会社ということでBeProudに転職してから2年と4ヶ月の短い期間でしたが、 いつでも前向きでアジャイル開発を地で行く多くの仲間達と一緒に仕事をすることができました。

Continue reading
Tags: beproud
Posted at 2012-03-31 00:54:53 under テクノロジ (by key)

MongoDBのニュースレターで MongoEngine を知った。

てっきり MongoDB Engine のことかと思ってサイトを覗いてみたら、 サイトの体裁がぜんぜん違うし10gen official evangelistのソフトウェアということだし、どうやら違うプロダクトである模様。 ちょっと気になって調べてみたところわりと素性が良さそう。

schemalessなデータベースを利用していて困るのはデータセット内に何があるかわからなくなることなので、個人的には保存時に何かしらのバリデーションが必要だと思ってます。 スキーマを定義可能なライブラリはいくつかありますが、django-mongodb-engineはdjangoモデルの拡張フィールドセットだけ、 mongokitはスキーマ定義が出来るものの埋め込みドキュメントがサポートされておらず、帯に短し襷に長しといった状況です。

で、mongoengineのドキュメントを読んだ限りではその辺りをクリアしており、なかなか良さそうだな〜という判断。

直近で使う機会がありそうなので、いろいろ試してまた紹介したいと思います。

Tags: mongodb, python
Posted at 2012-03-26 22:09:55 under テクノロジ (by key)

SSL通信を行うサイトを作ったりなんかしています。

django + fastcgiプロセスの組み合わせでリダイレクトする処理を確認していたところ、 アプリケーションがプロトコルスキームを認識出来ずにhttp://〜にリダイレクトされる問題がありました。

最初はアプリケーションが固定値でhttp://〜と出力しているのかと思い、 自分が書いた部分のコードやサードパーティのライブラリを含めて調査しまくった結果、 どうやらfastcgiプロセスがプロトコルをハンドリング出来ていないようでした(pdb埋め込んで追いかけまくった)。

で、ダメ押しでnginx fastcgi sslなどでググりまくって得た回答は nginxのコンフィグを適切に設定しないさい というものでした。

参考: FastCGI application behind NGINX is unable to detect that HTTPS secure connection is used

というわけで、以下のようなコンフィグを書いたところ、きちんと動くようになりました。

server {
    listen 443;

    # 省略
    location / {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:8083;
        fastcgi_pass_header Authorization;
        fastcgi_params HTTPS on;
        fastcgi_intercept_errors off;
    }
}

djangoのビュー関数が処理するrequestオブジェクト(内部オブジェクトを失念してしまったけどwsgi関連?)には アプリケーション実行時の各種環境変数が含まれていますが、この中にHTTPSというキーがありプロトコル判別にはその値を利用しています。 SSLアクセス時には、ウェブサーバ側で強制的に値を突っ込むことで解決することが出来るというわけですね。

というわけで久々のエントリは備忘録でした。

Tags: django, python
Posted at 2012-01-22 18:04:31 under テクノロジ (by key)

MyBikeに特定の位置情報をマスクする機能を追加しました。

どんなところで使っているかというと、GarminのGPSログをアップロードして地図や自転車のデータを見られる機能があるんですが、 例えば自宅から会社まで移動する際のログを取り続けると、始点終点を含めたポリラインが地図に描画されてしまい、自宅も会社もモロバレになってしまいます。

内部的にはこんな構造でデータを格納しています。クエリ一発で1行帰ってくるからすごく高速だし、 単純なループでグラフライブラリやGoogle Maps APIに渡すことが出来るので、システム全体としての負荷は激減しました。

activity_document = {
    'records' [
        {
            'timestamp': '2012-01-03T13:32:57',
            'speed': 35.0,
            'location': [135.0, 45.0],
        },
        {
            'timestamp': '2012-01-03T13:32:58',
            'speed': 36.0,
            'location': [135.0, 45.0],
        },
        {
            'timestamp': '2012-01-03T13:32:59',
            'speed': 38.0,
            'location': [135.0, 45.0],
        },
    ]
}
db.activity_record.insert(activity_documents)

MongoDBには位置情報を取り扱うための2Dインデックスというものがあって、 長方形や円に含まれる ドキュメントを 取得することができます。 次のように計算することで、自宅やオフィスを隠蔽できるなと考えたわけです。

位置情報全体 - 隠したい位置情報 = 表示する位置情報

ドキュメント内に情報を直列で持っている(recordsは配列になっている)ので records.location にインデックスを張ればいいや〜と簡単に考えていたのですが、 MongoDBの理解が浅くて罠にハマりました…。

罠。

  • nested arrayにはインデックスが張れない
  • embedded objectのみを取り出す方法が無い

こんなことが出来ません:

#records内のobjectにインデックスを指定…は出来ない
# 本来は records.0.location などとすべきだから。
db.activity_record.ensureIndex({'records.location':'2d'})

※MongoDB 2.0からインデックス作れるらしい。が、後述の問題は残る。

こんなことも出来ません:

# 経度、緯度から近い情報を取得…と言ってもドキュメントが丸っと帰ってくる
# 意味なし
db.activity_record.find({'location': {'$near': [130.0, 45.0]}})

仕方が無いので、データが増えることを覚悟の上で、時間と位置情報だけを持つコレクションを追加しました。 以下のドキュメントをデータ数分、activity_timestamp_locationというコレクションに保存します。

timestamp_location_doc = {
    'timestamp': '2012-01-03T13:32:59',
    'location': [135.0, 45.0]
}
db.activity_timestamp_location.insert(timestamp_location_doc)

最終的にGoogle Maps APIに渡す際は、次のように処理をしています。

# 隠すべき位置情報と時刻を取得する

# 隠したい場所の緯度経度、半径(km)
longitude, latitude = 135.0, 45.0
distance = 1

# 地球の半径
earthRadius = 6371

# 隠したい場所と周囲を指定して、位置と時刻を検索
results = db.activity_timestamp_location.find({
    'location': {
        "$within": {
            "$centerSphere": [[longitude, latitude], distance / earthRadius]
        }
    }
})
hidden_timestamp = [result['timestamp'] for result in results]

# 全てのデータから、隠したい場所の時刻を除外する
locations = [record['location'] for record in activity_record_document['records'] if record['timestamp'] not in hidden_timestamp]

GPS機器を使用した場合には(少なくともGarminは)時刻をキーとして利用できるので、 それを利用してマッチングをかけています。

ループ回して隠してる辺りがイマイチですが、速度的にはストレスを感じるほどでは無いのでしばらくこのままで行こうと思います。


環境。

  • MongoDB 2.0.2
  • pymongo 2.1.1

Tags: mongodb