We are building an application with visual studios 2017 using wpf, C# and Prism v6.1.0.0. We have a 3d view that is an Esri .net runtime SceneView. We wanted to use the GetElevationAsync(mapPoint) function to get elevation data from DTED level 0 data. In a stand-alone application using just Esri SceneView the GetElevationAsync(mapPoint) function works for both the SceneView and MapView if the SceneView is active. This is also using FileElevationSource and loading in DTED level 0 into the FileElevationSource and then adding that to the SceneView.Scene.Surface.
The issue we are having is when we try and call the GetElevationAsync(mapPoint) we get an System.AccessViolationException. Has anyone else tried using ESRi's .net runtime and Prism to create a SceneView application that is using the GetElevationAsync(mapPoint) function?
What are have is a Prism application with multiple view and a main shell. The SceneView Module has a service and was using this server to load the DTED level 0 data into the SceneView.Scene.Surface. I have moved all the functionality into the SceneViewView and we still get the same access error. The calling Thread is the main application thread. I have post the error and some code snippets. The same code I have in the Prism application is the same code I have in a simple WPF application that is using all the same controls but not a Prism architecture. It works great and I can get the eleveation data just by activating the Sceneview and passing a mapoint from the Mapview into the GetElevationAsync function with no issue.
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;
}
Map Point data being passed “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 occurred HResult=0x80004003 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=Esri.ArcGISRuntime StackTrace: at runtimeCoreNet.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() in \SceneViewModule\Views\SceneViewView\SceneViewView.xaml.cs:line 141
You mentioned you are using it within Unity?
The GetElevationAsync APIs only work with it in an active SceneView rendering. While the error doesn't sound right, this API will not work at this point stand-alone outside the SceneView (it's on our list for future enhancements though). It's main purpose at this point is to click the SceneView and get an accurate elevation for that point. It's not meant to be stand-alone. I'm guessing there's a bit of error handling not checking correctly for this, which is why you're seeing a crash. But if it were to be fixed, all you would get would be a better error message.
User contributions licensed under CC BY-SA 3.0