伤城文章网 > IT/计算机 > ArcGIS API for SilverlightWPF 2.1学习笔记

ArcGIS API for SilverlightWPF 2.1学习笔记


ArcGIS API for Silverlight/WPF 2.1 学习笔记(一) 学习笔记( (http://blog.163.com/zwx_gis/blog/static/32434435201122193611 576/)
一、安装 1、Visual Studio: (1)Visual Studio 2010 或 Visual Web Developer Express 2010 (2)Silverlight 4 Tools for Visual Studio (add-on) :仅 Silverlight 4 支持 (3)Expression Blend 4 SDK for Silverlight (also included with Expression Blend 4) (Necessary for behavior and Silverlight support) 2、Expression Blend: (1)Expression Blend 4:Included with Expression Studio editions 3、其它附加(非必须安装) (1)Deep Zoom Composer (2)Silverlight Toolkit 二、开始 1、VS2010,新建“Silverlight 应用程序” 2、勾选“在新网站中承载 Silverlight 应用程序”(ASP.NET Web 应用程序项目) 3、添加引用:.NET\ESRI.ArcGIS.Client 4、xaml 文件中:添加命名空间指向 ArcGIS Silverlight/WPF;添加 Map 控件,并指定其 MapServiceLayer。 <UserControl x:Class="SilverlightApplication.MainPage" xmlns="…" … xmlns:esri="http://schemas.esri.com/arcgis/client/2009"> <Grid x:Name="LayoutRoot"> <esri:Map x:Name="MyMap" > <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" Url="http://hostName/ArcGIS/rest/services/mapservName/MapServer"/> </esri:Map> </Grid> </UserControl> 注意:为了能跨域访问(MapServer 在不同域),需要将 clientaccesspolicy.xml 或 crossdomain.xml 文 件拷贝到网站根目录(如 IIS 的 C:\inetpub\wwwroot\)。

三、ArcGIS API for Microsoft Silverlight/WPF 2.1 的 ODM: 1、OMD(Object model diagrams 对象模型图表)总览:参见附件一 2、OMD(Object model diagrams 对象模型图表)详表:参见附件二 四、地图和图层(Maps and Layers) 1、创建地图(map) exent 属性:地图的左下角和右上角坐标值,即地图的显示范围 默认:所有地图图层的范围 spatial reference(空间参考)属性:如果空间参考不一致,地图将不显示 默认:采用第一个图层的空间参考值 <esri:Map x:Name="MyMap"> <esri:Map.Extent> <esriGeometry:Envelope XMin="." YMin="." XMax="." YMax="." > <esriGeometry:Envelope.SpatialReference> <esriGeometry:SpatialReference WKID="26777"/> </esriGeometry:Envelope.SpatialReference> </esriGeometry:Envelope> </esri:Map.Extent> </esri:Map> 也可后台指定: ESRI.ArcGIS.Client.Geometry.Envelope initialExtent = new ESRI.ArcGIS.Client.Geometry. Envelope(ESRI.ArcGIS.Client.Bing.Transform.GeographicToWebMercator( new ESRI. ArcGIS.Client.Geometry.MapPoint(-130, 20)),ESRI.ArcGIS.Client.Bing.Transform. GeographicToWebMercator(new ESRI.ArcGIS.Client.Geometry.MapPoint(-65, 55))); initialExtent.SpatialReference = new ESRI.ArcGIS.Client.Geometry.SpatialReference(102100); MyMap.Extent = initialExtent; 注:WKID-Well Know ID:EPSG 发布的代表特定椭球体、单位、地理坐标系或投影坐标系的 ID,例如 "EPSG:4326" 指的就是 WGS 84 地理坐标系,其中 WKID=4326 2、新增图层(layer) 第一加载图层的空间参考决定了整个地图的空间参考 先加载的图层在地图下边,如下图:

Map Service Layers 两种类型: tiled Service:瓦片,地图服务器上预先定义好的 Image Dyanmic Service:动态,动态生成的 Image Service host ArcGIS Service Map Service Layer Type ArcGISTiledMapServiceLayer 描述 地图服务器的缓存地图服务已经存在所有 地图 image 瓦片 ArcGISDynamicMapServiceLayer 地图服务器的无缓存地图服务动态生成地 图 images,可动态访问矢量(vector)和(栅 格)raster 数据 ArcGISImageServiceLayer 地图服务器的 image 服务动态生成地图 images,可动态访问栅格数据 Bing Maps TileLayer Feature layers 包含 features,如 geometry(几何学)和 attribute(属性) 不支持多图层缓存 ArcGISDynamicMapServiceLayer 的背景颜色通常为透明 opacity 属性用于定义图层的透明度(0-1) 地图不显示的原因有: url 不正确; Map Service 不可用 Map Service 网站或主机没有跨域认证文件(clientaccesspolicy.xml 或 crossdomain.xml) Map Service 要求 token 或 credentials 3、导航地图(Navigation)

(1)map 的 ZoomDuration 属性和 PanDuration 属性:用于指定缩放和平移动作的持续时间。 如<esri:Map ZoomDuration="00:00:00" PanDuration ="00:00:00” …> (2)map 的 SnapToLevels 属性:用于指定 level of detail(LOD),地图在该级别是否显示。 如<esri:Map SnapToLevels=”ture” …> (3)map 的 ZoomFactor 属性:键盘+/-进行缩放时,缩放的级数 (4)系统已封装的键盘和鼠标导航地图快捷键: 键盘 上、下、左、右 拖动 +、双击 Shift Shift+Ctrl 拉框 拉框 滚轮 鼠标 结果 地图平移 地图平移 地图缩放,缩放比例为 map 的 ZoomFactor 属性指定的值 地图放大,放大比例为 map 的 ZoomFactor 属性指定的值 拉框放大 拉框缩小 地图缩放 (5)系统已封装的导航地图的方式和接口: map 的属性|方法 Extent 属性 Zoom() Zoomto() ZoomToResolution() 描述 map.Extent=envelope map.Zoom(n) ,n 为缩放比率,n>1 为 zoomin,n<1 为 zoomout map.Zoomto(envelope) map.ZoomToResolution(lod.Resolution); Resolution 指每 pixel 包含的 map unit 数,如 Lod lod=tiledMapServiceLayer.TileInfo.Lods[5]; map.ZoomToResolution(lod.Resolution); Panto() Panto(point),point 为地图窗口的中心点 4、Time-aware layers(此知识点不懂,有待继续研究) ArcGIS10 开始支持 Time-aware layers,存储了随时间变化的信息,可用于: (1)飓风路径及其它气象学事件; (2)人口和土地利用的历史变化; (3)监测生产现状的变化;

(4)火灾或洪水的行进; (5)疾病的蔓延。 Time-aware layers 的使用: (1)使用 Tookit 里的 TimeSlider 控件 (2)使用 API 自己建立应用程序 Time-aware layers 的建立: 在 ArcMap 中,右键图层\属性\Time,勾选 Enable time on this layer

地图发布后,可以使用 time-aware map 或 feature Service(ArcGISDynamicMapServiceLayer 或 FeatureLayer classes)来随时间变化的查询和展示。 对于 Image Services,栅格地图必须提供 Mosaic Dateset,如下图:

访问 TimeExtent 类:通过 time-aware layers 的 TimeExtent 属性访问 TimeExtent timeExtent = (MyMap.Layers["MyFeatureLayer"] as FeatureLayer) .TimeExtent; //TimeExtent timeExtent = new ESRI.ArcGIS.Client.TimeExtent(); timeExtent.Start = DateTime.Parse("2002-01-01T17:33:46.0000000", CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal); 5、Behaviors 和 actions BehaviorAPI 位于 Esri.ArcGIS.Client.Behaviors 集(内藏在 Expression Blend4 中),用 于定义用户与地图的交互。使用时必须添加 System.Windows.Interactivity 集。 xaml 文件中必须添加命名空间如下: xmlns:esriBehaviors="clr-namespace:ESRI.ArcGIS.Client.Behaviors;assembly=ESRI.A rcGIS.Client.Behaviors" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.I nteractivity" BehaviorAPI 包括三个核心类:

(1)Behavior:由 trigger(地图上的事件)和 action(产生结果)组成
Behavior Description Code Example

<esri:Map x:Name="MyMap"
ConstrainExtentBehavior Limit the map extent to an envelope. The user cannot navigate outside of the envelope defined on the behavior.

Extent="-120,30,-60,60"> . . . <i:Interaction.Behaviors> <esriBehaviors:ConstrainExtentBehavior ConstrainedExtent="-120,30,-60,60"/> </i:Interaction.Behaviors> </esri:Map>

<esri:Map x:Name="MyMap">
MaintainExtentBehavior Maintain the current extent when the map is resized.

. . . <i:Interaction.Behaviors> <esriBehaviors:MaintainExtentBehavior /> </i:Interaction.Behaviors> </esri:Map> <esri:Map x:Name="MyMap">

ShowCoordinatesBehavior

Show map coordinates . . . next to the mouse cursor when hovering over the map.

<i:Interaction.Behaviors> <esriBehaviors:ShowCoordinatesBehavior FormatString="{}{0:0.00} , {1:0.00}"/> </i:Interaction.Behaviors> </esri:Map>

(2)Action:由 trigger(地图上的事件)和目标结果 Descripti on

Action

Code Example

<Button>
ClearGraphicsAction Clears all

graphics in a graphics layer.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:ClearGraphicsAction GraphicsLayerID="MyGraphicsLayer" TargetName="MyMap" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

MeasureAction

Shows measure distance, radius, and area.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:MeasureAction AreaUnit="SquareMiles" DisplayTotals="True" DistanceUnit="Miles" MapUnits="DecimalDegrees" MeasureMode="Polygon" FillSymbol="{StaticResource DefaultFillSymbol}" TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

PanToAction

Pans to a specified geometr y.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:PanToAction TargetName="MyMap"> <esriBehaviors:PanToAction.Geometry> <esriGeometry:MapPoint X="-120" Y="43" />

</esriBehaviors:PanToAction.Geometry> </esriBehaviors:PanToAction> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>
RedlineAction Draw graphics on the map and add it to a graphics layer.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:RedlineAction Color="#FF32FF00" DrawMode="Freehand" GraphicsLayerID="MyGraphicsLayer" TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

SpatialQueryAction

Draw geometr y on the map to query features in a feature layer. Draw the

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:SpatialQueryAction DrawMode="Rectangle" LayerID="MyGraphicsLayer" Url="http://myserver/ArcGIS/rest/myservice/Ma pServer/2"

results in Symbol="{StaticResource a graphics layer.

GraphicsLayerFillSymbol}" TargetName="MyMap" /> </i:EventTrigger> </i:Interaction.Triggers> </Button>

<Button>
ToggleLayerAction Toggle the visibility of a layer.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:ToggleLayerAction LayerID="MyDynamicLayer" TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

UpdateFeatureLayerA cvtion

Refresh the contents of a feature layer.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:UpdateFeatureLayerAction FeatureLayerID="MyFeatureLayer" TargetName="MyMap" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

ZoomToAction

Zoom to a specified geometr y. If the geometr y is a point, the map will pan.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:ZoomToAction TargetName="MyMap"> <esriBehaviors:ZoomToAction.Geometry> <esriGeometry:Envelope XMin="-110" YMin="40" XMax="-100" YMax="50" /> </esriBehaviors:ZoomToAction.Geometry> </esriBehaviors:ZoomToAction> </i:EventTrigger>

</i:Interaction.Triggers> </Button> <Button>
ZoomToFullExtentActi on Zoom to the full extent of all layers.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:ZoomToFullExtentAction TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button>

ZoomToLayerAction

Zoom the extent of a specified layer.

<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esriBehaviors:ZoomToLayerAction LayerID="MyTileLayer" TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
(3)Trigger(略)
五、Graphics layer 1、新增 Graphics layer

Graphics layer 用于显示用户自定义绘制的点、线、面图形。使用时确保 xaml 文件中 Graphics layer 定义在其它图层的下面,以确保它能显示在其它图层的上面。 <esri:Map x:Name="MyMap" Extent=", , , " > <esri:Map.Layers> <esri:ArcGISTiledMapServiceLayerID="."Url="http://../rest/./MapServer"/> <esri:GraphicsLayer ID=”.” /> </esri:Map.Layers> </esri:Map>

2、管理 Graphics features 在 Graphics layer 上创建 Graphics 的步骤一般如下: (1)获取 Graphics layer (2)创建或获取 Graphic (3)设置 Graphic 的 Geometry (4)应用 Graphic 的 Symbol (5)将 Graphic 添加到 Graphics layers 代码如下: GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; foreach (Graphic graphic in graphicsList) { graphic.Symbol = MySymbol; graphicsLayer.Graphics.Add(graphic); } 3、使用 Draw surface Draw surface 用于获取 Geometries,Geometries 可添加到 Graphics Layer 或用作 identify 和 buffer 操作。 使用 Draw surface,你必须 (1)设置绘图操作的 Symbols (2)设置 Draw surface 的地图 (3)执行逻辑以激活|解除 surface (4)处理 Geometries,以在 surface 上绘图 示例代码如下: xaml 文件: <Grid x:Name="LayoutRoot" Background="White"> <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="RedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources> <esri:Map …> …

cs 文件: MyDrawObject = new Draw(MyMap) { LineSymbol =LayoutRoot.Resources["DrawLineSymbol"] as LineSymbol, FillSymbol =LayoutRoot.Resources["DrawFillSymbol"] as FillSymbol }; MyDrawObject.DrawComplete += MyDrawObject_DrawComplete; MyDrawObject.DrawMode = DrawMode.Polygon; MyDrawObject.IsEnabled = true; private void MyDrawObject_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs args) { Graphic graphic = new Graphic() { Geometry = args.Geometry, Symbol = RedFillSymbol }; GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.Graphics.Add(graphic); } 4、Symbols 和 Renderers Symbols 定义了 Graphic 的非几何学方面的显示特性,如颜色、边框宽度、透明度等。 Renderers 定义了一个或多个应用于 Graphics layer 的 Symbols,指定哪些 Graphics 属性与哪个 Symbol 相符。 Symbols 和 Geometries 类型: Symbol SimpleMarkerSymbol PictureMarkerSymbol SimpleLineSymbol CartographicLineSymbol SimpleFillSymbol PictureFillSymbol Geometry Point Point Polyline Polyline Polygon Polygon 用简单形状来表现点 用 images 来表现点 用预定义的风格来表现线 用定制的风格来表现线 用 Silverlight Brush 来填充多边形 用 images 填充多边形 描述

