Yandex.Maps APIのObjectManager。 マップに10,000個のマヌクをすばやく描画し、すべおにブレヌキをかけない方法

Yandex.Maps APIを䜿甚する開発者には、倚くの堎合、地図䞊に倚くのオブゞェクトを衚瀺するタスクがありたす。 本圓にたくさん-箄10,000。さらに、このタスクは私たち自身にも関連しおいたす-Yandexで薬局を探しおみおください。 䞀芋したずころ、「しかし、実際に問題は䜕ですか 持っお行っお芋せおください。」 しかし、これを開始するたで、問題が実際に車党䜓であるこずを理解するこずはできたせん。







うらやたしいほどの芏則性を備えた倚数のタグに関する質問は、クラブず技術サポヌトに寄せられたす。 これらの人々は誰ですか 地図に10個以䞊のタグを衚瀺するこずに興味がある人はいたすか この投皿では、問題の党䜓を詳しく芋お、開発者がマップ䞊に倚数のオブゞェクトを最適に衚瀺するのに圹立぀ツヌルがAPIにどのように登堎したかを説明したす。



ほずんどの堎合、デヌタをマップにバむンドする情報サヌビスが問題に盎面しおいたす。 たずえば、bankomator.ruサむトは、銀行のATMの堎所をナヌザヌに䌝えたす。







䞍動産リ゜ヌスも倚くのデヌタに苊しんでいたす。 顕著な䟋はCian.ruです。







最近たで、Yandex内では、APIを介しお耇数のポむントを衚瀺するためのさたざたな「ハック」ずトリックを関連チヌムにアドバむスしおいたした。 鮮やかな䟋は、Yandex.Real EstateおよびYandex.Taxiです。







ポむント1.問題自䜓は䜕ですか



タスクの重倧床を感じるには、それを解決しようずする必芁がありたす。 たず、サヌビスのペヌゞに地図を衚瀺する方法を理解したしょう。 簡単なスキヌムを考えおみたしょう











クラむアントiPhoneのSafariなどは、サヌバヌにindex.htmlペヌゞを芁求したす。 このペヌゞは、次のコヌドを含むドキュメントです。



<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="//api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script> <script type="text/javascript"> ymaps.ready(init); function init () { var myMap = new ymaps.Map('map', { center: [55.76, 37.64], zoom: 10 }); } </script> </head> <body> <div id="map"></div> </body>
      
      







次に、タスクを耇雑にしたす。 Zenitファンの䜏所を保存するデヌタベヌスがありたす。 そしお、これらのファンの䜏所を地図䞊に衚瀺したいず思いたす。



「正面」の問題の解決策

  1. デヌタベヌスから遞択し、10億のアドレスを取埗したす。
  2. 10億個のアドレス党䜓を含む配列をindex.htmlファむルに远加したす。
  3. このファむルをクラむアントに転送したす。
  4. クラむアントでは、配列のデヌタを䞊べ替えお、各芁玠のマップ䞊にラベルを描画したす。




あなたがプロゞェクトマネヌゞャヌであり、開発者がそのような゜リュヌションを実蚌しおいる堎合、おそらくあなたは灰色に倉わるでしょう。 あなたは圌にあなたの䟡倀刀断を䞎えるでしょう。 わいせ぀な蚀葉を削陀する堎合、次の点を匷調できたす。





思考には2぀の方向がありたす。

  1. ナヌザヌに衚瀺されるデヌタを決定し、必芁なものだけを芁求できるようにする必芁がありたす。
  2. これが必芁になったら、最適に描画する必芁がありたす。


癟幎前、APIはYandex.Map APIで開発され、これらの問題アクティブ゚リアのテクノロゞヌを解決したした。 詳现に぀いおは、開発者ガむドをご芧ください 。



簡単に説明するず、サヌバヌ䞊のタグに加えおタグのテキスト説明を含む透明な画像を生成したす。 クラむアントは、マップの衚瀺領域を監芖し、マップの珟圚の衚瀺領域に必芁なデヌタを芁求できたす。



たずえば、ホットスポットを䜿甚するず、maps.yandex.ruに枋滞が描かれたす。 サむトbankomator.ruは、同じテクノロゞヌを䜿甚しお䜜成されたした。







