Yandex.Maps JS APIでポリゴンに署名するのに必要な計算量

JS API Yandex.Mapsでは、マップ上にさまざまなオブジェクトを作成できます。 それらの1つはポリゴンです。これにより、ユーザーマップの対話性を向上させることができます。個々のエリアを強調表示したり、非ポイントオブジェクトの位置を表示したりできます。 たとえば、この方法では、新しい四半期またはピザの配達エリアの建設計画を表示できます。



Yandex.Maps APIのユーザーは、ポリゴンの上に署名を追加することについて長い間疑問を抱いていました。 人々は、適切な場所でオブジェクトに署名を追加したり、隠したり、塗り直したりするためのトリッキーなソリューションを提供しましたが、そのようなソリューションは複雑で柔軟性に欠けることが判明しました。



たとえば、Yandex Research Departmentは、世界地図でいくつかの研究を行った後、ポリゴンに署名するための便利なツールを作成するようにというリクエストを受け取りました。





Dahl辞書からの地域の単語、つまりロシアの平均よりもはるかに頻繁に検索される単語のマッピング



実際、このタスクは重要なものでした。 想像してみてください。各ポリゴンについて、署名を表示するのに最適な中心を決定する必要があります。各スケールで、署名が適合するかどうか、選択したズームで非表示にする必要があるかどうか、各ズームでスタイルを変更し、すべてを再計算します。 つまり、インフォグラフィックをそれほど複雑にしないためには、たくさん汗をかいて、追加のデータをたくさん準備する必要があります。



ポリゴンのラベルを作成することは、日常的なタスクの1つです。 Photoshopですべてを座って描画できますが、可能な限り柔軟になります。





画像エディタでは、署名をインタラクティブにすることは非常に難しく、多角形のポイントの配列、将来の署名のテンプレートを指定して、すぐに視覚化することがはるかに簡単です。



さまざまな国に関するクエリで最も人気のある単語を表示します



その結果、ポリゴンの署名に関するユーザーの問題を解決し、カスタマイズの自由度を提供するモジュールを作成することにしました。



適切な署名センターを決定するアルゴリズムの選択



私たちが直面している主なタスクの1つは、ユーザーが追加設定なしで最終結果を得ることができるように、署名を表示するのに最適なセンターを決定することでした。



センター検索の問題を解決するためのアルゴリズムはいくつかあります。



重心位置の計算



これが最初に思い浮かぶことです。 数学および物理学では、重心(平面図の幾何学的中心)はすべての点の算術平均です。

重心検索の実装は非常に簡単で、アルゴリズム自体は高速です。 それはすべてのように思えますが、図が凸多角形ではないか、穴がある場合、ポイントは図の外側に落ちるか、署名を表示するために間違った場所に落ちる可能性があります。





これは、重心を決定した結果です。 ハバロフスクとカムチャッカの領土のポイントは、署名を表示するのに好ましくない場所に落ちたことがわかります。



到達不能の極または最大内接円のポイント







そのような点を見つける問題はすでに多くの人に発生しているため、アクセス不能の極を見つけるためのさまざまなアルゴリズムがありますが、残念ながら、公開されたソリューションは複雑な実装を必要とし、実行するには遅すぎます。



まず第一に、理論を研究した後、常に既製のソリューションを探しています。 そのため、 Mapboxの開発者から興味深いものを見つけることができて幸運でした



アクセシビリティの極を見つけるためのいくつかの解決策を検討し、いくつかの問題に直面し、アルゴリズムの1つに触発されて、独自のアルゴリズムを作成することができました。これにより、エラーを排除し、検索を高速化し、高品質の結果を取得する精度を高めました。



検索はどうですか



このアルゴリズムは、象限木のツリーに基づいています 。 つまり、調査対象のポリゴンについて、ポリゴンが完全に配置される領域(象限)が構築されます。 さらに、この領域は4つの等しい部分に分割され、各象限ごとに再帰的に繰り返されます。







条件を満たす細胞でのみ研究が続けられます。 セルは、ポリゴンの中心からエッジまでの距離と、セルを表す円の半径の合計が、象限での以前の計算よりも大きい場合に適していると見なされます。







重心アルゴリズムは、フォールバックとしてこのモジュール内でも使用されます。見つかったアクセス不能ポールが必要な精度を満たさない場合。

詳細はここで説明します



アルゴリズムの結果







アルゴリズムの精度がどのように異なるかを見ることができます。「問題」ポリゴンの「中心」は、署名の場所により適しています。









ポリゴンの「中心」を見つけるためのアルゴリズムを選択した後、署名モジュールの作業を開始しました。



モジュール操作アルゴリズム



ポリゴンの署名はいくつかの段階で行われます。

入力時に、モジュールには署名用のポリゴンの頂点が配置されたコレクションが与えられます。



最初に、各ポリゴンの座標は、到達不能ポールを見つけるためにモジュールに渡され、署名が配置されるポイントの座標が出力で取得されます。 このセンターモジュールは、特別なオプションを使用してセンターを再定義しなかった場合、すべてのズームに適用されます。 同じズームで2回以上計算しないように、ポリゴンの中心の値は署名容量のステータスとともにキャッシュされます。







次に、署名がポリゴンに適合するかどうかを理解するタスクに直面します。

モジュールは署名テンプレートを取り出し、それに基づいてHtmlElementを作成します。



