2017-03-27 10 views
1

私たちは、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

+0

なぜプリズムのv4を使用しているのですか? Prism 6.3がリリースされており、4はもはやサポートされていないか、または維持されています。 –

+0

プロジェクト設定で「ネイティブデバッグ」を有効にして、クラッシュが発生したときに取得するコールスタックを共有できますか?それは私に何かを与えるかもしれない。 – dotMorten

+0

はい、今日「ネイティブデバッグ」を有効にして結果を確認します。良いアイデア。 –

答えて

1

あなたはUnity内で使用しているとお伝えしましたか?

GetElevationAsync APIは、アクティブなSceneViewレンダリングでのみ使用できます。このエラーは正しいとは言えませんが、現時点ではこのAPIはSceneViewの外でスタンドアロンでは機能しません。この時点での主な目的は、SceneViewをクリックしてそのポイントの正確な標高を得ることです。これは単体ではありません。私は、あなたがクラッシュを見ている理由は、このために正しくチェックしていないエラー処理のビットがあると思います。しかし、修正する必要がある場合は、より良いエラーメッセージになります。

+0

Prism.Unity.WpfおよびPrism.Wpf、ランタイムバージョンv4.0.30319、リリース6.1.0.0。 wpfアプリケーションに沿ってスタンドで走って、GetElevationAsyncは素晴らしい作品です。まったく同じ状況を設定しても、PrismとSceneViewをモジュールで実行すると、GetElevationAsync呼び出しを行うときにアクセス違反が発生します。はい、アクティブなSceneViewをセットアップしています。マウスポイントを移動したときにマップポイントを渡しています。これは、PrismとUnityを使用しないプロトタイプでうまく動作します。 –

関連する問題