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