《ArcGIS Runtime SDK for .NET開發筆記》--三維功能


介紹

在ArcGIS Runtim SDK for .NET 10.2.6中,新添加了三維地圖功能。在ArcGIS中,我們將三維地圖稱為Scene(場景),所以在Runtime SDK SDK for .NET中提供SceneView和Scene控件來顯示三維數據,類似於在二維地圖中的MapView和Map控件。而且在三維場景中能實現大多數二維地圖下的功能。

顯示場景

場景的顯示由位置和觀察者(observer)的屬性決定,同過Canera這個類實現。下面的camera(相機)的特征用於顯示三維的場景。 
–Location,表示相機在表面上的位置(x,y坐標) 
–Heading表示相機水平的朝向角度 
–Pitch表示相機鏡頭與垂直線的角度 
–Evevation表示高程(z) 

ps:實際在camera.Location中可以設置z。

加載地圖

在三維場景中可以加載二維的地圖,三維的模型以及高程數據。 
 
 
在xaml中添加加載地圖代碼:

<esri:Scene x:Name="scene1"> <esri:Scene.Surface> <esri:ServiceElevationSource ServiceUri="http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" IsEnabled="True" ID="elevationLayer" /> </esri:Scene.Surface> <esri:ArcGISTiledMapServiceLayer x:Name="TiledMap1" ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/> <esri:SceneLayer ServiceUri="http://scene.arcgis.com/arcgis/rest/services/Hosted/Buildings_Philadephia/SceneServer/layers/0"/> </esri:Scene>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在場景中顯示圖形

添加圖形

圖形可以添加到Scene的GraphicsLayer,或者SceneView的GraphicsOverlay。每個圖形有一個幾何,一系列屬性和渲染需要的符號。下面的例子展示創建一個點圖形,並設置幾何和符號,最后添加到SceneView的GraphicsOverlay。 

public MainWindow()
        {
            InitializeComponent();
            // create a new point (MapPoint); pass x, y, and z coordinates in the constructor var newPoint = new MapPoint(-117.334, 34.55, 6000); // create a red "X" marker symbol var xMarkerSym = new SimpleMarkerSymbol(); xMarkerSym.Color = Colors.Red; xMarkerSym.Size = 34; xMarkerSym.Style = SimpleMarkerStyle.X; // create a new graphic; assign the point and the symbol in the constructor var graphic = new Graphic(newPoint, xMarkerSym); // get a graphics overlay in the scene view and add the graphic var overlay = MySceneView.GraphicsOverlays["MyGraphicsOverlay"]; overlay.Graphics.Add(graphic); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

渲染

渲染決定了圖層上圖形的樣式。渲染器可以使用單一的符號來渲染所有的要素,或者使用含有邏輯的方式來定義不同屬性的要素。 

<esri:GraphicsLayer ID="GraphicsLayer" > <esri:GraphicsLayer.Renderer> <esri:SimpleRenderer> <esri:SimpleRenderer.Symbol> <esri:SphereMarkerSymbol Color="#FFFF99" Radius="1000" AnchorPosition="Top" /> </esri:SimpleRenderer.Symbol> </esri:SimpleRenderer> </esri:GraphicsLayer.Renderer> </esri:GraphicsLayer> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

查詢功能

在Runtime SDK for .NET中雖然不直接支持對三維模型的查詢,但是我們可以通過將二維要素符號化后實現對三維屬性的查詢和三維建築的高亮顯示。 
 
查詢代碼

Esri.ArcGISRuntime.Layers.GraphicsLayer myGraphicsLayer = (Esri.ArcGISRuntime.Layers.GraphicsLayer)scene1.Layers["myGraphicsLayer"]; if(myGraphicsLayer!=null) myGraphicsLayer.Graphics.Clear(); Uri myUri = new Uri("http://localhost:6080/arcgis/rest/services/Feature_Philadelphia/MapServer"); FindParameters myFinfParameters = new FindParameters(); myFinfParameters.SearchText = "philly_"+TextBox1.Text+".flt"; List<int> myLayerIds = new List<int>(); myLayerIds.Add(0); myFinfParameters.LayerIDs = myLayerIds; if (CheckBox1.IsChecked == true) { myFinfParameters.Contains = false; } else { myFinfParameters.Contains = true; } List<string> mySearchFields = new List<string>(); mySearchFields.Add("Name"); myFinfParameters.SearchFields = mySearchFields; FindTask myFindTask = new FindTask(myUri); FindResult myFindResult = await myFindTask.ExecuteAsync(myFinfParameters); IReadOnlyList<FindItem> myFindItems = myFindResult.Results; TextBox2.Text = myFindItems.Count.ToString(); myGraphicsLayer = (GraphicsLayer)scene1.Layers["myGraphicsLayer"]; var states = new GraphicCollection(); foreach(FindItem oneFindItem in myFindItems) { states.Add(new Graphic(oneFindItem.Feature.Geometry, oneFindItem.Feature.Attributes)); MapPoint mylocation = new MapPoint(oneFindItem.Feature.Geometry.Extent.GetCenter().X, oneFindItem.Feature.Geometry.Extent.GetCenter().Y-2000,370, oneFindItem.Feature.Geometry.Extent.GetCenter().SpatialReference); var viewpoint1 = new Camera( mylocation,0,73.16171159612496); await MySceneView.SetViewAsync(viewpoint1, 4, true); } await MySceneView.LayersLoadedAsync(); var statesOverlay = MySceneView.GraphicsOverlays["statesOverLayer"]; statesOverlay.GraphicsSource = states;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

二三維聯動

在ArcGIS Runtime SDK for .NET中,在一個窗體中可以添加兩個視圖,這里我添加了一個SceneView和 一個MapView實現二三維的聯動。 
 
我們可以通過地圖控件的SpatialReferenceChanged來監控地圖的變化。

private async void MySceneView1_CameraChanged(object sender, EventArgs e) { var currentViewpoint = MySceneView1.GetCurrentViewpoint(ViewpointType.BoundingGeometry); MyMapView1.SetViewAsync(currentViewpoint); } private async void MyMapView1_ExtentChanged(object sender, System.EventArgs e) { var viewpoint1 = MyMapView1.GetCurrentViewpoint(ViewpointType.BoundingGeometry); await MySceneView1.SetViewAsync(viewpoint1); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

三維符號的屬性查詢

同二維的符號一樣三維的符號的屬性也可以進行查詢。下面是獲取的美國各州不同年齡段人口的數量。我們可以用三維的符號將人口數直觀的表現出來。還可以點擊符號,顯示出這是哪個州,這個年齡段的人口的數量。例如:圖中顯示是阿拉斯加州,5-17歲的人口是143126。 
 
屬性查詢代碼

GraphicsOverlay myGraphicsOverlay = MySceneView.GraphicsOverlays["statesOverlay"]; myGraphicsOverlay.ClearSelection(); Graphic myGraphic = await myGraphicsOverlay.HitTestAsync(MySceneView, e.Position); if (myGraphic != null) { myGraphic.IsSelected = true; IDictionary<string, object> myAttributes = myGraphic.Attributes; StringBuilder myStringBuilder = new System.Text.StringBuilder(); foreach (var oneAttribute in myAttributes) { if (statisticsComboBox.Text.ToString() == oneAttribute.Key.ToString() || oneAttribute.Key.ToString() == "STATE_NAME") myStringBuilder.AppendLine(oneAttribute.Key.ToString() + ": " + oneAttribute.Value.ToString()); } MessageBox.Show(myStringBuilder.ToString()); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM