Azure Maps Web SDK のベスト プラクティス
このドキュメントでは、Azure Maps Web SDK のベスト プラクティスに焦点を当てていますが、示されているベスト プラクティスと最適化の多くは、他のすべての Azure Maps SDK にも適用できます。
Azure Maps Web SDK を使用すると、大規模な空間データセットをさまざまな方法でレンダリングするための強力なキャンバスが提供されます。 場合によっては、同じ方法でデータをレンダリングする方法が複数ありますが、データ セットのサイズと望ましい機能に応じて、1 つの方法が他の方法よりもパフォーマンスが優れていることがあります。 この記事では、パフォーマンスを最大化し、スムーズなユーザー エクスペリエンスを実現するためのベスト プラクティスおよびヒントとコツについて説明します。
一般に、マップのパフォーマンスを向上させるには、レイヤーとソースの数、使用するデータセットとレンダリング スタイルの複雑さを減らす方法を探します。
セキュリティの運用方法
セキュリティのベスト プラクティスの詳細については、「認証のベスト プラクティス」を参照してください。
最新バージョンの Azure Maps を使用する
Azure Maps SDK と、この SDK で使用される可能性のある外部依存関係ライブラリには、定期的なセキュリティ テストが実施されています。 既知のセキュリティの問題は、適切なタイミングで修正されてから、運用環境にリリースされます。 ホストされているバージョンの Azure Maps Web SDK の最新メジャー バージョンをアプリケーションで参照している場合は、セキュリティ関連の修正を含むマイナー バージョンの更新プログラムすべてを自動的に受け取ります。
npm モジュールを使用して Azure Maps Web SDK を自己ホストする場合は、常に最新のマイナー バージョンを参照するように、package.json
ファイル内で Azure Maps npm パッケージのバージョン番号とキャレット (^) 記号を組み合わせて使用してください。
"dependencies": {
"azure-maps-control": "^3.0.0"
}
ヒント
必ず最新バージョンの npm Azure Maps Control を使用してください。 詳細については、npm ドキュメントの「azure-maps-control」を参照してください。
初期マップ読み込みを最適化する
Web ページの読み込み中に最初に行うべきことの 1 つは、ユーザーが空のページを見続けることにならないように、できるだけ早くレンダリングを開始することです。
マップの準備完了イベントを確認する
同様に、マップの初期読み込み時には、ユーザーに空のマップが表示されないように、多くの場合できるだけ早くデータを読み込む必要があります。 マップへのリソースの読み込みは非同期に行われるため、そこに独自のデータをレンダリングする前に、マップが操作可能な状態になるまで待機する必要があります。 2 つのイベントを待機することができます。load
イベントと ready
イベントです。 マップで初期マップ ビューの読み込みが完全に終了し、すべてのマップ タイルが読み込まれると、ロード イベントが発生します。 "スタイルの読み込みが完了していません" というエラーが表示された場合は、load
イベントを使用し、スタイルが完全に読み込まれるのを待つ必要があります。
ready イベントは、マップの操作を開始するために必要な最小限のマップ リソースがあれば発生します。 より正確には、マップで初めてスタイル データが読み込まれるときに ready
イベントがトリガーされます。 多くの場合、ready イベントは load イベントの半分の時間で発生するため、マップへのデータの読み込みをより早く開始できます。 スタイルの再読み込みがトリガーされる可能性があるため、現時点ではマップのスタイルまたは言語を変更しないでください。
Azure Maps Web SDK の遅延読み込みを行う
マップがすぐに必要ではない場合、必要になるまで Azure Maps Web SDK の読み込みを遅延させます。 これにより、Azure Maps Web SDK によって使用される JavaScript ファイルと CSS ファイルは、必要になるまで読み込みが遅延されます。 これが行われる一般的なシナリオは、ページ読み込み時点では表示されないタブまたはポップアップ パネルにマップが読み込まれる場合です。
マップの遅延読み込みコード サンプルは、ボタンが押されるまで Azure Maps Web SDK の読み込みを遅延する方法を示しています。 ソース コードについては、マップの遅延読み込みのサンプル コードを参照してください。
マップのプレースホルダーを追加する
ネットワークの制限やアプリケーション内のその他の優先事項のためにマップの読み込みに時間がかかる場合は、マップのプレースホルダーとして小さい背景画像をマップの div
に追加することを検討します。 これにより、マップの div
の読み込み中に空白が埋められます。
初期化時にマップのスタイルとカメラの初期オプションを設定する
多くの場合は、アプリでマップを特定の場所またはスタイルに読み込む必要があります。 場合により、開発者はマップの読み込みが完了するまで待機 (または ready
イベントを待機) してから、マップの setCamera
または setStyle
関数を使用することがあります。 こうすると、目的のマップ ビューのために必要なリソースを読み込む前に、多くのリソースが既定で読み込まれることになるため、多くの場合、必要な初期マップ ビューの取得にかかる時間が長くなります。 より適切な方法は、マップの初期化時に、必要なマップのカメラとスタイルのオプションをマップに渡すことです。
データ ソースを最適化する
Web SDK には 2 つのデータ ソースがあります。
- GeoJSON ソース:
DataSource
クラスは、GeoJSON 形式の生の場所データをローカルで管理します。 小規模から中規模のデータセット (数十万点を超えるフィーチャー) に適しています。 - ベクター タイル ソース:
VectorTileSource
クラスは、マップのタイル システムに基づいて、現在のマップ ビューのベクター タイルとして形式設定されたデータを読み込みます。 大規模から非常に大規模なデータセット (数百万または数十億点のフィーチャー) に最適です。
大規模なデータセットにタイルベースのソリューションを使用する
何百万ものフィーチャーを含む、より大規模なデータセットを使用する場合、最適なパフォーマンスを得るには、ベクターまたはラスター イメージ タイル サービスなどのサーバー側ソリューションを使用してデータを公開する方法をお勧めします。
ベクター タイルは、タイルのフォーカス領域にクリップされたジオメトリを使用してビュー内のデータのみを読み込むように最適化されており、タイルのズーム レベルのマップ解像度と一致するように一般化されています。
Azure Maps Creator プラットフォームでは、ベクター タイル形式でデータを取得します。 その他のデータ形式は、Tippecanoe などのツールを使用できます。 ベクター タイルの操作の詳細については、GitHub の「Mapbox awesome-vector-tiles readme」を参照してください。
サーバー側でデータセットをラスター イメージ タイルとしてレンダリングし、マップ SDK の TileLayer クラスを使用してデータを読み込むカスタム サービスを作成することもできます。 こうすると、マップに読み込んで管理する必要がある画像の数が最大でも数十個のみになるため、パフォーマンスが大きく向上します。 ただし、生データはローカルでは使用できないため、ラスター タイルの使用にはいくつかの制限があります。 多くの場合、ユーザーがクリックしたシェイプを確認するなど、任意の種類の相互作用エクスペリエンスを強化するには、セカンダリ サービスが必要です。 また、ラスター タイルのファイル サイズは、圧縮されたベクター タイル (一般化され、ズーム レベルが最適化されたジオメトリを含む) よりも大きくなることが多くあります。
データ ソースの詳細については、「データ ソースを作成する」を参照してください。
複数のデータセットを 1 つのベクター タイル ソースに結合する
マップで管理する必要があるデータ ソースが少ないほど、表示されるすべてのフィーチャーをより高速に処理できます。 特に、タイル ソースの場合は、2 つのベクター タイル ソースを組み合わせることでタイルを取得するための HTTP 要求の数を半分に減らせば、ファイル ヘッダーが 1 つだけになるため、データの合計量が若干小さくなります。
複数のデータセットを 1 つのベクター タイル ソースに結合するには、Tippecanoe などのツールを使用します。 複数のデータセットを 1 つのフィーチャー コレクションに結合したり、ベクター タイル内でソースレイヤーと呼ばれる別々のレイヤーに分割したりすることができます。 ベクター タイルのソースをレンダリング レイヤーに接続するときは、そのレイヤーでレンダリングするデータを含むソースレイヤーを指定します。
データ更新によるキャンバスの更新回数を減らす
DataSource
クラスのデータを追加または更新するには、いくつかの方法があります。 次の一覧に、適切なパフォーマンスを確保するためのさまざまな方法と考慮事項を示します。
- データ ソースの
add
関数を使用すると、データ ソースに 1 つ以上のフィーチャーを追加できます。 この関数が呼び出されるたびに、マップのキャンバスの更新がトリガーされます。 多数のフィーチャーを追加する場合は、データセットをループ処理してフィーチャーごとにこの関数を呼び出すのではなく、それらを配列またはフィーチャー コレクションに結合し、この関数に 1 回渡します。 - データ ソースの
setShapes
関数は、データ ソース内のすべてのシェイプを上書きするために使用できます。 それは、内部的にはデータ ソースのclear
とadd
の関数を組み合わせたもので、マップ キャンバスの更新を 2 回ではなく 1 回行い、さらに高速です。 データ ソース内のすべてのデータを更新する場合は、必ずこの関数を使用してください。 - データ ソースの
importDataFromUrl
関数を使用すると、URL を介して GeoJSON ファイルをデータ ソースに読み込むことができます。 データは、ダウンロードされるとデータ ソースのadd
関数に渡されます。 GeoJSON ファイルが別のドメインでホストされている場合は、その別のドメインがクロス ドメイン要求 (COR) をサポートしていることを確認してください。 そうでない場合は、ドメイン上のローカル ファイルにデータをコピーするか、COR が有効なプロキシ サービスを作成することを検討します。 ファイルが大きい場合は、ベクター タイル ソースに変換することを検討してください。 - フィーチャーが
Shape
クラスでラップされている場合、シェイプのaddProperty
、setCoordinates
、およびsetProperties
関数のすべてで、データ ソースでの更新とマップ キャンバスの更新がトリガーされます。 データ ソースのgetShapes
およびgetShapeById
関数によって返されるすべてのフィーチャーは、Shape
クラスで自動的にラップされます。 複数のシェイプを更新する場合は、データ ソースのtoJson
関数を使用して JSON に変換し、GeoJSON を編集してから、このデータをデータ ソースのsetShapes
関数に渡す方が高速です。
データ ソース clear 関数の不必要な呼び出しを避ける
DataSource
クラスの clear 関数を呼び出すと、マップ キャンバスが更新されます。 clear
関数が連続して複数回呼び出された場合、マップが各更新の実行を待機している間、遅延が発生する可能性があります。
これは、データ ソースをクリアし、新しいデータをダウンロードし、データ ソースをもう一度クリアしてから、新しいデータをデータ ソースに追加するアプリケーションの一般的なシナリオです。 必要なユーザー エクスペリエンスに応じて、次の代替手段を使用することをお勧めします。
- 新しいデータをダウンロードする前にデータをクリアし、それからデータ ソースの
add
またはsetShapes
関数に新しいデータを渡します。 これがマップ上で唯一のデータセットである場合、そのマップは、新しいデータをダウンロードしている間は空になります。 - 新しいデータをダウンロードしてから、データ ソースの
setShapes
関数に渡します。 これにより、マップ上のすべてのデータが置き換えられます。
使用されていないフィーチャーとプロパティを削除する
アプリで使用されないフィーチャーがデータセットに含まれている場合は、削除します。 同様に、必要のないフィーチャーのプロパティがあれば削除します。 これにはいくつかの利点があります。
- ダウンロードする必要があるデータの量が減ります。
- データをレンダリングするときにループ処理する必要があるフィーチャーの数が減ります。
- データドリブンの式やフィルターを簡略化または削除できる場合があります。これは、レンダリング時に必要な処理が少なくなることを意味します。
フィーチャーに多数のプロパティやコンテンツが含まれている場合は、データ ソースに追加されるものをレンダリングに必要なものだけに制限し、必要に応じて他のプロパティやコンテンツを取得するための別のメソッドまたはサービスを使用する方が、はるかにパフォーマンスが高くなります。 たとえば、選択するとマップ上に場所を表示するシンプルなマップの場合、詳細なコンテンツが大量に表示されます。 マップ上に場所をレンダリングする方法をカスタマイズするためにデータ ドリブンのスタイルを使用する場合は、必要なプロパティのみをデータ ソースに読み込みます。 詳細なコンテンツを表示するときは、フィーチャーの ID を使用して、他のコンテンツを個別に取得します。 コンテンツがサーバーに格納されている場合は、サービスを使用して非同期的に取得することで、マップを最初に読み込むときにダウンロードする必要のあるデータの量を低減できます。
さらに、フィーチャーの座標の有効桁数を減らすことで、データのサイズを大幅に削減することもできます。 座標に 12 桁以上の小数点以下桁数が含まれていることは珍しくありませんが、小数点以下 6 桁の精度は約 0.1 m です。これは多くの場合、座標が表す場所よりも正確です (建物の室内レイアウトなどの小さな位置データを使用する場合は、6 桁の小数点以下桁数をお勧めします)。 小数点以下桁数が 6 桁を超えても、データのレンダリング方法には違いがない可能性が高く、ユーザーがより多くのデータをダウンロードしなければならなくなり、メリットはありません。
GeoJSON データを処理するための便利なツールの一覧がこちらにあります。
個別のデータ ソースを使用して迅速にデータを変更する
場合によっては、ストリーミング データのライブ更新の表示やフィーチャーのアニメーション化などのために、マップ上のデータをすばやく更新することが必要になります。 データ ソースが更新されると、データ ソース内のすべてのフィーチャーがレンダリング エンジンによってループ処理され、レンダリングされます。 急速に変化するデータから別のデータ ソースに静的データを切り離し、各更新時に再レンダリングされる機能の数を減らすことで、全体的なパフォーマンスを向上させます。
ライブ データでベクター タイルを使用する場合、更新をサポートする簡単な方法は、expires
応答ヘッダーを使用することです。 既定では、ベクター タイル ソースまたはラスター タイル レイヤーには、expires
日付になるとタイルが自動的に再読み込みされます。 この機能がマップ内のトラフィック フローとインシデント タイルで使用され、新しいリアルタイムのトラフィック データがマップに表示されるようになります。 この機能を無効にするには、マップの refreshExpiredTiles
サービス オプションを false
に設定します。
GeoJSON データ ソースのバッファーとトレランスのオプションを調整する
DataSource
クラスを使用すると、生の位置データを即時レンダリングのためのローカルのベクター タイルに変換できます。 これらのローカル ベクター タイルは、タイル間のスムーズなレンダリングが確実になるように、バッファーを少量使用して生データをタイル領域の境界にクリップします。 buffer
オプションが小さいほど、ローカル ベクター タイルに格納される重複するデータが少なくなり、パフォーマンスが向上しますが、レンダリング アーティファクトが変更する可能性が大きくなります。 このオプションを微調整して、レンダリング アーティファクトを最小限に抑えつつパフォーマンスを適切に組み合わせるようにしてください。
DataSource
クラスには、レンダリングを目的としてジオメトリの解像度を下げるときに、Douglas-Peucker の単純化アルゴリズムと共に使用する tolerance
オプションもあります。 この許容値を大きくすると、ジオメトリの解像度が低下し、その代わりにパフォーマンスが向上します。 このオプションを微調整して、データセットのジオメトリの精度とパフォーマンスを適切に組み合わせるようにしてください。
GeoJSON データ ソースの最大ズーム オプションを設定する
DataSource
クラスを使用すると、生の位置データを即時レンダリングのためのローカルのベクター タイルに変換できます。 既定では、これはズーム レベル 18 まで実行されます。そのレベルでさらに拡大すると、ズーム レベル 18 用に生成されたタイルからデータがサンプリングされます。 これは、これらのレベルで拡大するときに高解像度を必要とするほとんどのデータセットに適しています。 ただし、州や都道府県の多角形を表示する場合など、縮小したときに表示される可能性が高いデータセットを処理する場合は、データ ソースの minZoom
オプションを 12
などの小さい値に設定すると、計算の量、発生するローカルのタイル生成、データ ソースによって使用されるメモリが減少し、パフォーマンスが向上します。
GeoJSON の応答を最小化する
サービスを介して、またはフラット ファイルを読み込むことによってサーバーから GeoJSON データを読み込むときは、ダウンロード サイズが必要以上に大きくならないように、データを最小化して不要な空白文字を削除するようにします。
URL を使用して生の GeoJSON にアクセスする
GeoJSON オブジェクトを JavaScript 内にインラインで保存することは可能ですが、このオブジェクト用に作成した変数と、別の Web worker 内でそれを管理するデータ ソース インスタンスとの全体にコピーが格納されるため、さらに多くのメモリが使用されます。 代わりに URL を使用して GeoJSON をアプリに公開すると、データ ソースでデータ ソース Web worder にデータの単一のコピーが直接読み込まれます。
レンダリング レイヤーを最適化する
Azure Maps には、マップ上にデータをレンダリングするための異なる複数のレイヤーが用意されています。 これらのレイヤーをご自身のシナリオに合わせて調整し、パフォーマンスと全体的なユーザー エクスペリエンスを向上させるために利用できる最適化が多数あります。
レイヤーを 1 回作成して再利用する
Azure Maps Web SDK は、データ ドリブンです。 データ ソースにデータが格納された後、レンダリング レイヤーに接続されます。 マップ上のデータを変更する場合は、データ ソース内のデータを更新するか、レイヤーのスタイル オプションを変更します。 多くの場合、変更ごとにレイヤーを削除してから再作成するよりも、この方が高速です。
シンボル レイヤー上のバブル レイヤーを検討する
バブル レイヤーを使用すると、マップ上にポイントを円としてレンダリングし、データ ドリブンの式を使用して、その半径と色のスタイルを簡単に設定できます。 円は WebGL での描画が容易なシェイプであるため、画像を読み込んでレンダリングする必要があるシンボル レイヤーよりも、レンダリング エンジンで高速にレンダリングできます。 この 2 つのレンダリング レイヤーのパフォーマンスの違いは、数万個のポイントをレンダリングするときに顕著です。
HTML マーカーとポップアップは控えめに使用する
レンダリングに WebGL を使用する Azure Maps Web コントロールのほとんどのレイヤーとは異なり、HTML のマーカーとポップアップの場合はレンダリングに従来の DOM 要素を使用します。 そのため、ページに追加される HTML マーカーとポップアップが多くなるほど、DOM 要素数も多くなります。 数百個の HTML マーカーまたはポップアップを追加すると、パフォーマンスが低下する可能性があります。 大規模なデータセットの場合は、データをクラスター化するか、シンボルまたはバブル レイヤーを使用することを検討します。
複数のピンを使用したポップアップの再利用コード サンプルは、1 つのポップアップを作成し、その内容と位置を更新して再利用する方法を示しています。 ソース コードについては、複数のピンを使用したポップアップの再利用のソース コードを参照してください。
しかしながら、マップ上にレンダリングするポイントが少ない場合は、HTML マーカーの簡便さが好まれることがあります。 また、必要な場合は簡単に HTML マーカーをドラッグ可能にすることができます。
レイヤーを結合する
マップには数百個のレイヤーをレンダリングすることができますが、レイヤーが多いほど、シーンのレンダリングにかかる時間が長くなります。 レイヤーの数を減らす方法の 1 つは、類似したスタイルを使用しているか、データドリブンのスタイルを使用してスタイルを設定できるレイヤーを結合することです。
たとえば、すべてのフィーチャーに、true
または false
の値に設定できる isHealthy
プロパティが使用されているとします。 このプロパティに基づいて、異なる色のバブルをレンダリングするバブル レイヤーを作成するとします。これを行うには、次の一覧に示すように、最もパフォーマンスが低いものから最もパフォーマンスが高いものまで複数の方法があります。
isHealthy
の値に基づいてデータを 2 つのデータ ソースに分割し、色オプションをハードコーディングしたバブル レイヤーを各データ ソースにアタッチします。- すべてのデータを 1 つのデータ ソースに格納し、ハードコーディングされた色オプションと
isHealthy
プロパティに基づくフィルターを使用して、2 つのバブル レイヤーを作成します。 - すべてのデータを 1 つのデータ ソースに格納し、
isHealthy
プロパティに基づく色オプションを確認するcase
スタイル式を使用して、1 つのバブル レイヤーを作成します。 これを示すコード サンプルはこちらです。
var layer = new atlas.layer.BubbleLayer(source, null, {
color: [
'case',
//Get the 'isHealthy' property from the feature.
['get', 'isHealthy'],
//If true, make the color 'green'.
'green',
//If false, make the color red.
'red'
]
});
スムーズなシンボル レイヤー アニメーションを作成する
シンボル レイヤーでは、競合検出が既定で有効になっています。 この競合検出は、2 つのシンボルが重複しないようにすることを目的としています。 シンボル レイヤーのアイコンとテキストのオプションには、2 つのオプションがあります。
allowOverlap
- 他のシンボルとの競合がある場合にシンボルが表示されるかどうかを指定します。ignorePlacement
-シンボルとの競合を他のシンボルに許可するかどうかを指定します。
これらのオプションは、どちらも既定では false
に設定されています。 シンボルをアニメーション化するとき、アニメーションの各フレームに対して競合検出の計算が実行され、アニメーションの速度が低下して滑らかに見えなくなる可能性があります。 アニメーションを滑らかにするには、これらのオプションを true
に設定します。
シンボルの単純なアニメーションのコード サンプルでは、シンボル レイヤーの単純なアニメーション化方法を示しています。 このサンプルのソース コードについては、シンボルの単純なアニメーションのサンプル コードを参照してください。
ズーム レベルの範囲を指定する
データが次のいずれかの条件に該当する場合は、レイヤーの最小および最大のズーム レベルを指定して、ズーム レベルの範囲外の場合はレンダリング エンジンでスキップできるようにします。
- データがベクター タイル ソースから提供される場合 (さまざまなデータの種類のソース レイヤーは、ある範囲のズーム レベルでのみ使用できることが多い)。
- 0 から 24 のすべてのズーム レベルにタイルがないタイル レイヤーを使用していて、タイルがあるレベルでのみレンダリングする必要があり、欠落しているタイルを他のズーム レベルのタイルで埋めようとしない場合。
- 特定のズーム レベルでのみレイヤーをレンダリングする場合。
すべてのレイヤーには
minZoom
とmaxZoom
のオプションがあり、ロジックmaxZoom > zoom >= minZoom
に基づいて、これらのズーム レベルの間である場合にレイヤーがレンダリングされます。
例
//Only render this layer between zoom levels 1 and 9.
var layer = new atlas.layer.BubbleLayer(dataSource, null, {
minZoom: 1,
maxZoom: 10
});
タイル レイヤーの境界とソース ズーム範囲を指定する
既定では、タイル レイヤーのタイルは地球全体に読み込まれます。 ただし、タイル サービスに特定の領域のタイルしかない場合、この領域の外側ではマップによるタイルの読み込みが試みられます。 これが発生すると、各タイルに対する要求が行われ、回答が待機されます。これにより、マップによって行われる他の要求がブロックされ、そのために他のレイヤーのレンダリング速度が低下する可能性があります。 タイル レイヤーの境界を指定すると、その境界ボックス内にあるタイルだけがマップで要求されます。 また、タイル レイヤーが特定のズーム レベル間でのみ使用可能な場合は、同じ理由で最小および最大のソース ズームを指定します。
例
var tileLayer = new atlas.layer.TileLayer({
tileUrl: 'myTileServer/{z}/{y}/{x}.png',
bounds: [-101.065, 14.01, -80.538, 35.176],
minSourceZoom: 1,
maxSourceZoom: 10
});
基本マップが表示されない場合に空白のマップ スタイルを使用する
基本マップを完全に覆うマップにレイヤーが重ねて表示されている場合は、基本マップがレンダリングされないようにマップ スタイルを blank
または blank_accessible
に設定することを検討します。 これを行う一般的なシナリオとして、不透明度または透明な領域が欠落している地球全体のタイルを基本マップの上にオーバーレイする場合があります。
画像またはタイル レイヤーをスムーズにアニメーション化する
マップ上の一連の画像またはタイル レイヤーを通してアニメーション化するとします。 多くの場合、画像またはタイル レイヤーごとにレイヤーを作成して不透明度を変更する方が、単一レイヤーのソースをアニメーション フレームごとに更新するよりも高速です。 不透明度をゼロに設定してレイヤーを非表示にし、不透明度をゼロより大きい値に設定して新しいレイヤーを表示する方が、レイヤー内のソースを更新するより高速です。 または、レイヤーの表示と非表示は切り替えができますが、レイヤーのフェード期間を必ずゼロに設定します。そうしないと、レイヤーが表示されるときにアニメーション化されます。その場合、新しいレイヤーが表示されるより先に、前のレイヤーが非表示になるため、ちらつきの現象が発生します。
シンボル レイヤーの競合検出ロジックを調整する
シンボル レイヤーには、アイコンとテキストの両方を対象に存在する allowOverlap
および ignorePlacement
という 2 つのオプションがあります。 これら 2 つのオプションを使用して、シンボルのアイコンまたはテキストを重ねることができるか、または重なっているかを指定します。 false
に設定した場合、シンボル レイヤーで各ポイントをレンダリングするときに計算が実行されます。これは、レイヤー内で既にレンダリングされている他のシンボルと競合しているかどうかを確認するためであり、競合している場合は、競合するシンボルはレンダリングされません。 これは、マップの乱雑さを軽減し、レンダリングされるオブジェクトの数を減らすのに適しています。 これらのオプションを false
に設定すると、この競合検出ロジックはスキップされ、すべてのシンボルがマップ上にレンダリングされます。 パフォーマンスとユーザー エクスペリエンスが最適な組み合わせになるように、このオプションを調整します。
大きなポイント データのセットをクラスター化する
多数のデータ ポイントのセットを処理する場合、特定のズーム レベルでレンダリングしたときに、ポイントの多くが重なっていて、表示されたとしても一部分のみであることがあります。 クラスタリングは、互いに近いポイントをグループ化し、単一のクラスター化されたポイントとして表現するプロセスです。 ユーザーがマップを拡大すると、クラスターは個々のポイントに分解されます。 これにより、レンダリングする必要があるデータの量を大幅に削減し、マップの乱雑さを減らして、パフォーマンスを向上させることができます。 DataSource
クラスには、ローカルでデータをクラスター化するためのオプションがあります。 さらに、ベクター タイルを生成する多くのツールにもクラスタリング オプションがあります。
さらに、パフォーマンスを向上させるために、クラスターの半径のサイズを大きくします。 クラスターの半径が大きいほど、追跡とレンダリングの対象となるクラスター化されたポイントが少なくなります。 詳細については、「Web SDK でのポイント データのクラスタリング」を参照してください。
重み付けされてクラスタリングされたヒート マップを使用する
ヒート マップ レイヤーを使用すると、数万個のデータ ポイントを簡単にレンダリングできます。 より大規模なデータ セットの場合は、データ ソースに対してクラスタリングを有効にし、小さいクラスター半径を使用して、クラスターの point_count
プロパティを高さマップの重みとして使用することを検討します。 クラスター半径のサイズがわずか数ピクセルの場合、レンダリングされたヒート マップに視覚的な違いはほとんどありません。 より大きなクラスター半径を使用すると、パフォーマンスが向上しますが、レンダリングされたヒート マップの解像度が低下する場合があります。
var layer = new atlas.layer.HeatMapLayer(source, null, {
weight: ['get', 'point_count']
});
詳細については、「クラスタリングとヒート マップ レイヤー」を参照してください。
画像のリソースを小さく保つ
シンボル レイヤーでアイコンを、または多角形レイヤーでパターンをレンダリングするために、画像をマップ画像スプライトに追加できます。 これらの画像を小さく維持し、ダウンロードする必要があるデータの量を最小限に抑え、マップ画像スプライトに占める領域の量を減らします。 size
オプションを使用してアイコンを拡大縮小するシンボル レイヤーを使用する場合は、マップ上に表示する予定の最大サイズの画像を使用し、それより大きいものは使用しないようにします。 これにより、使用するリソースを最小限に抑えながら、高解像度でアイコンがレンダリングされるようになります。 さらに、単純なアイコン画像用に、より小さなファイル形式として SVG を使用することもできます。
式を最適化する
データドリブンのスタイルの式を使用すると、マップ上のデータをフィルター処理したり、スタイルを設定したりするための柔軟性と機能が提供されます。 式は、さまざまな方法で最適化できます。 以下に、ヒントをいくつか示します。
フィルターの複雑さを軽減する
フィルターを使用すると、データ ソース内のすべてのデータをループ処理し、各フィルターがフィルターのロジックに一致するかどうかを確認できます。 フィルターが複雑になると、パフォーマンスの問題が発生する可能性があります。 これに対処するための方法としては、次のようなものがあります。
- ベクター タイルを使用する場合は、データを異なる複数のソース レイヤーに分割します。
DataSource
クラスを使用する場合は、そのデータを個別のデータ ソースに分割します。 データ ソースの数とフィルターの複雑さのバランスを調整します。 データ ソースが多すぎても、パフォーマンスの問題が発生する可能性があります。そのため、テストを実施して、ご自分のシナリオに何が最適かを確認することが必要な場合があります。- レイヤーに対して複雑なフィルターを使用する場合は、スタイルの式で複数のレイヤーを使用して、フィルターの複雑さを軽減することを検討します。 レイヤーの数が多くてもパフォーマンスの問題が発生する可能性があるので、スタイルの式を使用できる場合は、スタイルをハードコーディングした多数のレイヤーを作成しないようにします。
式によってエラーが生成されないようにする
式は、レンダリング時に計算や論理演算を実行するコードを生成するためによく使用されます。 アプリケーションの他の部分のコードと同じように、計算と論理が意味をなすものであり、エラーが発生しやすいものではないことを確実にする必要があります。 式にエラーがあると、式の評価で問題が発生し、パフォーマンスが低下して、レンダリングの問題が発生する可能性があります。
注意する必要がある一般的なエラーの 1 つは、すべてのフィーチャーに存在するとは限らないフィーチャー プロパティに依存する式を使用することです。 たとえば、次のコードでは、式を使用してバブル レイヤーの color プロパティをフィーチャーの myColor
プロパティに設定しています。
var layer = new atlas.layer.BubbleLayer(source, null, {
color: ['get', 'myColor']
});
データ ソース内のすべてのフィーチャーに myColor
プロパティがあり、そのプロパティの値が色である場合、上記のコードは正常に機能します。 データ ソース内のデータを完全に把握しており、すべてのフィーチャーの myColor
プロパティに有効な色が設定されていることを確信できる場合は、これが問題になることはありません。 そうは言っても、このコードにエラーが発生しないことを確実にするために、case
式を has
式と共に使用して、フィーチャーに myColor
プロパティがあることを確認します。 それがある場合は、to-color
タイプの式を使用して、そのプロパティの値を色に変換することができます。 色が無効な場合は、フォールバック色を使用できます。 次のコードは、これを実行し、フォールバック色を緑色に設定する方法を示しています。
var layer = new atlas.layer.BubbleLayer(source, null, {
color: [
'case',
//Check to see if the feature has a 'myColor' property.
['has', 'myColor'],
//If true, try validating that 'myColor' value is a color, or fallback to 'green'.
['to-color', ['get', 'myColor'], 'green'],
//If false, return a fallback value.
'green'
]
});
最も限定的なものから最も限定的でないものへブール式を順序付ける
最も具体的なものから最も具体的でないものの順に並べ替えることで、複数の条件付きテストが含まれるブール式を使用する場合に必要となる条件付きテストの合計数を減らします。
式を簡略化する
式は強力であり、複雑になることもあります。 複雑でない式の評価速度が向上します。 たとえば、単純な比較が必要な場合は、['==', ['get', 'category'], 'restaurant']
のような式の方が、['match', ['get', 'category'], 'restaurant', true, false]
のような match 式を使用するよりも適しています。 この場合、チェックする対象のプロパティがブール値であれば、get
式はさらに単純な ['get','isRestaurant']
になります。
Web SDK のトラブルシューティング
Azure Maps Web SDK を使用して開発するときに発生する一般的な問題のいくつかをデバッグするためのヒントを次に示します。
Web コントロールを読み込んでもマップが表示されないのはなぜですか?
確認事項:
- マップで認証オプションを完了していることを確認します。 認証を行わないと、マップには空のキャンバスが読み込まれ、ブラウザーの開発者ツールの [ネットワーク] タブに 401 エラーが返されます。
- インターネット接続ができることを確認します。
- コンソールで、ブラウザー開発者ツールのエラーの有無を確認します。 一部のエラーにより、マップがレンダリングされない場合があります。 アプリケーションをデバッグします。
- サポートされているブラウザーを使用していることを確認します。
すべてのデータが地球の反対側に表示されます。どうなっているのでしょうか?
Azure Maps SDK においては、座標 (位置とも呼ばれる) は [longitude, latitude]
という地理空間業界の標準形式で配置されます。 この同じ形式は、Azure Maps SDK 内で使用される形式設定されたコア データである GeoJSON スキーマで座標を定義する方法でもあります。 データが地球の反対側に表示されているときは、ほとんどの場合、経度と緯度の値が座標または位置情報で反転されていることが原因と考えられます。
HTML マーカーが Web コントロールの間違った場所に表示されるのはなぜですか?
確認事項:
- マーカーにカスタム コンテンツを使用する場合は、
anchor
およびpixelOffset
オプションが正しいことを確認してください。 既定では、コンテンツの下部中央がマップ上の位置に揃えられます。 - Azure Maps の CSS ファイルが読み込まれていることを確認します。
- HTML マーカーの DOM 要素を調べて、アプリの CSS がマーカーに追加され、その位置に影響を与えているかどうかを確認します。
シンボル レイヤーのアイコンまたはテキストが間違った場所に表示されるのはなぜですか?
anchor
および offset
オプションが、マップ上の座標に合わせる画像またはテキストの部分と揃うように正しく構成されていることを確認してください。
マップを回転したときにのみシンボルの配置が正しくない場合は、rotationAlignment
オプションを確認します。 既定では、シンボルはマップのビューポートと共に回転し、ユーザーに対して正立するように表示されます。 ただし、シナリオによっては、rotationAlignment
オプションを map
に設定して、マップの向きに合わせてシンボルをロックすることが望ましい場合があります。
マップをピッチ調整または傾けた場合にのみシンボルの配置が正しくない場合は、pitchAlignment
オプションを確認します。 既定では、マップをピッチ調整または傾けたときに、シンボルはマップのビューポートで正立した状態を維持します。 ただし、シナリオによっては、pitchAlignment
オプションを map
に設定して、マップのピッチに合わせてシンボルをロックすることが望ましい場合があります。
マップにデータがまったく表示されないのはなぜですか?
確認事項:
- ブラウザーの開発者ツールでコンソールにエラーがないか確認します。
- データ ソースが作成されてマップに追加されていることと、データ ソースが以前にマップに追加されたレンダリング レイヤーに接続されていることを確認します。
- コードにブレーク ポイントを追加し、ステップ実行します。 データがデータ ソースに追加され、データ ソースとレイヤーがマップに追加されていることを確認します。
- レンダリング レイヤーからデータドリブンの式を削除してみてください。 そのうちの 1 つに、問題の原因となっているエラーが含まれている可能性があります。
サンドボックス化された iframe で Azure Maps Web SDK を使用できますか?
はい。
サポートを受ける
次に示すのは、問題に応じて Azure Maps のサポートを受けるためのさまざまな方法です。
データの問題や住所に関する問題を報告するには、どうすればよいですか?
Azure Maps フィードバック サイトを使用して、問題を報告します。 データの問題を報告する詳細な手順については、「Azure Maps にデータのフィードバックを送信する」を参照してください。
Note
送信された問題ごとに、それを追跡するための一意の URL が生成されます。 解決時間は、問題の種類と、変更が正しいことを確認するために必要な時間によって異なります。 変更は、レンダリング サービスでは毎週の更新に表示され、ジオコーディングやルーティングなどの他のサービスでは毎月の更新に表示されます。
サービスまたは API のバグを報告するには、どうすればよいですか?
[サポート リクエストの作成] ボタンを選択して、Azure の [ヘルプとサポート] ページで問題を報告します。
Azure Maps のテクニカル ヘルプはどこで入手できますか?
Azure Maps Power BI ビジュアルに関連する質問については、Power BI サポートに問い合わせてください。
その他すべての Azure Maps サービスについては、Azure サポートに問い合わせてください。
特定の Azure Maps の機能に関する質問またはコメントについては、Azure Maps 開発者フォーラムを使用してください。
次の手順
アプリケーションのユーザー エクスペリエンスを向上させるためのヒントについては、次の記事を参照してください。
Azure Maps と地理空間の業界で使用される用語の詳細については、こちらを参照してください。