通常,视觉定义在 xaml 文件中,行为逻辑定义在.cs 文件中,让表现层和业务逻辑层分开,使得应用 程序更容易开发、维护和扩展。 Symbol 的使用: (1)添加命名空间:symbol 类定义在 ESRI.ArcGIS.Client.Symbols 命名空间中(ESRI.ArcGIS.Client 集) xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client"

(2)xaml 文件中定义 Symbol <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="MyRedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources> //Symbol 运用于 FeatureLayer <esri:FeatureLayer ID="." Where="1=1" FeatureSymbol="{StaticResource MyRedFillSymbol}" Url="http://./ArcGIS/rest/services/./MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>POP07_SQMI</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> (3)cs 文件中动态生成 SimpleFillSymbol fillSymbol = new SimpleFillSymbol() { BorderBrush = new SolidColorBrush(Color.FromArgb(0, 255, 0, 0)), BorderThickness = 2, Fill = new SolidColorBrush(Color.FromArgb(alphaVal, redVal, greenVal, blueVal)) }; //Symbol 运用于 GraphicsLayer 的每一个 graphic GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; foreach (Graphic graphic in graphicsLayer.Graphics) graphic.Symbol = fillSymbol; 创建 Unique Value Renderer: <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="a" Fill=""BorderBrush=""BorderThickness="" /> <esriSymbols:SimpleFillSymbol x:Name="b" Fill=""BorderBrush=""BorderThickness="" /> <esriSymbols:SimpleFillSymbol x:Name="c" Fill=""BorderBrush=""BorderThickness="" /> <esri:UniqueValueRenderer x:Name="abcRenderer" Attribute="STATE_NAME" > <esri:UniqueValueRenderer.Infos>