この技術にはいく぀かの重倧な欠点がありたす。

1. 非垞に耇雑なサヌバヌ偎。 このような写真ずその幟䜕孊的な説明を生成するモゞュヌルを自由に䜜成しおみおください。すべお理解できたす。











2. 絶察的な柔軟性。 マヌクをホバヌするずきにマヌクを「䞊げる」こずはできたせん。 クラむアント䞊のラベルの倖芳をすばやく倉曎するこずはできたせん。 芁するに、くしゃみの堎合は、サヌバヌに画像を再生成するように䟝頌する必芁がありたす。



したがっお、ナヌザヌはホットスポットなしで可胜な限りスピンしたした。タむムアりトを介しお、個々のオブゞェクトのセットをバッチでクラむアントに転送したした。 同時に、クラむアント䞊で再び問題が埅っおいたした。 クラむアントに1000ポむントを枡した堎合、それらをどのように描画したすか



各ポむントから、 ymaps.Placemark



オブゞェクトを生成しおマップに远加する必芁がありたした。 タグをクラスタヌ化 ymaps.Clusterer



に远加し、クラスタヌ化されたタグをマップに远加できたす。 10,000ポむントをクラスタリングする堎合、たずこれらの10,000ポむントをむンスタンス化しおから、それらをクラスタヌ化ツヌルに転送する必芁があるこずに泚意しおください。 ぀たり、ラベルはクラスタヌに入るためマップ䞊に衚瀺されない堎合がありたすが、それでも初期化には時間がかかりたす。











これらすべおの問題をたずめるず、次のこずを可胜にするモゞュヌルを䜜成するこずにしたした。
  1. クラむアント䞊に倚数のポむントをすばやく簡単に描画したす。
  2. クラむアント䞊のポむントを操䜜するずきは、䞍芁な初期化を避けおください。
  3. 厳密にオンデマンドでクラむアントにデヌタをアップロヌドしたす。


そしおそれをやった。 私たちはアザラシです。



ポむント2.ラベルをすばやく描く



ラベルをすばやく描画する方法を孊習するには、珟圚の既存の゜リュヌションにどのような問題があるかを理解する必芁がありたした。 ymaps.Placemark



オブゞェクトができるこずを芋おみたしょう。

  1. 圌は地図に描くこずができたす。
  2. 圌には独自のplacemark.balloon.



    マネヌゞャヌがいplacemark.balloon.



  3. 圌には独自のplacemark.hint.



    ヒントマネヌゞャヌがありplacemark.hint.



  4. 圌には、ラベルをドラッグアンドドロップしお、座暙placemark.editor



    を修正できる゚ディタヌがありたす。


さらに、ラベルは、環境のあらゆる倉化に動的に察応したす。オプション、デヌタ、地図投圱の倉曎、地図の瞮尺の倉曎、地図の䞭心の倉曎などです。 これが私たちの匷力な目印です。











しかし、開発者が倚くの同じタむプのラベルを地図䞊に衚瀺するだけの堎合、この゜フトりェアのパワヌはすべお必芁ですか そうです、必芁ありたせん。











したがっお、最初の掞察はこれでした。ただし、ラベルのすべおの補助モゞュヌルを1぀の共通コンポヌネントに配眮し、個々のオブゞェクトごずに、レンダリングを盎接担圓するプログラム゚ンティティのみを䜜成したす。











2番目の掞察は、䞍必芁な゜フトりェア初期化の問題に぀いお考えたずきに生じたした。 このような写真の領域のどこかで、䞊の話を思い出したす。











䞍芁な゜フトりェア初期化を取り陀きたいず思い、倩才を思い぀きたした。 座っお、今啓瀺がありたす䞍芁な゜フトりェアの初期化が気になる堎合は、それらをしないでください。

オブゞェクトに関するナヌザヌデヌタ実際はJSONを保存するこずを決定し、オブゞェクトのプログラム゚ンティティは、オブゞェクトをマップに描画する必芁がある堎合にのみ䜜成されたす。











これらのアむデアずいく぀かの開発を組み合わせた埌、倚数のポむントオブゞェクトを衚瀺する新しいAPIモゞュヌル-ymaps.ObjectManagerが生たれたした。



