Prism和Esri GetElevationAsync(mapPoint)

时间:2017-03-27 21:37:59

标签: c# wpf prism esri sceneview

我们正在使用wpf,C#和Prism v6.1.0.0为视觉工作室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应用程序?

有多个视图和主shell的Prism应用程序。 SceneView模块有一个服务,并使用此服务器将DTED级别0数据加载到SceneView.Scene.Surface中。我已将所有功能移到SceneViewView中,我们仍然遇到相同的访问错误。调用Thread是主应用程序线程。我发布了错误和一些代码片段。 我在Prism应用程序中使用的代码与我在一个简单的WPF应用程序中使用的代码相同,该应用程序使用所有相同的控件而不是Prism体系结构。它工作得很好,我只需激活Sceneview并将一个mapoint从Mapview传递到GetElevationAsync函数就可以得到eleveation数据。没有问题。

  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]}”

  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   Message =尝试读取或写入受保护的内存。这通常表明其他内存已损坏。   来源= Esri.ArcGISRuntime   堆栈跟踪:    在runtimeCoreNet.CoreLocalElevationRaster.LocalElevationLayerPickElevation(IntPtr pNativeElevationLayer,Double x,Double y,Double&amp; z)    在Esri.ArcGISRuntime.Controls.FileElevationSource.GetElevationAsync(MapPoint point)    在SceneViewModule.Views.SceneViewView.SceneViewView.d__19.MoveNext()在\ SceneViewModule \ Views \ SceneViewView \ SceneViewView.xaml.cs:第141行

1 个答案:

答案 0 :(得分:1)

你提到你在Unity中使用它吗?

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