<esri:UniqueValueInfo Value="California" Symbol="{StaticResource a}" /> <esri:UniqueValueInfo Value="New York" Symbol="{StaticResource b}" /> <esri:UniqueValueInfo Value="Kansas" Symbol="{StaticResource c}" /> </esri:UniqueValueRenderer.Infos> </esri:UniqueValueRenderer> </Grid.Resources> // FeatureLayer 中,指定一个过滤,仅仅 California、New York、Kansas 被绘制 //并且将其 STATE_NAME 字段的值显示在 layer 的 Graphics 中 <esri:FeatureLayer ID="" Where="(STATE_NAME='California') OR (STATE_NAME='New York') OR (STATE_NAME = 'Kansas')" Renderer="{StaticResource abcRenderer}" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/Ma pServer/5" > <esri:FeatureLayer.OutFields> <sys:String>STATE_NAME</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> 创建 Class Breaks Renderer:即将 symbol 应用于一组指定范围的 graphics 中。 <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="a" Fill="" BorderBrush=""BorderThickness="" /> <esriSymbols:SimpleFillSymbol x:Name="b" Fill="" BorderBrush=""BorderThickness="" /> <esriSymbols:SimpleFillSymbol x:Name="c" Fill="" BorderBrush=""BorderThickness="" /> <esri:ClassBreaksRenderer x:Name="abcRenderer" Attribute="POP07_SQMI" > <esri:ClassBreaksRenderer.Classes> <esri:ClassBreakInfo MinimumValue="0" MaximumValue="50" Symbol="{StaticResource a}" /> <esri:ClassBreakInfo MinimumValue="51" MaximumValue="125" Symbol="{StaticResource b}" /> <esri:ClassBreakInfo MinimumValue="125" MaximumValue="2000" Symbol="{StaticResource c}" /> </esri:ClassBreaksRenderer.Classes> </esri:ClassBreaksRenderer> </Grid.Resources>