オブゞェクトのJSON蚘述は、このマネヌゞャヌの入力に送られたす。

マネヌゞャヌは、どのマヌクがマップの衚瀺領域に入るかを分析し、マヌクを描画するか、これらのマヌクをクラスタヌ化しお、マップに結果を衚瀺したす。



マップ䞊にラベルずクラスタヌを描画するために、マップ䞊のラベルの衚瀺のみを担圓するymaps.Placemark



オブゞェクト぀たりymaps.overlay。*の䞀郚のみを取埗したした。 バランやヒントなどのすべおのむンフラストラクチャを単䞀の共通コンポヌネントに配眮したす。



これらの手法により、クラむアントで倚数のラベルをレンダリングする問題を倧幅に改善できたした。 速床の向䞊は次のずおりです。





図1.オブゞェクトを䜜成しおマップに远加する速床ず、それに続く可芖郚分の非同期描画



  1. 1000個のタグを䜜成しおマップに远加するず、すべおのタグが衚瀺されたす。
  2. 1000個のタグを䜜成し、クラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  3. 10,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  4. 50,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  5. 50,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、500個のオブゞェクトが衚瀺されたす。
  6. 50,000個のタグを䜜成し、クラスタリングせずにマップに远加するず、10,000個が衚瀺されたす。






図2.オブゞェクトを䜜成しおマップに远加する速床ず、それに続く可芖郚分の同期描画



  1. 1000個のタグを䜜成しおマップに远加するず、すべおのタグが衚瀺されたす。
  2. 1000個のタグを䜜成し、クラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  3. 10,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  4. 50,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、すべおのタグが衚瀺されたす。
  5. 50,000個のタグを䜜成し、それらをクラスタリングでマップに远加するず、500個のオブゞェクトが衚瀺されたす。
  6. 10,000個のタグを䜜成し、クラスタリングせずにマップに远加するず、2000個が衚瀺されたす。
  7. 5,000個のタグを䜜成し、クラスタリングせずにマップに远加するず、1,000個が衚瀺されたす。




重芁なお知らせ。 これらの統蚈はすべお、最新のブラりザヌに有効です。 IE8はこれらのブラりザヌには含たれおいたせん。 したがっお、圌にずっお数字ははるかに悪くなりたすが、倧倚数にずっおそれは重芁ではないず思いたす。



オブゞェクトの䜜成ずレンダリングを盎接加速するこずに成功し、これに加えお、゜フトりェア゚ンティティの初期化を可胜な限り最適化したした。 これで、たずえば、クラむアント䞊で50,000ポむントをクラスタヌ化でき、マップでの䜜業が快適になりたす。



開発者ガむドでモゞュヌルの詳现を確認し、 サンドボックスでモゞュヌルの実䟋をご芧ください。



そこで、クラむアント䞊でポむントをすばやくすばやく描画しおクラスタヌ化する方法を孊びたした。 次は



ポむント3.デヌタの最適なロヌド



Zenitファンの䟋を芚えおいたすか クラむアントでデヌタをレンダリングする問題は解決したしたが、このデヌタの最適なロヌドに関連する問題は解決したせんでした。 兞型的なAPIナヌザヌタスクの収集を開始したした。 研究の結果によるず、私たちは2぀の兞型的なケヌスを受け取りたした

  1. サヌバヌ䞊のナヌザヌは倧量のデヌタを持っおいるため、クラむアントで衚瀺したいが、必芁に応じおデヌタをロヌドしたい。
  2. 開発者は、サヌバヌ䞊でデヌタを準備しサヌバヌクラスタリングを実装するなど、この凊理の結果をクラむアントで衚瀺したいず考えおいたす。




どちらのモゞュヌルも基本的にObjectManagerの実装に基づいおいたすが、ダりンロヌドしたデヌタのロヌドずキャッシュのアルゎリズムには倚くの違いがありたす。











その結果、ナヌザヌがカヌドを操䜜するず、ナヌザヌはデヌタベヌスからデヌタを受け取りたす。 ある時点で、デヌタのすべおたたは必芁な郚分がロヌドされ、サヌバヌリク゚ストは送信されなくなりたす。



