ベスト プラクティス: マップ操作
マウス操作を必要とするツールを作成する場合、マウスがクリックされるのを待つ代わりに Draw サーフェスを使用します。Draw サーフェスを使用すれば、アプリケーションのユーザによって描画されたジオメトリを簡単にキャプチャできます。これらのジオメトリを取得したら、それをグラフィックス レイヤに追加するか、または別の操作の入力として使用できます。
マップ クリックをキャプチャするツールを作成するには、次の処理を行います。
- Draw オブジェクトを使用してマウス入力をキャプチャします。最新のビューア アプリケーションでは、マップ クリックをキャプチャするツールが 1 つだけとは限りません。そのため、マップの MouseClick イベントを待つのではなく、必ず Draw オブジェクトを使用してください。Draw オブジェクトは一度に 1 つしか有効になりません。ある Draw オブジェクトがすでに有効なとき、さらに別の Draw オブジェクトを有効にすると、2 番目の Draw オブジェクトが自動的に無効になります。
- Draw オブジェクトが自動的に無効になった場合に対処するために Draw オブジェクトの IsEnabled プロパティの変更を待ちます。たとえば、アクティブな Draw オブジェクトを使用してマップ クリックをキャプチャし、その個別属性表示の結果をダイアログ ボックスに表示する個別属性表示ツールを実装するとします。この場合、マップ入力をキャプチャする別のツールが選択された時点で、このダイアログ ボックスを閉じます。そのためには、IsEnabled プロパティの変更を待つ必要があります。
次のコード スニペットでは、マップ上に新しい Draw サーフェスを作成し、DrawMode を Point に設定して、IsEnabled プロパティを待ちます。
private Identify identifyDialog;
private IdentifyTask identifyTask;
private Draw draw;
public void Execute(object parameter)
{
if (draw == null)
{
draw = new Draw(MapApplication.Current.Map) { DrawMode = ESRI.ArcGIS.Client.DrawMode.Point };
draw.DrawComplete += DrawComplete;
// Listen to the IsEnabled property. This is to detect cases where other tools have
// disabled the Draw surface.
// Utils class shown below.
Utils.RegisterForNotification("IsEnabled", draw, identifyDialog, OnDrawEnabledChanged);
}
draw.IsEnabled = true;
MapApplication.Current.ShowWindow("Identify", identifyDialog, false, null, IdentifyDialogHidden);
}
// Fires when the drawing action is complete. Issues an identify operation using the drawn geometry.
private void DrawComplete(object sender, DrawEventArgs e)
{
MapPoint clickPoint = e.Geometry as MapPoint;
IdentifyParameters identifyParams = new IdentifyParameters()
{
Geometry = clickPoint,
MapExtent = MapApplication.Current.Map.Extent,
LayerOption = LayerOption.visible,
SpatialReference = MapApplication.Current.Map.SpatialReference
};
if (identifyTask.IsBusy)
identifyTask.CancelAsync();
identifyTask.ExecuteAsync(identifyParams);
GraphicsLayer graphicsLayer = MapApplication.Current.Map.Layers["IdentifyResultsLayer"] as GraphicsLayer;
if (graphicsLayer == null)
{
graphicsLayer = createResultsLayer();
MapApplication.Current.Map.Layers.Add(graphicsLayer);
}
else
{
graphicsLayer.ClearGraphics();
}
Graphic graphic = new Graphic() { Geometry = clickPoint };
graphicsLayer.Graphics.Add(graphic);
}
public class Utils
{
public static void RegisterForNotification(string propertyName, object source, FrameworkElement element,
PropertyChangedCallback callback)
{
//Bind to a depedency property.
Binding b = new Binding(propertyName) { Source = source };
var prop = System.Windows.DependencyProperty.RegisterAttached(
"ListenAttached" + propertyName,
typeof(object),
typeof(UserControl),
new PropertyMetadata(callback));
element.SetBinding(prop, b);
}
}
6/8/2012