地図上の200万ポイント? 簡単!

少し前までは、サービスを作成する(およびモジュールを「バッファーに入れる」)ために、SQLデータベースからマップ上にあるポイントをすばやく選択する方法を考え出す必要がありました。

システム全体の理解を妨げないように、コードは小さくなります。









TK



そのため、「入口」には200万ポイント(これまでのところ、実際のポイントはまだ小さいため、テストポイントのみ)、Googleマップ(または基本的にはYandex)のベースがあり、各ポイントには座標があります。 ユーザーは、マップ内を移動し、すべてのポイントを確認する必要があります。サーバーは、毎秒200人の「希望する」出席を考慮して、フロアラックのサイズにしないでください。



アイデア?




多くのポイントがあります。 たくさん。 マップの境界線へのポイントのエントリをチェックするバリアントは適切ではありません((x1 <x <x2)や(y1 <y <y2)など)。このような要求は20〜50ミリ秒で行われ、マップを移動するたびに送信量を実行する必要があったためデータは数十キロバイトになりました(そして、テキスト情報を含む「バラン」をポイントに追加できるので、メガバイトになります)。 クエリキャッシュは、パフォーマンスが低いため、実際には意味がありません。



ソリューションの検索で、次のポイントに到達しました。

1.マップタイルの操作(正方形、ブロック)

2.データベースのポイントqtreeタイルに保存する

3.ズームせずにマップ内を移動する場合、「新しい」タイルからポイントのみをロードします



qtreeの理解en.wikipedia.org/wiki/Quadtree

このkoti.mbnet.fi/ojalesa/quadtree/quadtree_intro.htmの内容を理解する



データベース内の各ポイントの「ツリー」を含む行は、01320232312222100231210323203のようになります(桁数は最大ズームレベルに等しくなります)。

実際、世界地図が2x2の4つの部分に分割されている場合、ポイントは1ブロック(スクラッチから番号付けを省略し、簡略化のために番号0の「メインブロック」)、このブロックを2x2で再び分割すると、ブロック3など。 各ズームレベルで、「ツリー」を「より深く」見る必要があります。







この形式でデータを保存する利点は何ですか?

美しさは、タイルとスケールの座標を知っているので、132023231という形式のqtreeを取得し、このスケールレベルでマップ上のこのエリアに含まれるすべてのポイントを見つけるには、 point_qtree LIKE '132023231%'という条件でリクエストを行う必要があります(次の行のサブストリングを探します)最初の文字)。 この場合、point_qtreeフィールドにインデックスを付ける必要があります。これは、サンプルの速度が最大レベルに達することを意味します。 SQLはqtreeツリーを構築し、選択タスクを可能な限り簡素化します。



やったー ポイントの選択にかかる時間が何倍も短くなりました。



地図を扱いましょう


マップ内を移動するとき、いくつかのことを行う必要があります。





マップAPIで表示されるタイルを決定するには、マップウィンドウの座標とズームレベルを要求できます。 そして、これらのデータに基づいて、左上と右下のエッジのタイルを取得し、その間にある他のすべてをリストします。



012、013、021、020の形式の配列を取得します。



oldTileと呼ばれる変数に保存します。



マップ内を移動するたびに、すべてのタイルを計算して現在のoldTile配列と比較し、oldTileに含まれていないすべてのタイルをリストするnewTile配列を取得する必要があります。 次に、各タイルのポイントを選択するためにajaxリクエストをサーバーに送信する必要があります(リクエストで新しいタイルの配列を送信できますが、個別のリクエストに分割する目的を以下で説明します)、たとえば/ point / 012、新しいポイントをマップに追加します(古いものをクリアせずに) 。 次に、単純なoldTile = oldTile + oldTileを実行します。



マップを拡大するとき、oldTile(およびオプションの1つであるマップ上のポイント)をクリアする必要があります。2番目のオプション:ポイントをクリーニングしないで、oldTile配列もクリアする必要はありません。 ) その後、「計画に従って」地図の表示可能なタイルなどを計算します。



この方法で得られるもの:





システム最適化の次の段階として:

1.データベースに新しいポイントを追加する場合、ツリーブランチ全体のすべての配列を強制的にmemcacheに更新します。 したがって、さらにリクエストnginx + memcacheが消えないようにし、データが常に関連するようにします。これにより、memcacheから大根に切り替えることができ、「コールドスタート」を恐れることがなくなります。



All Articles