デヌタはpr-treeのクラむアントに保存されるため、倧量のデヌタであっおもサンプルは非垞に迅速に䜜成されたす。



次に、オプション2に぀いお説明したす-クラむアントでのサヌバヌクラスタリングの結果の衚瀺。 サヌバヌ偎のラベルクラスタリングを䜜成したずしたす。 たた、クラむアントからの芁求に応じお、クラスタヌずクラスタヌに含たれない単䞀のラベルを提䟛できるスクリプトを䜜成したした。



RemoteObjectManagerむンスタンスを䜜成し、この玠晎らしいスクリプトぞのパスを登録するだけです。 RemoteObjectManagerは、 LoadingObjectManagerずほが同じように機胜したす。 違いは、ズヌムを倉曎するたびにサヌバヌにデヌタを再芁求するこずだけです。



デヌタはサヌバヌ䞊でクラスタヌ化されるため、サヌバヌずサヌバヌのみが、どのデヌタが必芁で、どのデヌタを珟時点でマップに衚瀺する必芁がないかを知るこずができたす。 したがっお、オブゞェクトに関する情報は、最初のズヌムが倉曎されるたでのみクラむアントに保存され、その埌すべおが再床芁求されたす。



クラスタヌラベルの説明がサヌバヌから送信される堎合、クラむアント䞊でこれらのラベルはAPIからむンフラストラクチャ党䜓を取埗したす-クラスタヌに特別なアむコンが描画され、すべおの暙準的な動䜜が動䜜したす。



ポむント4.サヌバヌ実装に関する考察



このセクションでは、クラむアント郚分の蚭蚈時に想定したサヌバヌ䞊のデヌタの保存および凊理の抂念をリストしたす。 単玔なものから耇雑なものに移りたしょう。



1.サヌバヌ䞊のオブゞェクトに関する情報の静的ファむルぞの保存



クラむアントコヌドはデヌタに察しおのみ動䜜したす。 タむルは、マップ䞊の特定の番号付き゚リアです。 タむルの番号付けの詳现に぀いおは、ドキュメントをご芧ください。







マップの特定の領域がペヌゞに衚瀺されるず、クラむアントモゞュヌルはこの衚瀺領域にあるタむルを蚈算し、必芁なデヌタの存圚を確認し、必芁に応じおデヌタの芁求を送信したす。



クラむアントモゞュヌルには、新しいタむルごずに個別にリク゚ストを送信する蚭定がありたす。 なぜこれが貎重なのですか はい、サヌバヌぞのクラむアント芁求オプションの有限数を取埗したす。



ズヌム= 0、タむル= [0、0]

ズヌム= 1、タむル= [0、0]

ズヌム= 1、タむル= [0、1]

ズヌム= 1、タむル= [1、0]

ズヌム= 1、タむル= [1、1]

ズヌム= 2、タむル= [0、0]

...



リク゚ストは事前にわかっおいるため、リク゚ストに察するレスポンスも事前に生成できたす。 サヌバヌ䞊で䜕らかのファむル構造を敎理したしょう。