objectManager.add({ ... options: { labelLayout: '<h1>{{properties.name}}</h1>' }, properties: { name: 'nameOfMyPolygon' } });
      
      









次に、モジュールはタグからイメージがロードされるのを待機し(存在する場合)、getBoundingClientRect()を使用して、この署名サイズが計算されます。 残念ながら、DOMに挿入されていない要素のサイズを通知できるメソッドはありません。 したがって、最初に署名をレンダリングする必要があります。 また、サイズを受け取るときに「ちらつき」(署名の表示と非表示)を防ぐために、ユーザーの目からは見えない特別なコンテナに描画されます。







モジュールは中心オフセットや表示エラーなどのさまざまなオプションをサポートしているため、最初に適用され、次に署名が適合するかどうかがチェックされます。



 objectManager.add({ ... options: { labelLayout: '<h1>{{properties.name}}</h1>', labelOffset: [80, -50] }, properties: { name: 'nameOfMyPolygon' } });
      
      









署名の中心は地理座標の形式で表示され、署名要素の寸法はピクセル単位で表示されるため、中心の地理座標は変換されます。

さらに、この中心から要素の幅と高さは脇に置かれ、示されている場合は計算の誤差が適用されます。



 objectManager.add({ ... options: { labelLayout: '<h1>{{properties.name}}</h1>', labelOffset: [80, -50], labelPermissibleInaccuracyOfVisibility: 10 }, properties: { name: 'nameOfMyPolygon' } });
      
      









結果の座標は地理座標に変換され、署名がポリゴンに適合するかどうかがチェックされます。







これはすべて、ズームごと、および次のパートで詳しく説明する2種類の署名で発生します。



モジュールの機能



ウェブマスターが直面する最も不快な問題を調べた後、私たちはあなたの個人的なニーズに合わせてモジュールを便利に設定するのに役立つ多くのオプションを作成しました。



重要なタスクの1つは、レイアウトをポリゴンに挿入する便利な方法を作成することでした。 特別なオプションを使用すると、Twig / Django Templatesテンプレート言語の基本構文を文字列としてサポートするHTMLレイアウトを指定できます。



各ポリゴンには、メインとスモールの2種類の署名があります。







これは、主署名の小さなコピーを表示するために行われます。



各署名は、署名パラメーターの管理が行われる1つのポリゴンに属します。



さまざまなスケールで署名設定を制御できるようにするために、追加のオプションが導入されました。 ユーザーが署名センターの標準定義に満足していない場合は、署名を表示する必要な座標を設定できます。





左側-自動中心、右側-座標に設定[72、92]



また、署名の位置と表示エラーからインデントを設定することもできます。この値は、ポリゴンの境界を超える署名の量を意味します。





インデント30px上下





25pxの精度



スタイルがなかったわけではなく、テキストのサイズと色を変更したり、クラス属性の値を設定したりできます。



これらの署名パラメーターはすべて、ズームごとに構成するか、すべての縮尺に1つの値を設定できます。



これはすべて、ユーザーがモジュールの動作をカスタマイズできるようにするために必要です。

可能なオプションの全リストは次のとおりです。



イベントは注意なく放置されませんでした。 署名で発生したすべてのイベント(クリック、ホバリング...)は親ポリゴンに転送され、APIの基本イベントに対応します。それらの前に「ラベル」を追加するだけです。



署名の可視性をすばやく変更するために、すべてのポリゴンが持つ特別な状態が作成されました。 モジュールのインスタンスを介して受け取った後、署名のタイプを変更したり、完全に隠すことさえできます。 たとえば、縮小されたコピーの上にマウスを置いたときに、メインシグネチャが収まらないポリゴンに表示したい場合があります。

また、この状態を介して、表示されている署名の現在のタイプ、または署名が配置されている座標を取得できます。



ソリューションの設計とインターフェース



多くの場合、テキストは署名の主要部分の1つであるため、特別な注意を払いました。



領域の境界を横断するとき、および半透明のポリゴン上で署名を明確に読み取るために、ストロークによって背景から署名を分離する必要がありました。 ほとんどの場合に適した2つの標準スタイルを作成しました。





上の画像:プレーンテキスト、ストロークなし

下の画像:2つの標準モジュールスタイル



テキストを左に揃える場合、複数行のキャプションは読みにくいため、中央揃えをデフォルトに設定しました。







署名レイアウトは任意のhtmlとして設定できるため、署名に画像を追加することは難しくありません。これは、たとえば、地図上に天気予報を作成したり、チャートでデータを視覚化したりするのに便利です。







柔軟な署名のレイアウトは、たとえば、世界の国の旗や地域の紋章を示すインフォグラフィックにも役立ちます。







それで何を得たの





おわりに



便利な署名作成の基本的なニーズを満たすことができる基本的な使用シナリオについて説明することにしましたが、モジュールが機能することを希望する場合は、それらを確実に検討します。



興味を持った人のために



モジュールの使用を開始するには、 このリポジトリの指示からいくつかのポイントを実行する必要があります





jsfiddle.net/51qtdx3a/5



すべての質問について、提案やフィードバックをお送りします。テクニカルサポートをご希望の場合はご連絡ください。コメントに提案を残してください。 私たちのツールがウェブマスターの生活を少し楽にし、地図上のデータの視覚化においてあなたに新しい視野を開くことを願っています。



All Articles