我们正在使用 wpf、C# 和 Prism v6.1.0.0 使用 Visual Studios 2017 构建一个应用程序。我们有一个 3d 视图,它是一个 Esri .net 运行时 SceneView。我们想使用 GetElevationAsync(mapPoint) 函数从 DTED 0 级数据中获取高程数据。在仅使用 Esri SceneView 的独立应用程序中,如果 SceneView 处于活动状态,GetElevationAsync(mapPoint) 函数适用于 SceneView 和 MapView。这也是使用 FileElevationSource 并将 DTED 级别 0 加载到 FileElevationSource 中,然后将其添加到 SceneView.Scene.Surface。
我们遇到的问题是,当我们尝试调用 GetElevationAsync(mapPoint) 时,我们会收到 System.AccessViolationException。有没有其他人尝试使用 ESRi 的 .net 运行时和 Prism 来创建使用 GetElevationAsync(mapPoint) 函数的 SceneView 应用程序?
拥有的是具有多个视图和主外壳的 Prism 应用程序。SceneView 模块有一项服务,并且正在使用该服务器将 DTED 级别 0 数据加载到 SceneView.Scene.Surface。我已将所有功能移到 SceneViewView 中,但我们仍然遇到相同的访问错误。调用线程是主应用程序线程。我已经发布了错误和一些代码片段。我在 Prism 应用程序中使用的代码与我在使用所有相同控件但不是 Prism 架构的简单 WPF 应用程序中使用的代码相同。它工作得很好,我可以通过激活 Sceneview 并将 Mapview 中的一个映射点传递给 GetElevationAsync 函数来获取高程数据,没有任何问题。
private void OnSceneViewViewLoaded(object sender, RoutedEventArgs e)
{
SceneViewService = UnityContainer.Resolve<ISceneViewService>();
string elevationSourcePath = System.Environment.GetEnvironmentVariable("SHELL") + "\\Resources\\Terrain\\DTED\\Level0\\";
AddElevationSources(elevationSourcePath);
mSceneView.MouseMove += OnSceneViewMouseMove;
}
private void OnSceneViewMouseMove(object sender, MouseEventArgs e)
{
{
Point screenPoint = e.GetPosition(mSceneView);
double elevation = 0.0;
MapPoint point = mSceneView.ScreenToLocation(screenPoint);
if (point != null)
{
MapPoint mapPoint = GeometryEngine.Project(point, SpatialReferences.Wgs84) as MapPoint;
elevation = GetElevation(mapPoint).Result;
if (!Double.IsNaN(elevation))
{
mElevationStatusBarTextBlock.Text = elevation.ToString();
}
}
}
}
public void AddElevationSources(string elevationSourcePath)
{
FilenameCollection mFilenameCollection = new FilenameCollection();
List<String> files = new List<String>();
try
{
files = DirSearch(elevationSourcePath);
foreach (String file in files)
mFilenameCollection.Add(file);
mFileElevationSource.Filenames = mFilenameCollection;
mFileElevationSource.ID = "Elevation Source";
mSceneView.Scene.Surface.Add(mFileElevationSource);
mFileElevationSource.IsEnabled = true;
}
catch (Exception excpt)
{
Console.WriteLine("AddElevationSources, ElevationSourceService " + excpt.Message);
}
}
public List<String> DirSearch(string sourceDirectory)
{
List<String> files = new List<String>();
try
{
foreach (string file in Directory.GetFiles(sourceDirectory, "*.dt0"))
{
files.Add(file);
}
foreach (string directory in Directory.GetDirectories(sourceDirectory))
{
files.AddRange(DirSearch(directory));
}
}
catch (Exception excpt)
{
Console.WriteLine("DirSearch, AddElevationSources " + excpt.Message);
}
return files;
}
正在传递的地图点数据“mapPoint = {MapPoint[X=4.54778361440582, Y=27.7940801510867, Z=5.58793544769287E-09, Wkid=4326]}”</p>
public async Task<double> GetElevation(MapPoint mapPoint)
{
double elevation = 0.0;
try
{
if (!Double.IsNaN(mapPoint.X) && !Double.IsNaN(mapPoint.Y))
{
elevation = await mFileElevationSource.GetElevationAsync(mapPoint);
if (Double.IsNaN(elevation))
elevation = 0;
}
}
catch (Exception excpt)
{
Console.WriteLine("Task<double> GetElevation, ElevationSourceModule " + excpt.Message);
}
return elevation;
}
}
System.AccessViolationException 发生 HResult=0x80004003 消息=尝试读取或写入受保护的内存。这通常表明其他内存已损坏。Source=Esri.ArcGISRuntime StackTrace:在运行时CoreNet.CoreLocalElevationRaster.LocalElevationLayerPickElevation(IntPtr pNativeElevationLayer, Double x, Double y, Double& z) at Esri.ArcGISRuntime.Controls.FileElevationSource.GetElevationAsync(MapPoint point) at SceneViewModule.Views.SceneViewView.SceneViewView.d__19 .MoveNext() 在 \SceneViewModule\Views\SceneViewView\SceneViewView.xaml.cs:line 141