// FeatureLayer 中,将 renderer 和 Feature layer 联系起来,进行地图绘制 //并且将其 POP07_SQMI 字段的值显示在 layer 的 Graphics 中 <esri:FeatureLayer ID="" Where="1=1" Renderer="{StaticResource abcRenderer}" Url="http://./ArcGIS/rest/services/./MapServer/5" > <esri:FeatureLayer.OutFields> <sys:String>POP07_SQMI</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> 5、使用 Clustering(聚类分组,用于 render 的数量很大时) 当点很多和密集时,使用 Clustering 将点分组,使得在 cluster distance 内的多个点用一个点代替。 Clustering 可用于 GraphicsLayer 和 Feature Layer。 (1)使用 FlareClusterer FlareClusterer 可按如下方式添加到 GraphicsLayer 和 FeatureLayer 中: <esri:GraphicsLayer ID="MyGraphicsLayer"> <esri:GraphicsLayer.Clusterer> <esri:FlareClusterer /> </esri:GraphicsLayer.Clusterer> </esri:GraphicsLayer> 效果如下图:

FlareClusterer 的属性如下表: FlareClusterer 属性 FlareBackground 描述 填充的背景颜色(默认红色)

FlareForeground MaximumFlareCount

边界和文字颜色(默认白色) 当鼠标移动到 cluster 时,各小点是否展开的最大数量界限 小于此值时,鼠标移上去会展开各小点;大于此值时,称为 large clusters,其 颜色和大小会根据点多少变化。(默认=10)

Radius Gradient

被 cluster 的半径,单位 pixels(默认 20) LinearGradientBrush 线性渐变刷用于 large clusters (默认:Default = LinearGradientBrush; MappingMode = RelativeToBoundingBox; GradientStop1: Offset = 0, Argb = 127,255,255,0, GradientStop2: Offset = 1, Argb = 127,255,0,0) 示例:修改 FlareClusterer 的默认属性 <Grid.Resources> <LinearGradientBrush x:Name="aGradient" MappingMode="RelativeToBoundingBox" > <GradientStop Color="#990011FF" Offset="0"/> <GradientStop Color="#990055FF" Offset="0.25"/> <GradientStop Color="#990099FF" Offset="0.5"/> <GradientStop Color="#9900CCFF" Offset="0.75"/> <GradientStop Color="#9900FFFF" Offset="1"/> </LinearGradientBrush> </Grid.Resources> <esri:Map x:Name="MyMap"> <esri:Map.Layers> <esri:GraphicsLayer ID="MyGraphicsLayer"> <esri:GraphicsLayer.Clusterer> <esri:FlareClusterer FlareBackground="Yellow" FlareForeground="#99000000" MaximumFlareCount="5" Radius="15" Gradient="{StaticResource aGradient}" /> </esri:GraphicsLayer.Clusterer> </esri:GraphicsLayer> </esri:Map.Layers> </esri:Map> (2)扩展 GraphicsClusterer