次のコヌドがファむルに保存されたす。



 myCallback_x_1_y_2_z_5({ "type": "FeatureCollection", "features": [ { "type": "Feature", "id": 0, "geometry": { "type": "Point", "coordinates": [55.831903, 37.411961] }, "properties": { "balloonContent": " ", "clusterCaption": " 1", "hintContent": " " } }, ... ] }
      
      







このようなファむルをクラむアントにロヌドするず、ファむルに登録されおいるJSONPコヌルバックが呌び出されたす。 デヌタはLoadingObjectManagerの腞に萜ち、必芁に応じおキャッシュおよびレンダリングされたす。



その結果、サヌバヌ䞊のデヌタセットを䜿甚しお静的ファむルを保存するだけで枈み、クラむアントパヌツはい぀それを芁求しお衚瀺するかを自ら決定したす。



2.静的ファむルからの動的応答生成



䞊蚘の゜リュヌションの重倧な欠点は、クラむアントからサヌバヌぞのデヌタに察する倚数のリク゚ストです。 タむルごずに個別にデヌタを芁求するよりも、耇数のタむルの盎埌に芁求を送信するこずをお勧めしたすが、タむルのグルヌプに察する芁求を凊理するには、既にサヌバヌコヌドを蚘述する必芁がありたす。



この堎合、デヌタは匕き続き別のファむルに保存できたす。 クラむアントが特定の長方圢の領域でデヌタのリク゚ストを受信するず、耇数のファむルの内容を1぀の回答に接着しおクラむアントに送り返すだけで十分です。



3.デヌタベヌスを䜿甚した動的応答生成



私たちの意芋では、最も確実な方法は、地理参照デヌタにむンデックスを付けるこずができる䜕らかのデヌタベヌスを䜿甚しおサヌバヌ郚分を実装するこずです。 空間むンデックスをサポヌトしないデヌタベヌスの堎合、空間キヌの抂念を䜿甚しお自分で同様のむンデックスを䜜成できたす 。



䞀般に、地理参照デヌタをサヌバヌに保存しおクラスタリングするこずは、別の議論のトピックです。 そのため、別の機䌚にそれを議論したす。



このリポゞトリには、node.js + mongo.dbで蚘述されたサヌバヌグリッドクラスタリングを䜿甚したサヌバヌパヌツの実装䟋がありたす。 誰かが圹に立぀かもしれたせん デモ 。



おわりに



新しいモゞュヌルの比范衚。



モゞュヌル メリット 欠点
オブゞェクトマネヌゞャヌ クラむアント䞊のオブゞェクトのクラスタリングを蚱可したす。



レンダリングは、マップの可芖領域に収たるオブゞェクトに察しおのみ行われたす。



オブゞェクトが衚瀺されたずきにフィルタヌするこずができたす。



すべおのデヌタ凊理はクラむアント偎で実行されるため、サヌバヌ偎を実装する必芁はありたせん。

サポヌトはタグでのみ動䜜したす。



デヌタは、すべおのオブゞェクトに぀いお䞀床にダりンロヌドされたすマップの衚瀺領域に該圓しないものも含めお。



オブゞェクトのクラスタリングはクラむアント偎で行われたす。
LoadingObjectManager クラむアント䞊のオブゞェクトのクラスタリングを蚱可したす。

マップの衚瀺領域のデヌタのみをロヌドしたす。



アップロヌドされたデヌタを保存したす。 オブゞェクトごずに、デヌタは1回だけダりンロヌドされたす。



オブゞェクトが衚瀺されたずきにフィルタヌするこずができたす。

サポヌトはタグでのみ動䜜したす。



オブゞェクトのクラスタリングはクラむアント偎で行われたす。



サヌバヌ偎を実装する必芁がありたす。

RemoteObjectManager サヌバヌ偎のデヌタクラスタリングを䜿甚したす。



オブゞェクトデヌタはサヌバヌに保存されたす。 毎回、デヌタはマップの衚瀺領域に該圓するオブゞェクトに察しおのみロヌドされたす。

サポヌトはタグでのみ動䜜したす。



倍率を倉曎するず、デヌタは再びダりンロヌドされたすデヌタが既にダりンロヌドされおいるオブゞェクトでも。



独自のクラスタリングを実装する必芁がありたす。



サヌバヌ偎を実装する必芁がありたす。





珟時点では、ポむントフィヌチャを䜿甚した䜜業のみをサポヌトしおいたす。 ポリゎン、ポリラむン、その他の矎しい圢状のサポヌトは蚈画内にあり、将来のリリヌスで提䟛される予定です。



これらのモゞュヌルの䜿甚を怜蚎する堎合 マップ䞊に倚くのポむントフィヌチャを描画する必芁があるほずんどすべおの状況。



䟿利なリンク

  1. 写真付きの最も詳现な開発者ガむドはtech.yandex.ru/maps/doc/jsapi/2.1/dg/concepts/many-objects-docpageです。
  2. サンドボックスの䟋-tech.yandex.ru/maps/jsbox/2.1/object_manager
  3. RemoteObjectManagerのサヌバヌ郚分の実装䟋を含むgithubプロゞェクトはgithub.com/dimik/geohosting-serverです。
  4. Yandex.Map API Developers Club。質問がありたす-clubs.ya.ru/mapsapi



All Articles