私たちは、wpf、C#、Prism v6.1.0.0を使ってビジュアルスタジオ2017でアプリケーションを構築しています。私たちは、Esri .netランタイムSceneViewである3Dビューを持っています。 GetElevationAsync(mapPoint)関数を使用して、DTEDレベル0データから標高データを取得したかったのです。 Esri SceneViewだけを使用するスタンドアロンアプリケーションでは、SceneViewがアクティブな場合、GetElevationAsync(mapPoint)関数はSceneViewとMapViewの両方で機能します。これはFileElevationSourceを使用しており、DTEレベル0でFileElevationSourceにロードしてからSceneView.Scene.Surfaceに追加します。プリズムとエスリGetElevationAsync(mapPoint)
私たちが抱えている問題は、GetElevationAsync(mapPoint)を試して呼び出すときに、System.AccessViolationExceptionが発生することです。誰かがESRiの.netランタイムとプリズムを使ってGetElevationAsync(mapPoint)関数を使っているSceneViewアプリケーションを作成しようとしましたか?
何があるのは、複数のビューとメインシェルを持つプリズムアプリケーションです。 SceneViewモジュールにはサービスがあり、このサーバーを使用してDTEDレベル0のデータをSceneView.Scene.Surfaceにロードしていました。私はすべての機能をSceneViewViewに移しましたが、同じアクセスエラーが発生します。呼び出し元のスレッドはメインのアプリケーションスレッドです。私はエラーといくつかのコードスニペットを投稿しています。 プリズムアプリケーションで使用しているのと同じコードは、同じコントロールを使用していて、プリズムアーキテクチャではない単純なWPFアプリケーションと同じコードです。素晴らしいことですが、Sceneviewをアクティブにし、マップビューからマップポイントを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]}」
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が発生渡されます0x350004003 メッセージ=保護されたメモリの読み取りまたは書き込みを試みました。これはしばしば、他のメモリが壊れていることを示します。 ソース= Esri.ArcGISRuntime のStackTrace:SceneViewModule.ViewsでEsri.ArcGISRuntime.Controls.FileElevationSource.GetElevationAsyncでruntimeCoreNet.CoreLocalElevationRaster.LocalElevationLayerPickElevation(のIntPtr pNativeElevationLayer、ダブルX、ダブルY、ダブル& Z) で(MapPointの点) .SceneViewView.SceneViewView.d__19.MoveNext()\ SceneViewModule \ Views \ SceneViewView \ SceneViewView.xaml.cs:line 141
なぜプリズムのv4を使用しているのですか? Prism 6.3がリリースされており、4はもはやサポートされていないか、または維持されています。 –
プロジェクト設定で「ネイティブデバッグ」を有効にして、クラッシュが発生したときに取得するコールスタックを共有できますか?それは私に何かを与えるかもしれない。 – dotMorten
はい、今日「ネイティブデバッグ」を有効にして結果を確認します。良いアイデア。 –