我正在尝试设置ESRI本地服务器以显示.mpk
。我有一个像
public class Model
{
private string basemapLayerUri = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer";
private string mapPackage = "D:\\App\\Data\\Canada.mpk";
public Model() { }
public string BasemapLayerUri
{
get { return this.basemapLayerUri; }
set
{
if (value != this.basemapLayerUri)
{
this.basemapLayerUri = value;
}
}
}
public string MapPackage
{
get { return this.mapPackage; }
set
{
if (value != this.mapPackage)
{
this.mapPackage = value;
}
}
}
}
在ViewModel.cs
班我有
public class ViewModel : INotifyPropertyChanged
{
public Model myModel { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public ViewModel()
{
myModel = new Model();
this.CreateLocalServiceAndDynamicLayer();
}
public string BasemapUri
{
get { return myModel.BasemapLayerUri; }
set
{
this.myModel.BasemapLayerUri = value;
OnPropertyChanged("BasemapUri");
}
}
public async void CreateLocalServiceAndDynamicLayer()
{
LocalMapService localMapService = new LocalMapService(this.MAPKMap);
await localMapService.StartAsync();
ArcGISDynamicMapServiceLayer arcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};
//myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);
}
public string MAPKMap
{
get { return myModel.MapPackage; }
set
{
this.myModel.MapPackage = value;
OnPropertyChanged("MAPKMap");
}
}
protected void OnPropertyChanged([CallerMemberName] string member = "")
{
var eventHandler = PropertyChanged;
if (eventHandler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}
}
如您所见,我正尝试在ViewModel.cs
中实现本地服务器和动态层,如
public async void CreateLocalServiceAndDynamicLayer()
{
LocalMapService localMapService = new LocalMapService(this.MAPKMap);
await localMapService.StartAsync();
ArcGISDynamicMapServiceLayer arcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};
//myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);
}
但我不知道如何将此服务绑定到Model
?我尝试过
myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);
但是您知道myModel
没有任何Map对象。
更新
using M_PK2.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Esri.ArcGISRuntime.LocalServices;
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Layers;
namespace M_PK2.ViewModels
{
class ViewModel : ViewModelBase
{
private readonly LocalMapService localMapService;
private readonly Model myModel;
private LayerCollection layers;
public ViewModel()
{
myModel = new Model();
layers = new LayerCollection();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}
private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args)
{
starting -= onStarting; //optional
// the following runs on background thread
await localMapService.StartAsync();
// returned to the UI thread
var serviceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};
Layers.Add(serviceLayer);
OnPropertyChanged(nameof(Layers)); //Notify UI
}
public LayerCollection Layers
{
get
{
return layers;
}
}
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged([CallerMemberName] string member = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}
}
答案 0 :(得分:5)
除了事件处理程序外,避免使用async void
引用Async/Await - Best Practices in Asynchronous Programming
在您的情况下,您正在混合属于视图的UI问题。视图模型应公开视图以执行其功能。
由于所使用的依赖项LocalMapService
的异步性质,您应该创建一个异步事件处理程序来管理获取服务URI,并在通过绑定属性更改事件完成该任务时通知UI。
例如
public class ViewModel : ViewModelBase {
private readonly LocalMapService localMapService;
private readonly Model myModel;
private string serviceUri;
public ViewModel() {
myModel = new Model();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}
private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args) {
starting -= onStarting; //optional
// the following runs on background thread
await localMapService.StartAsync();
// returned to the UI thread
ServiceUri = localMapService.UrlMapService; //notifies UI
}
public string ServiceUri {
get { return serviceUri; }
set {
serviceUri = value;
OnPropertyChanged();
}
}
}
public class ViewModelBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged([CallerMemberName] string member = "") {
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}
这样,在异步启动服务后,UI会收到有关更改的通知。
<!-- Add a MapView Control. -->
<esriControls:MapView x:Name="MapView1">
<!-- Add a Map. -->
<esriControls:Map>
<!-- Add an ArcGISDynamicMapServiceLayer via XAML. -->
<esriLayers:ArcGISDynamicMapServiceLayer ID="mpklayer"
ServiceUri="{Bind ServiceUri}"/>
</esriControls:Map>
</esriControls:MapView>
如果目标是能够操纵多个图层,那么我建议绑定到Map.Layers Property以便能够直接访问视图模型中的图层集合。
视图模型可能最终看起来像
public class ViewModel : ViewModelBase {
private readonly LocalMapService localMapService;
private readonly Model myModel;
private LayerCollection layers;
public ViewModel() {
myModel = new Model();
layers = new LayerCollection();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}
private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args) {
starting -= onStarting; //optional
// the following runs on background thread
await localMapService.StartAsync();
// returned to the UI thread
var serviceLayer = new ArcGISDynamicMapServiceLayer() {
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};
Layers.Add(serviceLayer);
}
public LayerCollection Layers {
get {
return layers;
}
}
}
视图
<!-- Add a MapView Control. -->
<esriControls:MapView x:Name="MapView1">
<!-- Add a Map. with layers via binding-->
<esriControls:Map Layers="{Bind Layers, Mode=OneWay}" />
</esriControls:MapView>
您现在可以根据需要通过代码来操纵图层
答案 1 :(得分:0)
我没有可用的SDK,但是以下代码应该可以工作:
查看模型:
private readonly LocalMapService localMapService;
// initialize localMapService instance in the constructor
public string UrlMapService
{
get { return localMapService.UrlMapService; }
}
XAML:
<!-- A Map ControlView to display various GIS layers. -->
<esriControls:MapView x:Name="MapView1" Width="448" Height="480" VerticalAlignment="Top" Margin="2,2,2,2">
<!-- A Map. -->
<esriControls:Map x:Name="Map1" >
<!-- Add an ArcGISDynamicMapServiceLayer via Xaml. Set the ID and ImageFormat properties. -->
<esriLayers:ArcGISDynamicMapServiceLayer ID="serviceLayer" ImageFormat="PNG24"
ServiceUri="{Binding UrlMapService, Mode=OneWay}"/>
</esriControls:Map>
</esriControls:MapView>