ソーシャルネットワークを使用して都市環境の魅力を評価し、人気のある場所、朝は町の人々が活動している場所、夕方は週末にどこに行っているのか、そして彼らの行動に影響を与えているものを見つけることに興味を持ちました。
この問題を明確にするために、モスクワで公開されたジオメトリの分析( 「ckeck-in」 )に関する小さなプロジェクトを開始しました。 データは過去24時間に収集され、リアルタイムで地図上にリアルタイムで表示されます。 誰が私たちがこのベンチャーから得たものを気にしている-猫へようこそ。
![](https://habrastorage.org/getpro/habr/post_images/82b/494/057/82b494057bc60d9882d67e9159b1d7d2.png)
VKを選ぶ理由 もちろん、彼の選択は偶然ではありませんでした-今日、それは最も人気のあるロシアのソーシャルネットワークであり、他のどこにもないほど多くのデータです。 VKontakteには、ロシアに毎日約3,600万人の訪問者がいます。 これらのうち、約900万人が首都にあります。 そしてこれは、少なくとも半分のマスコビットが毎日彼らのページを訪れることを意味します。 おそらく、分析に最適なサイトを見つけることは不可能です。
そのため、分析対象のオーディエンスを見つける際の問題は解決されました。 いくつかの質問がありました。
- そして、技術的な観点から、VKontakteから必要なジオタギングデータを収集できますか? つまり、公開VKontakte APIはユーザーのチェックに関する情報を「取得」しますか? はい、入手するだけでなく、モスクワ全土で定期的にリアルタイムで入手してください。
- このデータは、実験のアイデアにどの程度適合しますか?
VKの技術サポートと一緒に、最初の質問は肯定で答えられました(ビンゴ!しかし、それについては以下で詳しく説明します)。 2番目はどうですか? マップは、自宅またはデスクトップPCから収集された興味深いデータのみで構成されますか? 統計をもう一度見てみましょう。LiveInternetによると 、訪問の少なくとも20〜25%はAndroidとiOSであり、Opera Miniは基盤を失っていますが、 4番目に人気のあるブラウザーを保持しています。 モバイルブームはVKonakteの視聴者をspareしみませんでした。訪問者のますます重要な部分はポータブルガジェットです。 「chekins」は通常、リビングルームやキッチンではなく、余暇の間にさまざまな公共の場所で作られていることを考慮する価値があります。 これは、私たちが受け取る情報によって、市全体の活動傾向を判断できることを意味します。
実装
それでは、最も興味深い部分である技術的な部分に移りましょう! いくつかの革新的な技術が使用されたとは言えませんが、おそらく以下に示す技術のいくつかは、大衆にとって興味深いものになるでしょう。
VC APIのドキュメントの短い分析により、 places.getCheckinsメソッドを見つけることができました。 このメソッドは、検索の開始点近くのジオタグを持つすべての投稿を返します。 素晴らしいですか? もちろん! ただし、APIリクエストの数は1秒あたり5に制限されており、これは私たちの規模ではありません。いつかこの制限に到達するでしょう。 executeメソッドは(VKの操作上のアドバイスに対するテクニカルサポートのおかげで)助けになりました。これにより、20の呼び出しを1つに収めることができました。 主なことは、executeにネストされたサブクエリの限られた実行時間を満たすことです。 このアプローチのもう1つの利点は、情報処理の一部をVKサーバーに転送できることです。
これで、VKに必要なデータを直接アピールする準備がすべて整いました。 問題は小さいように思えます-首都の中心の座標をplaces.getCheckinsメソッドと出来上がりに転送する必要があります! しかし、そこにはありませんでした。 このアプローチでは、APIから返されたオブジェクトは右上隅に積み上げられましたが、都市の左側は空でした。 私はちょっとしたトリックに頼らなければなりませんでした。モスクワの地図をセクションに分割し(下の写真)、1つの大きなエリアではなく、いくつかの小さなエリアにインタビューし始めました。
![](https://habrastorage.org/getpro/habr/post_images/93b/281/796/93b28179633487d8a8a100589c4dc0ea.png)
状況は改善されましたが、APIは必要な座標を常に返すとは限りませんでした。 見つけることができる限り、VKがその拠点から場所を認識できなかった場合、これが起こりました。 ここで、緯度と経度を取得する唯一の方法は、 wall.getByIdメソッドを使用してユーザーの壁で緯度と経度に直接アクセスすることです。 places.getCheckinsが ' wall_id 'を ' id 'フィールドに渡すことを考えると、そのような操作を実行することは難しくありませんでした。
継続的なデータ収集のために、次の内容でexecuteメソッドを常に呼び出すことで、ジオタグの新しいバッチを定期的に呼び出す小さなデーモンが作成されました。
いくつかのコード
var COUNT_CHEKING = 18; var LAST_TIME = %time_replace%; var max_time = 0; var cordinatesPonint = [ [55.91843, 37.379394], [55.908424, 37.541442], [55.895336, 37.682891], [55.822116, 37.821593], [55.742574, 37.839446], [55.658996, 37.836699], [55.579897, 37.687011], [55.583002, 37.551055], [55.646599, 37.387633], [55.72943, 37.38214], [55.829059, 37.399993], [55.827516, 37.541442], [55.816715, 37.680144], [55.730977, 37.680144], [55.66132, 37.677398], [55.66132, 37.537322], [55.740255, 37.535949], [55.754071, 37.617504], [55.989164, 37.184386], [55.519302, 37.520843], ]; var placesMoscow = []; var iCordinatesPonint = 0; while(iCordinatesPonint < cordinatesPonint.length) { placesMoscow = placesMoscow + [API.places.getCheckins({ "latitude":cordinatesPonint[iCordinatesPonint][0], "longitude":cordinatesPonint[iCordinatesPonint][1], "count":COUNT_CHEKING, "timestamp": LAST_TIME })]; iCordinatesPonint = iCordinatesPonint + 1; } var walls; var iMoscow = 0; var returnObj = []; var wallsIds = []; var returnObj2 = []; var i; while(iMoscow < placesMoscow.length) { var getWallId = placesMoscow[iMoscow]@.latitude; var i = 1; while(i < getWallId.length) { if(getWallId[i] == 0) { wallsIds = wallsIds + [placesMoscow[iMoscow][i].id]; } else { if(max_time < placesMoscow[iMoscow][i].date) { max_time = placesMoscow[iMoscow][i].date; } returnObj = returnObj + [{ "lat": placesMoscow[iMoscow][i].latitude, "lng": placesMoscow[iMoscow][i].longitude, "id": placesMoscow[iMoscow][i].id, "time": placesMoscow[iMoscow][i].date }]; } i = i + 1; } iMoscow = iMoscow + 1; } if(wallsIds.length > 0) { walls = API.wall.getById({"posts": wallsIds}); i = 0; while(i < walls.length) { if(max_time < walls[i].date) { max_time = walls[i].date; } returnObj2 = returnObj2 + [{ "coordinates": walls[i].geo.coordinates, "time": walls[i].date, "id": wallsIds[i] }]; i = i + 1; } } var moscow = { "checkins": returnObj, "wals": returnObj2 }; return { "max_time" : max_time, "spb": { "checkins": [], "wals": [] }, "moscow" : moscow};
デーモン( Pythonで作成 )は、約3秒ごとにVKサーバーをポーリングします。 ' timestamp 'パラメーターのおかげで、古いデータのフィルタリングを心配することなく、新しいデータのみを簡単に受信できます。
VKから取得した結果が解析されます-座標と時間がバイナリファイルとMongoDBに書き込まれます。 元々はMongoを使用してクラスターを作成することを計画していましたが、後にこのアイデアを放棄することが決定されたため、バイナリファイルは一種のデータバックアップを実行します。
デーモンが新しいチェックを処理するとすぐに、http経由でポイント座標がローカルデーモンに送信され、2番目のデーモンがwebsoket接続を保持します。 2番目のデーモンが座標を受け取った後、すぐにブラウザーでユーザーに座標を送信します(そして、はい、ブラウザーはwebsocketを開いて応答を待ちます)。
さて、これらすべてに少しのダイナミクスを与えるために、地図に表示される各ジオタグに美しいアニメーションを固定することにしました。
![](https://habrastorage.org/getpro/habr/post_images/730/36a/ee2/73036aee2863672baa23285dfaccb513.gif)
地図作成の基礎として、標準のGoogleマップを少しカスタマイズして使用しました。色の反転+ガンマと明るさの調整により、マークとの最適なコントラストを作成しました。
クライアント部分はPHPで記述されており、過去24時間以内にMongoDBからデータを取得します。
開始が与えられます
そのため、すべての準備が完了し、別のマシンで安全に開始しました。 質問は最後まで延期されていましたが、これまで以上に重要になりました。モスクワで1日に何人のチェカインが完成したのでしょうか。 カードを記入するのに十分ですか? 幸いなことに、この点に関するすべての懸念はすぐに解消されました。最初の日、サーバーはジオタグ付きの約10,000件の出版物を引き出して処理しました。 2日目は、この数字が間違いや偶発的な活動の急増ではないことを確認しただけです。
最初の結果
興味深い観察から:旧赤10月工場の敷地にある創造的なクラスターは、モスクワの重要な文化の中心地になり、今日は赤の広場と同じくらい人気があります。
マスコビテ人のお気に入りの通りはアルバートであり、2012年にモスクワ当局によってストレシニコフ車線からクズネツキーまで開かれた歩行者ゾーンは、首都で最も人気のあるものの1つになりました!
このような都市空間の研究は、市内のあらゆる場所やイベントで実施できます。 そのため、この週末、フェスティバル「 冬のベストシティー 」と合わせて、ライトインスタレーションの立ち上げ中のアクティビティを監視しました。 新しいマークが10〜30秒ごとに燃え上がるのを見るのはひどく刺激的でした。 インストールは明らかに誰も無関心なままにしたわけではありません。
![](https://habrastorage.org/getpro/habr/post_images/63e/584/0eb/63e5840eb6585f1cfde93ec96f87d9d8.jpg)
あなたはこのすべてがここに住んでいると感じることができます -whatsupmoscow.ru
すべてのプロジェクトソースコードは GitHub で入手でき ます。