1

我们正在使用 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

4

1 回答 1

0

你提到你在 Unity 中使用它?

GetElevationAsync API 仅在活动的 SceneView 渲染中使用它。虽然错误听起来不太对劲,但此时此 API 将无法在 SceneView 之外独立工作(不过,它在我们的列表中以供将来增强)。此时的主要目的是单击 SceneView 并获得该点的准确高程。它并不意味着是独立的。我猜有一些错误处理没有正确检查,这就是你看到崩溃的原因。但是,如果要修复它,您将得到的只是更好的错误消息。

于 2017-03-27T23:38:51.913 回答