C1MapVirtualLayer は、仮想化と非同期データロードをサポートしてマップ上に要素を表示します。一度に表示する要素が多くない場合は、これを使用して、無制限の数の要素を表示できます。そのオブジェクトモデルは C1MapItemsLayer とはまったく異なります。C1MapVirtualLayer では、マップ空間がいくつかの領域に分割されている必要があり、項目のソースは IMapVirtualSource インターフェイスを実装している必要があります。
マップ空間の分割は、MapSlice の C1MapVirtualLayer.Slices コレクションを使って定義されます。各マップスライスはに、その区分の最小ズームレベルが定義され、あるスライスの最大ズームレベルが次のスライスの最小ズームレベルになります。したがって、最後のスライスの最大ズームレベルは、マップの最大ズームレベルになります。さらに、各スライスは、緯度/経度のグリッドに分割されます。
例として次のレイヤを紹介します。
C# |
コードのコピー
|
---|---|
var layer = new C1MapVirtualLayer { Slices = { new MapSlice(2, 2, 5), new MapSlice(4, 4, 10) } }; |
ここには、ズーム5~10 とズーム 10~最大ズームの2つのスライスがあります。ズーム値が元のスライスから別のスライスに移動すると、仮想レイヤはそのソースにデータを要求します。また、最初のスライスは緯度/経度によって2×2に分割されます。つまり、マップは4つの領域に分割され、レイヤは現在表示されている領域のデータのみを要求します。2番目のスライスが 16 個の領域に分割されているのは、ズーム値が大きくなるほど多数に分割した方がパフォーマンスが向上するためです。
IMapVirtualSource インターフェイスを理解するために、Factories サンプルの実装を紹介します。
C# |
コードのコピー
|
---|---|
public class ServerStoreSource : IMapVirtualSource { public void Request(double minZoom, double maxZoom, Point lowerLeft, Point upperRight, Action callback) { if (minZoom < minStoreZoom) return; var client = CreateFactoriesService(); client.GetStoresCompleted += (s, e) => { if(e.Error == null) callback(e.Result); }; client.GetStoresAsync(lowerLeft.Y, lowerLeft.X, upperRight.Y, upperRight.X); } } |
Request メソッドは、マップ空間の1つの領域をパラメータとして受け取るほか、コールバックを使って返される項目のコレクションを受け取ります。この実装は最初に、要求された最小ズームがアプリケーションパラメータより小さいかどうかをチェックし、小さい場合は何もしません。そうでない場合は、Web サービスを呼び出してデータを取得します。
サーバー側には GetStores の実装があります。これは、データベース内のすべての要素を反復処理して、要求された範囲内にある項目を返します。
C# |
コードのコピー
|
---|---|
public List<Store> GetStores(double lowerLeftLat, double lowerLeftLong, double upperRightLat, double upperRightLong) { var stores = new List<Store>(); var dataBase = DataBase.GetInstance(Context); foreach (var store in dataBase.Stores) { if (store.Latitude > lowerLeftLat && store.Longitude > lowerLeftLong && store.Latitude <= upperRightLat && store.Longitude <= upperRightLong) { stores.Add(store); } } return stores; } |
さらに上手な実装としては、すべての項目を反復処理しなくても済むように、あらかじめストアを領域に分割しておきます。