为了定制 cluster 的外观,你可以创建一个继承自 ESRI.ArcGIS.Client.GraphicsClusterer 的类,并重 写 OnCreateGraphic()方法来定义 cluster graphic。示例代码如下: public class SumClusterer : GraphicsClusterer { public SumClusterer() { MinimumColor = Colors.Red; MaximumColor = Colors.Yellow; SymbolScale = 1; base.Radius = 50; } public string AggregateColumn { get; set; } public double SymbolScale { get; set; } public Color MinimumColor { get; set; } public Color MaximumColor { get; set; } protected override Graphic OnCreateGraphic(GraphicCollection cluster, MapPoint point, int maxClusterCount) { if (cluster.Count == 1) return cluster[0]; Graphic graphic = null; double sum = 0; foreach (Graphic g in cluster) { if (g.Attributes.ContainsKey(AggregateColumn)) {try{sum += Convert.ToDouble(g.Attributes[AggregateColumn]); }} } double size = (sum + 450) / 30; size = (Math.Log(sum * SymbolScale / 10) * 10 + 20); if (size < 12) size = 12; graphic=new Graphic(){Symbol=new ClusterSymbol() {Size = size},Geometry= point}; graphic.Attributes.Add("Count", sum);

graphic.Attributes.Add("Size", size); graphic.Attributes.Add("Color", InterpolateColor(size - 12, 100)); return graphic; } private static Brush InterpolateColor(double value, double max) { value = (int)Math.Round(value * 255.0 / max); if (value > 255) value = 255; else if (value < 0) value = 0; return new SolidColorBrush(Color.FromArgb(127, 255, (byte)value, 0)); } } 六、Feature Layer Feature Layer 是一种特殊的 Graphics layer(继承自 Graphics layer),除了像 Graphics layer 一样 包含和显示 Graphic features,还能提供: Editing——编辑 (editing 控件包含在 ArcGIS Toolkit 库中,通过 feature service 来编辑 feature layer) Definition expressions——通过 where 子句,条件显示某些 feature Time definitions——通过 time-aware layer 的时间定义,条件显示某些 feature Selection——通过 feature 的子集,达到显示、编辑、分析的目的 feature layer 的三种服务源: Feature layer source ArcGIS Server map service 描述

Dynamic (non-cached) ArcGIS Server map services 能包含多个 feature layers, http://./ArcGIS/rest/services/./MapServer/8 如:

ArcGIS Server feature service

如:http://. /ArcGIS/rest/services/./FeatureServer/0 当 feature layer 在 ArcSDE geodatabase 中时,支持编辑

MapIt

Mapit 包含 REST-ful Web service, table 可能 spatially-enabled。 其 Mapit layers 不支持 Editing 和 time-awareness。 如:http://./SDS/databases/Demo/dbo.USStates_Geographic Feature layers 的关键成员|属性:(仅 Feature layers 支持,Graphics layers 不支持)

Feature layers 成员 Url Where Mode

描述 服务的 url Query 条件显示。where(“1=1”)显示全部 定义获取 features 的方式: Snapshot:获取所有 feature,用于较小的 datasets 或临时 data On Demand:返回当前视窗范围内的 feature Selection Only:初始不返回任何 feature,仅仅在作出 selection 后才返回

OnDemandCacheSize FeatureSymbol SelectionColor TimeExtent

当 Mode=On Demand 时, 定义客户端缓存大小, 用来缓存当前视窗外的 feature 定义一个单独 symbol,用于 rendering 一个单独的 Graphics 时 定义 feature layer 中 selected graphic features 的颜色 实例化或范围显示 feature layer 的时间。 该属性为只读,定义于 ArcGIS Server map 或 feature service 中。

DisableClientCaching Update

是否允许客户端缓存。默认为 true,不能自动更新客户端显示。 更新客户端显示,用于 layer 或 table contents 发生改变时。

Feature layer 应用 //添加 Symbol 命名空间,需要定义 Symbol 给 FeatureSymbol 属性 xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client //定义 Symbol <Grid.Resources> <esriSymbols:SimpleMarkerSymbol x:Name="MyMarkerSymbol" Color="Green" Style="Diamond" Size="14" /> </Grid.Resources> //定义 FeatureLayer <esri:Map x:Name="MyMap" Extent="-130,10,-70,60" > <esri:Map.Layers> <esri:FeatureLayer ID="" Url="http://./ArcGIS/rest/services/./MapServer/0" Where="POP1990 > 75000" FeatureSymbol="{StaticResource MyMarkerSymbol}" >

</esri:FeatureLayer> </esri:Map.Layers> </esri:Map>

效果如下图:各 feature 叠加在一起,不能有效的反应实际数量。

故采用 Clustering 方式改进(设置 ClusterFeatures 属性实现): //添加命名空间 xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client xmlns:sys="clr-namespace:System;assembly=mscorlib” //定义 Symbol <Grid.Resources> <esriSymbols:SimpleMarkerSymbol x:Name="MyMarkerSymbol" Color="Green" Style="Diamond" Size="14" /> </Grid.Resources> //定义 FeatureLayer <esri:Map x:Name="MyMap" Extent="-130,10,-70,60" > <esri:Map.Layers> <esri:FeatureLayer ID="MyFeatureLayer" Url="http://./ArcGIS/rest/services/Specialty/./MapServer/0" Where="POP1990 > 75000"> <esri:FeatureLayer.Clusterer> <esri:FlareClusterer FlareBackground="#99FF0000" FlareForeground="White" MaximumFlareCount="9" /> </esri:FeatureLayer.Clusterer> <esri:FeatureLayer.OutFields>

<sys:String>CITY_NAME</sys:String> <sys:String>POP1990</sys:String> </esri:FeatureLayer.OutFields> </esri:FeatureLayer> </esri:Map.Layers> </esri:Map> 效果如下:

七、Editing ArcGIS Server 10 提供了: 通过 feature service,在 Web 上编辑 Feature layers 的 geographic data 的功能。 通过 geometry service,利用 EditorWidget 控件(ArcGIS Toolkit)实现 Web 编辑功能。 注意:要实现简单 feature 编辑,feature service 中的 features 必须来自 ArcSDE geodatabase。 在 web 上实现编辑后,应该周期性地用 ArcGIS Desktop 确认数据的完整性,虽然 Web API 能完成一些数 据确认,但拓扑学的确认仍不能实现。 实现 Editing 的前提条件: (1)Feature service:提供访问 Feature 的能力,使得地图服务能暴露 feature 的 geometry 和 symbol 属 性 (2)Geometry service:帮助完成通用编辑操作,如创建(creating)、切分(cutting)、变形(reshaping)地理 特征(geographic feature)。在使用 EditorWidget 前,必须提供 geometry service 的 url。 (3)custom editing solutions(自定义编辑方案):不采用 EditorWidget,而自定义。 Add——画或新增 graphics CancelActive——取消地图上的 active 命令

ClearSelection——取消选择所有 graphics Cut——用用户自定义 line 来 cut graphics DeleteSelected——删除 selected 的 graphics 如果 graphics 与一个可编辑的 feature layer 相关联 features 。 , 将会从数据库中删除。 EditVertices——编辑用户点选的 graphic 的顶点 Move——点击和拖动 graphic Reshape——用用户自定义 line 来 reshape graphics(使用 geometry service) Save——提交并保存对所有 feature layer 的编辑 Union——合并用户选择的 graphics(使用 geometry service) 设计 editing 虽然 API 包含了较全面的 Editor Widget,但并不完全适用你的具体应用,可尝试通过如下方法设计 Web editing 应用: (1)Feature sketching:特征草图,如鸟瞰图,适用于精度要求不高的情况。 (2)Attribute-only editing:仅仅属性编辑,适用于不需要改变几何学特征的情况。 (3)Editing adjacent polygons:编辑邻接多边形,适用于仅需 reshape 现有的多边形或改变其属性而不 会引起裂口(gaps)或叠加(overlaps)。 (4) Citizen Participation,or geo-wiki:适用于不需要关心编辑 GIS 数据,仅仅需要在地图上放置点 feature 和进行有限的属性编辑。如市民向政府部门反映情况,要求能在地图上放置点,该点包括包括相片、简短 描述等辅助信息。你需要 code 一些安全检查,以确保他们仅仅能编辑和删除自己的事件,并周期性的清 除数据库。 (5)Specialized field work:假定有一些分析家管理街道数据库,仅仅能在街道网络 layer 新建和删除线 feature,那么 Template Picker 必须能指示出新建了哪种类型的道路(泊油路、铺石转路等),能对属性 进行随意的编辑。。。 八、Tasks task classes 提供了如下一些空间分析功能: (1)Query:属性(attribute)——空间(spatial),双向查询 从一个 feature layer 中获取 features,展示 features 的 geometries 或 attribute 目的是为了查询它的具体信息 a、简单查询:通过关键字查询,获得结果列表 b、Attribute 查询:通过关键字查询,获得结果的详细信息,并在地图上显示 c、Spatial 查询:点查询、线查询、拉框查询、任意多边形查询 (2)Find:通过特定属性值,查询其空间定位和结果列表 从一个或多个 layer 中,通过 attribute 查找 features,展示其 geometries 或 attribute

通过关键字查询,获得结果的列表(显示结果所在层的信息,如层名等,但不显示结果本身的详细信息), 并在地图上显示。(目的是为了找到它的位置)。 (3)Identify:相交定位,得到 features 在地图上点击,识别并显示点击到的 features 的详细信息。 (4)Address locator:地址(geocode)——位置(location),双向查询 输入地址,显示地图上的位置;点击地图上的位置,显示地址 (5)Geometry——几何的操作,如计算面积和长度、buffering、projection、simplifying (6)Goeprocessing——复杂 GIS 分析(通过 Goeprocessing 服务发布的 Goeprocessing 模型) (7)Route——路径分析 1、Query 示例代码 (1)xaml 文件: //添加 Symbol 命名空间 xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client //创建 Symbol <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="ResultsFillSymbol" Fill="#500000FF" BorderBrush="Blue" BorderThickness="1" /> </Grid.Resources> //创建 GraphicsLayer,显示 Query 查询结果 <esri:GraphicsLayer ID="MyGraphicsLayer"> <esri:GraphicsLayer.MapTip> <Grid Background="LightYellow"> <StackPanel> <TextBlock Text="{Binding [STATE_NAME]}" FontWeight="Bold" /> <StackPanel Orientation="Horizontal"> <TextBlock Text="Population Density (2007): " /> <TextBlock Text="{Binding [POP07_SQMI]}" /> </StackPanel> </StackPanel> <Border BorderBrush="Black" BorderThickness="1" /> </Grid>

</esri:GraphicsLayer.MapTip> </esri:GraphicsLayer> //Query 查询对话框 <Canvas HorizontalAlignment="" VerticalAlignment="" Margin="0,15,7,0" Width="250" > <Rectangle Fill="#CC5C90B2" Stroke="Gray" RadiusX="10" RadiusY="10" Width="230" Height="55" /> <TextBlock Text="输入 query 并点执行" Foreground="White" FontSize="10" Margin="10,5,0,0" /> <TextBox x:Name="QueryTextBox" Width="150" Margin="15,22,0,0" Text="POP07_SQMI > 500" /> <Button x:Name="QueryButton" Content="执行" Margin="168,23,0,0" Click="QueryButton_Click" /> </Canvas> (2)cs 文件: //添加命名空间 using ESRI.ArcGIS.Client.Tasks; using ESRI.ArcGIS.Client.Symbols; // 点击执行按钮,执行查询 private void QueryButton_Click(object sender, RoutedEventArgs e) { //初始化 Query task QueryTask queryTask = new QueryTask("http://./ArcGIS/rest/services/./MapServer/5"); queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted; queryTask.Failed += QueryTask_Failed; // 初始化 Query 及其参数:返回 geometry、州名、人口密度 Query query = new Query(); query.ReturnGeometry = true; query.OutFields.AddRange(new string[] { "STATE_NAME", "POP07_SQMI" }); //query 条件 query.Where = QueryTextBox.Text; //执行 query queryTask.ExecuteAsync(query); }

//query 完成后绘制查询结果 private void QueryTask_ExecuteCompleted(object sender, QueryEventArgs args) { //获得 graphicsLayer,并清除先前的结果 GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); // Check for new results FeatureSet featureSet = args.FeatureSet; if (featureSet.Features.Count > 0) { //将结果添加到地图 foreach (Graphic resultFeature in featureSet.Features) { resultFeature.Symbol = ResultsFillSymbol; graphicsLayer.Graphics.Add(resultFeature); } } else { MessageBox.Show("No features found"); } } // query 失败,显示错误原因 private void QueryTask_Failed(object sender, TaskFailedEventArgs args) { MessageBox.Show("Query failed: " + args.Error); } 2、Find 示例代码 (1)xaml 文件: //添加 Symbol 命名空间

xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client //创建 Symbol <Grid.Resources> <esriSymbols:SimpleFillSymbol x:Name="ResultsFillSymbol" Fill="#64FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources> //创建 GraphicsLayer,显示查询结果 <esri:GraphicsLayer ID="MyGraphicsLayer"> <esri:GraphicsLayer.MapTip> <Grid Background="LightYellow"> <StackPanel Margin="5"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding [NAME]}" FontWeight="Bold" /> <TextBlock Text=" County, " FontWeight="Bold" /> <TextBlock Text="{Binding [STATE_NAME]}" FontWeight="Bold" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Population (2007): " /> <TextBlock Text="{Binding [POP2007]}" /> </StackPanel> </StackPanel> <Border BorderBrush="Black" BorderThickness="1" /> </Grid> </esri:GraphicsLayer.MapTip> </esri:GraphicsLayer> //Find 对话框 <Canvas HorizontalAlignment="" VerticalAlignment="" Margin="0,15,7,0" Width="230" > <Rectangle Fill="#CC5C90B2" Stroke="Gray" RadiusX="10" RadiusY="10" Width="210" Height="55" /> <TextBlock Text="Find 的国家名:" Foreground="White" FontSize="10" Margin="10,5,0,0" /> <TextBox x:Name="FindTextBox" Width="150" Margin="15,22,0,0" Text="Wash" />

<Button x:Name="FindButton" Content="Find" Margin="168,23,0,0" Click="FindButton_Click" /> </Canvas> (2)cs 文件 //添加命名空间 using ESRI.ArcGIS.Client; using ESRI.ArcGIS.Client.Tasks; // 点击 find 按钮,执行 Find private void FindButton_Click(object sender, RoutedEventArgs e) { //初始化 Find task FindTask findTask = new FindTask("http://./ArcGIS/rest/services/./MapServer/"); findTask.ExecuteCompleted += FindTask_ExecuteCompleted; findTask.Failed += FindTask_Failed; //初始化 Find 参数:将 countries 图层的 Name 字段作为 Find Field FindParameters findParameters = new FindParameters(); findParameters.LayerIds.AddRange(new int[] { 3 }); findParameters.SearchFields.AddRange(new string[] { "NAME" }); //返回 find 结果的 feature geometry findParameters.ReturnGeometry = true; //textbox 的 text 作为查询关键字 findParameters.SearchText = FindTextBox.Text; //执行查询 findTask.ExecuteAsync(findParameters); } //find 结束后,将结果绘制在地图上 private void FindTask_ExecuteCompleted(object sender, FindEventArgs args) { //获取 graphicsLayer,清除先前的查询结果 GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics();

// Check for new results if (args.FindResults.Count > 0) { //将结果添加进地图 foreach (FindResult result in args.FindResults) { result.Feature.Symbol = ResultsFillSymbol; graphicsLayer.Graphics.Add(result.Feature); } } else { MessageBox.Show("No features found"); } } //find 失败时,显示失败原因 private void FindTask_Failed(object sender, TaskFailedEventArgs args) { MessageBox.Show("Find failed: " + args.Error); } 3、Identify 示例代码 (1)xaml 文件: //添加命名空间 xmlns:esriTasks="clr-namespace:ESRI.ArcGIS.Client.Tasks;assembly=ESRI.ArcGIS.Client" xmlns:esriSymbols="clr-namespace:ESRI.ArcGIS.Client.Symbols;assembly=ESRI.ArcGIS.Client xmlns:slData="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" //定义 task resources <Grid.Resources> <esriSymbols:PictureMarkerSymbol x:Name="IdentifyLocationSymbol" OffsetX="35" OffsetY="35" Source="/Assets/images/i_about.png" />

