要素
GIS中要素分两种,分别是Feature和Graphic。
不同点
Feature存在于Mapview.Map下的要素图层(FeatureLayer)中,而Graphic是仅存在于内存中。
一般情况下Feature通过图层或者服务的渲染器渲染,Graphic则一般通过单独的符号化进行渲染。
相同点
Feature和Graphic都包含三大要素:Geometry,Symbol,Attribute。
Geometry用于控制要素形状,Symbol用于控制要素符号,Attribute是要素的非空间属性。
Graphic的符号化
ArcGIS Runtime SDK Quartz由于三维功能的加入,分二维符号和三维符号
二维符号
根据要素Geometry类型的不同,二维符号有五种,分别是SimpleMarkerSymbol、PicutreMarkerSymbol、SimpleLineSymbol、SimpleFillSymbol、TextSymbol。
SimpleMarkerSymbol:简单点符号,用于点要素和多点要素的符号化
SimpleMarkerSymbol sms = new SimpleMarkerSymbol(); sms.Color = Color.FromArgb(255, 255, 255, 0); sms.Size = 16; MapPoint mp = new MapPoint(109, 38); Graphic g = new Graphic(mp, sms);
PictureMarkerSymbol pms = new PictureMarkerSymbol(new Uri(@"C:\Users\ant\Desktop\esri_logo.jpg")); MapPoint mp = new MapPoint(108, 33); Graphic g = new Graphic(mp, pms);
MapPoint mp = new MapPoint(108, 33); MapPoint mp2 = new MapPoint(108, 34); List<MapPoint> pointlist = new List<MapPoint>(); pointlist.Add(mp); pointlist.Add(mp2); SimpleLineSymbol sls = new SimpleLineSymbol(); sls.Color= Color.FromArgb(255, 0, 0, 255); sls.Width = 2; sls.Style = SimpleLineSymbolStyle.Solid; Polyline polyline = new Polyline(pointlist); Graphic g = new Graphic(polyline, sls); GraphicsOverlay graphicsOverlay = new GraphicsOverlay(); graphicsOverlay.Graphics.Add(g); this.mysceneview.GraphicsOverlays.Add(graphicsOverlay);
SimpleFillSymbol:简单填充符号,用于面要素的符号化
MapPoint mp = new MapPoint(108, 33); MapPoint mp2 = new MapPoint(108, 34); MapPoint mp3 = new MapPoint(109, 34); MapPoint mp4 = new MapPoint(109, 33); List<MapPoint> pointlist = new List<MapPoint>(); pointlist.Add(mp); pointlist.Add(mp2); pointlist.Add(mp3); pointlist.Add(mp4); SimpleFillSymbol sfs = new SimpleFillSymbol(); sfs.Color= Color.FromArgb(255, 0, 255, 0); //sls为线符号实例 sfs.Outline = sls; Polygon polygon = new Polygon(pointlist); Graphic g = new Graphic(polygon, sfs);
TextSymbol ts = new TextSymbol(); ts.Color = Colors.Gray; ts.Size = 18; ts.Text = "Text Symbol"; ts.HorizontalAlignment = Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Left; ts.VerticalAlignment = Esri.ArcGISRuntime.Symbology.VerticalAlignment.Bottom; MapPoint mp = new MapPoint(108, 33); Graphic g = new Graphic(mp, ts);
三维符号
三维符号的种类比较多,有BoxMarkerSymbol、SphereMarkerSymbol、ModelMarkerSymbol、ConeMarkerSymbol、TubeLineSymbol、DiamondMarkerSymbol、DistanceCompositeSymbol、TetrahedromMarkerSymbol。
SphereMarkerSymbol:三维球体符号
SimpleMarkerSceneSymbol smss = new SimpleMarkerSceneSymbol(); smss.Style = SimpleMarkerSceneSymbolStyle.Sphere; smss.Height = 3000; smss.Width = 3000; smss.Depth = 3000; MapPoint mp = new MapPoint(108, 33); Graphic g = new Graphic(mp, smss);
ModelSceneSymbol mss = await ModelSceneSymbol.CreateAsync(new Uri(@"C:\RuntimeResource\Data\CVN-80.dae"), 30); MapPoint mp = new MapPoint(120.7, 33.5, 500,SpatialReferences.Wgs84); Graphic g = new Graphic(mp, mss);
还有一个比较重要的符号就是DistanceCompositeSceneSymbol,这是一个基于距离的符号。
距离的符号能够根据相机镜头与要素的之间的距离控制要素的符号,当镜头较远时,要素显示为点符号,随着镜头的拉近,要素符号可以变为圆锥符号,到一定短距离时,开始显示模型符号。这样的符号方式能减轻runtme渲染压力。
DistanceCompositeSceneSymbol compositeSymbol = new DistanceCompositeSceneSymbol(); DistanceSymbolRange nearSymbolInfo = new DistanceSymbolRange(modelSymbol, 0, 5000); compositeSymbol.Ranges.Add(nearSymbolInfo); DistanceSymbolRange midSymbolInfo = new DistanceSymbolRange(coneSymbol, 5000, 50000); compositeSymbol.Ranges.Add(midSymbolInfo); DistanceSymbolRange farSymbolInfo = new DistanceSymbolRange(markerSymbol, 50000, 0); compositeSymbol.Ranges.Add(farSymbolInfo); MapPoint mp = new MapPoint(108, 33, 3000, SpatialReferences.Wgs84);
远距离时显示点符号
中等距离时显示圆锥符号
近距离时显示模型符号
渲染器
渲染器的作用对象是图层,他是针对图层设置的。渲染器的使用方法比较简单,只需要构造渲染器,然后传值给图层就可以。
二维渲染器
SimpleRenderer:简单渲染器,整个图层使用一个符号进行渲染
SimpleMarkerSymbol sms = new SimpleMarkerSymbol(); sms.Color = Colors.Red; sms.Size = 10; SimpleRenderer simpRenderer = new SimpleRenderer(sms); GraphicsOverlay graphicsOverlay = new GraphicsOverlay(); graphicsOverlay.Renderer = simpRenderer;简单渲染器的渲染效果就是整个图层使用同一个符号进行渲染,这里就不在贴图。
UniqueValueRenderer:唯一值渲染器,可以根据要素的字段内容对符号进行渲染的渲染器。
这里偷个懒,使用ArcGIS Runtime官网的代码。英文原版请参见:https://developers.arcgis.com/net/latest/wpf/guide/symbols-and-renderers.htm
ServiceFeatureTable statesFeatureTable = new ServiceFeatureTable(new System.Uri("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3")); var FeatureLayer = new FeatureLayer(statesFeatureTable); var stateRenderer = new UniqueValueRenderer(); //设置唯一值渲染字段 stateRenderer.FieldNames.Add("STATE_ABBR"); //构建三填充符号 var nevadaFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Colors.Blue, null); var arizonaFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Colors.Green, null); var californiaFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Colors.Red, null); //添加三个唯一值 stateRenderer.UniqueValues.Add(new UniqueValue("Nevada", "Nevada", nevadaFillSymbol, "NV")); stateRenderer.UniqueValues.Add(new UniqueValue("Arizona", "Arizona", arizonaFillSymbol, "AZ")); stateRenderer.UniqueValues.Add(new UniqueValue("California", "California", californiaFillSymbol, "CA")); //这里设置一个默认值符号,也就是其他符号 var defaultFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Null, Colors.Transparent, null); stateRenderer.DefaultSymbol = defaultFillSymbol; stateRenderer.DefaultLabel = "Other"; //要素图层 FeatureLayer statesLayer = new FeatureLayer(); //设置要素图层的渲染器 statesLayer.Renderer = stateRenderer; this.mysceneview.Scene.OperationalLayers.Add(statesLayer);
ClassBreakRenderer:分级设色渲染器,分级设色就是对要展现的要素根据其属性值的分布范围,对属性的值域进行分级,对不同等级使用不同的颜色深浅或形状大小来形象直观地表示地理要素。
分级设色渲染器是ArcGIS Runtime官网示例中没有提到的,这里做详细说明。
这里,我们先通过xaml代码来构造一个GraphicOverlay,在GraphicOverlay里面构造一个ClassBreakRenderer。
先配置几个符号,用作不同级别要素的符号。
<Grid.Resources> <esri:SimpleFillSymbol x:Key="0-60000" Color="#FF0A57FC" Style="Solid"/> <esri:SimpleFillSymbol x:Key="60001-150000" Color="#FF1CA2A3" Style="Solid"/> <esri:SimpleFillSymbol x:Key="150001-250000" Color="#FF60AD12" Style="Solid"/> <esri:SimpleFillSymbol x:Key="250001-350000" Color="#FFFFFE0A"/> <esri:SimpleFillSymbol x:Key="350001-450000" Color="#FFFDA208"/> <esri:SimpleFillSymbol x:Key="450001-510000" Color="#FFFB5107"/> </Grid.Resources>
<esri:GraphicsOverlay ID="statesOverlay"> <esri:GraphicsOverlay.Renderer> <esri:ClassBreaksRenderer Field="Productioin" > <esri:ClassBreaksRenderer.Infos > <esri:ClassBreakInfo Minimum="0" Maximum="60000" Symbol="{StaticResource 0-60000}"/> <esri:ClassBreakInfo Minimum="60001" Maximum="150000" Symbol="{StaticResource 60001-150000}"/> <esri:ClassBreakInfo Minimum="150001" Maximum="250000" Symbol="{StaticResource 150001-250000}"/> <esri:ClassBreakInfo Minimum="250001" Maximum="350000" Symbol="{StaticResource 250001-350000}"/> <esri:ClassBreakInfo Minimum="350001" Maximum="450000" Symbol="{StaticResource 350001-450000}"/> <esri:ClassBreakInfo Minimum="450001" Maximum="520000" Symbol="{StaticResource 450001-510000}"/> </esri:ClassBreaksRenderer.Infos> </esri:ClassBreaksRenderer> </esri:GraphicsOverlay.Renderer> </esri:GraphicsOverlay>需要说明的是,这里计划使用“甘肃省各地市草原生产力情况”面要素,并且将其发布成了服务
其表结构如下:
其服务名称如下:
http://localhost:6080/arcgis/rest/services/GS_GrassProduction/MapServer
在上面的xaml代码中,可以看到,GraphicsOverlay图层的渲染字段为“Production”字段,下面的ClassBreakInfo中设置了6个级别,Production在0-60001范围内,使用符号0-60001、Production在60001-150000范围内,使用符号60001-150000……以此类推。
然后我将这个数据发布为了FeatureService服务,然后通过Runtime的Query查询功能,获取服务中的要素加入xaml代码中构建的GraphicsOverlay中。
var queryTask = new QueryTask( new Uri("http://localhost:6080/arcgis/rest/services/GS_GrassProduction/MapServer/0")); Query query = new Query("1=1"); query.OutFields.Add("Productioin"); var result = await queryTask.ExecuteAsync(query); this.MySceneView.GraphicsOverlays["statesOverlay"].Graphics.AddRange(result.FeatureSet.Features.OfType<Graphic>());
截图略,我将在下一节中在分级设色渲染器(ClassBreaksRenderer)的基础上更进一步,是要素的表达获得更好的效果。
三维渲染器
ArcGIS Runtime其实本身没有三维渲染器,只是如果是三维场景中的图层,可以设置其渲染器的三维属性(SceneProperties)。下面我将在ClassBreaksRenderer的基础上,进一步对其设置SceneProperties。可以看到在Renderer的SceneProperties属性中,设置了拉伸表达式为"Production"字段,拉伸模式为“绝对高度”。
<esri:GraphicsOverlay ID="statesOverlay"> <esri:GraphicsOverlay.Renderer> <esri:ClassBreaksRenderer Field="Productioin" > <esri:ClassBreaksRenderer.SceneProperties> <esri:RendererSceneProperties ExtrusionExpression="[Productioin]" ExtrusionMode="AbsoluteHeight" /> </esri:ClassBreaksRenderer.SceneProperties> <esri:ClassBreaksRenderer.Infos > <esri:ClassBreakInfo Minimum="0" Maximum="60000" Symbol="{StaticResource 0-60000}"/> <esri:ClassBreakInfo Minimum="60001" Maximum="150000" Symbol="{StaticResource 60001-150000}"/> <esri:ClassBreakInfo Minimum="150001" Maximum="250000" Symbol="{StaticResource 150001-250000}"/> <esri:ClassBreakInfo Minimum="250001" Maximum="350000" Symbol="{StaticResource 250001-350000}"/> <esri:ClassBreakInfo Minimum="350001" Maximum="450000" Symbol="{StaticResource 350001-450000}"/> <esri:ClassBreakInfo Minimum="450001" Maximum="520000" Symbol="{StaticResource 450001-510000}"/> </esri:ClassBreaksRenderer.Infos> </esri:ClassBreaksRenderer> </esri:GraphicsOverlay.Renderer> </esri:GraphicsOverlay>这下给出程序运行截图: