2017-03-27 5 views
1

Wir erstellen eine Anwendung mit Visual Studios 2017 mit WPF, C# und Prism v6.1.0.0. Wir haben eine 3D-Ansicht, die eine Esri .net Runtime SceneView ist. Wir wollten die Funktion GetElevationAsync (mapPoint) verwenden, um Höhendaten von Daten der DTED-Ebene 0 zu erhalten. In einer eigenständigen Anwendung, die nur Esri SceneView verwendet, funktioniert die Funktion GetElevationAsync (mapPoint) sowohl für das SceneView als auch für MapView, wenn das SceneView aktiv ist. Dazu wird auch FileElevationSource verwendet und in DTED-Ebene 0 in die FileElevationSource geladen und dann zur SceneView.Scene.Surface hinzugefügt.Prism und Esri GetElevationAsync (mapPoint)

Das Problem, das wir haben, ist, wenn wir versuchen, den GetElevationAsync (mapPoint) aufzurufen, erhalten wir eine System.AccessViolationException. Hat noch jemand versucht, ESRis .NET-Laufzeitumgebung und Prism zu verwenden, um eine SceneView-Anwendung zu erstellen, die die GetElevationAsync-Funktion (mapPoint) verwendet?

Was haben sind eine Prism-Anwendung mit Mehrfachansicht und eine Haupthülle. Das SceneView-Modul verfügt über einen Dienst und verwendete diesen Server, um die Daten der DTED-Ebene 0 in die SceneView.Scene.Surface zu laden. Ich habe alle Funktionen in das SceneViewView verschoben und wir erhalten immer noch denselben Zugriffsfehler. Der aufrufende Thread ist der Hauptanwendungs-Thread. Ich habe den Fehler und einige Code-Schnipsel gepostet. Derselbe Code, den ich in der Prism-Anwendung habe, ist der gleiche Code, den ich in einer einfachen WPF-Anwendung habe, die alle die gleichen Kontrollen aber nicht eine Prism-Architektur verwendet. Es funktioniert großartig und ich kann die Daten abrufen, indem ich einfach den Sceneview aktiviere und einen Mapoint aus der MapView in die GetElevationAsync Funktion ohne Probleme übergebe.

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 Punktdaten „= mapPoint MapPoint {[X = 4,54778361440582, Y = 27,7940801510867, Z = 5.58793544769287E-09, Wkid = 4326]}“ übergeben wird

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 aufgetreten HResult = 0x80004003 Nachricht = versucht, geschützten Speicher zu lesen oder zu schreiben. Dies ist oft ein Hinweis darauf, dass anderer Speicher beschädigt ist. Source = Esri.ArcGISRuntime Stacktrace: bei runtimeCoreNet.CoreLocalElevationRaster.LocalElevationLayerPickElevation (IntPtr pNativeElevationLayer, Double x, y Doppel, Double & z) bei Esri.ArcGISRuntime.Controls.FileElevationSource.GetElevationAsync (MapPoint Punkt) bei SceneViewModule.Views .SceneViewView.SceneViewView.d__19.MoveNext() in \ SceneViewModule \ Views \ SceneViewView \ SceneViewView.xaml.cs: Linie 141

+0

Nur neugierig, warum Sie v4 von Prism verwenden? Sie wissen, Prism 6.3 ist out, und 4 wird nicht mehr unterstützt oder beibehalten, oder? –

+0

Können Sie "natives Debugging" in den Projekteinstellungen aktivieren und den Aufrufstack freigeben, den Sie erhalten, wenn der Absturz auftritt? Es könnte mir etwas geben, um weiterzumachen. – dotMorten

+0

Ja, ich werde heute "natives Debugging" aktivieren und die Ergebnisse anschauen. Gute Idee. –

Antwort

1

Sie erwähnten Sie es innerhalb von Unity verwenden?

Die GetElevationAsync-APIs funktionieren nur in einem aktiven SceneView-Rendering mit ihr. Obwohl der Fehler nicht richtig klingt, funktioniert diese API derzeit nicht außerhalb der SceneView (sie steht jedoch auf unserer Liste für zukünftige Erweiterungen). Der Hauptzweck an diesem Punkt besteht darin, auf den SceneView zu klicken und eine genaue Höhe für diesen Punkt zu erhalten. Es ist nicht als alleinstehend gedacht. Ich schätze, es gibt ein bisschen Fehlerbehandlung, die nicht richtig überprüft, weshalb Sie einen Absturz sehen. Aber wenn es behoben würde, wäre alles, was Sie bekommen würden, eine bessere Fehlermeldung.

+0

Prism.Unity.Wpf und Prism.Wpf, Laufzeitversion v4.0.30319, Release 6.1.0.0. In einem Stand entlang wpf-Anwendung läuft das GetElevationAsync großartig. Wenn wir genau die gleiche Situation einstellen, aber Prism und das in einem Modul ausgeführte SceneView verwenden, erhalten wir eine Zugriffsverletzung, wenn wir den GetElevationAsync-Aufruf durchführen. Ja, ich habe ein aktives SceneView eingerichtet und übergebe den Kartenpunkt, wenn der Mauszeiger bewegt wird. Dies funktioniert gut in dem Prototyp, der Prism und Unity nicht verwendet. –