<esriSymbols:SimpleFillSymbol x:Name="SelectedFeatureSymbol" Fill="#64FF0000" BorderBrush="Red" BorderThickness="2" /> </Grid.Resources> //创建 GraphicsLayer,容纳 Identify 的地图结果显示 <esri:GraphicsLayer ID="ResultsGraphicsLayer" /> <esri:GraphicsLayer ID="IdentifyIconGraphicsLayer" /> //Identify 的属性结果显示界面 <StackPanel Margin="10" HorizontalAlignment="Left"> <Grid> <Rectangle Fill="#CC5C90B2" Stroke="Gray" RadiusX="10" RadiusY="10" /> <TextBlock Text="点击地图 identify feature" Foreground="White" FontSize="10" Margin="10,5,10,5" /> <StackPanel x:Name="IdentifyResultsStackPanel" Margin="15,30,15,10" Visibility="Collapsed"> <TextBlock Text="Select a result from the list to display it" Foreground="White" FontSize="10" Margin="0,0,0,5" /> <ComboBox x:Name="IdentifyComboBox" SelectionChanged="IdentifyComboBox_SelectionChanged" /> <ScrollViewer MaxHeight="340" Margin="0,10,0,0"> <slData:DataGrid x:Name="IdentifyDetailsDataGrid" AutoGenerateColumns="False" HeadersVisibility="None" > <slData:DataGrid.Columns> <slData:DataGridTextColumn Binding="{Binding Path=Key}" FontWeight="Bold"/> <slData:DataGridTextColumn Binding="{Binding Path=Value}"/> </slData:DataGrid.Columns> </slData:DataGrid> </ScrollViewer> </StackPanel> </Grid> </StackPanel> (2)cs 文件

//添加命名空间 using ESRI.ArcGIS.Client.Tasks; using ESRI.ArcGIS.Client.Symbols; // IdentifyResult private List<IdentifyResult> _lastIdentifyResult; public MainPage() { InitializeComponent(); } // 点击地图,执行 Identify private void MyMap_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs args) { //在 identify 的地方(鼠标点击附近)显示一个 icon GraphicsLayer graphicsLayer = MyMap.Layers["IdentifyIconGraphicsLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic() { Geometry = args.MapPoint, Symbol = IdentifyLocationSymbol }; graphicsLayer.Graphics.Add(graphic); // 初始化 Identify task IdentifyTask identifyTask = new IdentifyTask("http://./ArcGIS/rest/services/./MapServer"); identifyTask.ExecuteCompleted += IdentifyTask_ExecuteCompleted; identifyTask.Failed += IdentifyTask_Failed; //初始化 Identify parameters,指定 searching 的 layers IdentifyParameters identifyParameters = new IdentifyParameters(); identifyParameters.LayerOption = LayerOption.all; // 设置 identify parameters:通过地图的现有属性 identifyParameters.MapExtent = MyMap.Extent; identifyParameters.Width = (int)MyMap.ActualWidth; identifyParameters.Height = (int)MyMap.ActualHeight; //通过点击执行 Identify features

identifyParameters.Geometry = args.MapPoint; identifyTask.ExecuteAsync(identifyParameters); } //identify 完成后,查询结果的 Attribute 显示窗口 private void IdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args) { //清除旧的结果 IdentifyComboBox.Items.Clear(); // Check for new results if (args.IdentifyResults.Count > 0) { IdentifyResultsStackPanel.Visibility = Visibility.Visible; //将结果添加到 ComboBox foreach (IdentifyResult result in args.IdentifyResults) { string title = string.Format("{0} ({1})", result.Value.ToString(), result.LayerName); IdentifyComboBox.Items.Add(title); } // Workaround for ComboBox bug IdentifyComboBox.UpdateLayout(); // Store the list of identify results _lastIdentifyResult = args.IdentifyResults; // Initialize ComboBox and fire SelectionChanged IdentifyComboBox.SelectedIndex = 0; } else { // Hide ComboBox and attributes DataGrid and notify user IdentifyResultsStackPanel.Visibility = Visibility.Collapsed; MessageBox.Show("No features found");

} }

//多个结果时,点击下拉框更改其它结果 void IdentifyComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { //地图上清除先前的结果 GraphicsLayer graphicsLayer = MyMap.Layers["ResultsGraphicsLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); // Check that ComboBox has a selected item. Needed because SelectionChanged fires // when ComboBox.Clear is called. if (IdentifyComboBox.SelectedIndex > -1) { // Update DataGrid with selected feature's attributes Graphic selectedFeature = _lastIdentifyResult[IdentifyComboBox.SelectedIndex].Feature; IdentifyDetailsDataGrid.ItemsSource = selectedFeature.Attributes; // Apply symbol and add selected feature to map

selectedFeature.Symbol = SelectedFeatureSymbol; graphicsLayer.Graphics.Add(selectedFeature); } } //identify 失败时,显示失败原因 private void IdentifyTask_Failed(object sender, TaskFailedEventArgs args) { MessageBox.Show("Identify failed: " + args.Error); } 4、Adress locator 示例代码(暂未学) 5、Geometry 示例代码(暂未学) 6、Geoprocessing 示例代码(暂未学) 7、Route 示例代码(暂未学)


搜索更多“ArcGIS API for SilverlightWPF 2.1学习笔记”

网站地图

All rights reserved Powered by 伤城文章网 5xts.com

copyright ©right 2010-2021。
伤城文章网内容来自网络,如有侵犯请联系客服。zhit325@126.com