1.地图的加载
arcgis server for silverlight 通过控件map实现地图的浏览功能。map控件的使用方法如下:
<esri:Map x:Name="MyMap" WrapAround="True" IsLogoVisible="False" Extent="-15000000,2000000,-7000000,8000000"
MouseMove="MyMap_MouseMove" Progress="MyMap_Progress" ExtentChanged="MyMap_ExtentChanged"> <esri:ArcGISTiledMapServiceLayer ID="MyBaseLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"> </esri:ArcGISTiledMapServiceLayer> <esri:ArcGISTiledMapServiceLayer ID="Imagery" Visible="False" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" /> <esri:ArcGISDynamicMapServiceLayer ID="MyDynamicLayer" Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer"></esri:ArcGISDynamicMapServiceLayer>
</esri:Map>在Map对象是地图的容器,在其中可以添加自己需要的地图图层。ArcGISTitleMapServerLayer,可以加载网上在线的地图。ArcgisDinamicLayer可以加载本地的地图。Extent 可以设置地图初始化加载的范围。
2.要素图层的聚合和MapTip
API提供了对图层要素的聚合,还有MapTip功能
<esri:FeatureLayer ID="MyFeatureLayer" IgnoreServiceScaleRange="True"
Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/0">//图层聚合
<esri:FeatureLayer.Clusterer> <esri:FlareClusterer></esri:FlareClusterer> </esri:FeatureLayer.Clusterer>//MapTip
<esri:FeatureLayer.MapTip> <Border CornerRadius="5" BorderBrush="Black" BorderThickness="1" Background="White"> <TextBlock Text="{Binding [POP2000]}" Foreground="Black" Margin="5"></TextBlock> </Border> </esri:FeatureLayer.MapTip> </esri:FeatureLayer>3.图层控制
API提供了图层控制功能,通过Legend控件。Legend控件可以以树的形式展示图层,但是并不能对图层进行控制,我们需要设置MapLayerTemplate和LayerTemplate,分别为两个模板绑定DataTemplate
<esri:Legend Map="{Binding ElementName=MyMap}"
LayerItemsMode="Tree" ShowOnlyVisibleLayers="False" Margin="5,5,5,5"> <esri:Legend.MapLayerTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <CheckBox Content="{Binding Label}" IsChecked="{Binding IsEnabled, Mode=TwoWay}" IsEnabled="{Binding IsInScaleRange}" > </CheckBox> </StackPanel> </DataTemplate> </esri:Legend.MapLayerTemplate> <esri:Legend.LayerTemplate> <DataTemplate> <CheckBox Content="{Binding Label}" IsChecked="{Binding IsEnabled, Mode=TwoWay}" IsEnabled="{Binding IsInScaleRange}" > </CheckBox> </DataTemplate> </esri:Legend.LayerTemplate> </esri:Legend>这样一个普通的图层控制工具就有了。
4.LayerAction
API提供了很多LayerAction,下面说说常用的几个LayerAction
距离测量,能够测出要素之间的距离,也称多段线测量,需要地图有空间参考
<Button Style="{StaticResource ResourceKey=MenuItem}" Content="MeasurePolyline">
<i:Interaction.Triggers> <i:EventTrigger EventName="Click">//定义距离测量
<esri:MeasureAction MeasureMode="Polyline" MapUnits="Meters" DistanceUnit="Meters" DisplayTotals="True" TargetName="MyMap"> </esri:MeasureAction> </i:EventTrigger> </i:Interaction.Triggers> </Button>面积测量,能够进行面积的测量。需要地图有空间参考,同时需要设置测量的方式,显示的单位,面积单位等。
<Button Style="{StaticResource ResourceKey=MenuItem}" Content="MeasurePolygon">
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esri:MeasureAction MeasureMode="Polygon" MapUnits="Meters" DistanceUnit="Meters" AreaUnit="SquareMeters" TargetName="MyMap" DisplayTotals="True" FillSymbol="{StaticResource DefaultFillSymbol}"> </esri:MeasureAction> </i:EventTrigger> </i:Interaction.Triggers> </Button>返回全局地图的行为,能够快速返回全局地图
<Button Style="{StaticResource ResourceKey=MenuItem}" Content="ZoomToFullExtent">
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esri:ZoomToFullExtentAction TargetName="MyMap"></esri:ZoomToFullExtentAction> </i:EventTrigger> </i:Interaction.Triggers> </Button>ZoomToLayer。快速定位到指定的图层
<Button Style="{StaticResource ResourceKey=MenuItem}" Content="Zoom To Layer">
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esri:ZoomToLayerAction LayerID="MyFeatureLayer" TargetName="MyMap"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>图层控制Toggle行为,能够控制图层的显示,隐藏指定的图层
<Button Style="{StaticResource MenuItem}" Content="Toogle">
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <esri:ToggleLayerAction LayerID="MyDynamicLayer" TargetName="MyMap"> </esri:ToggleLayerAction> </i:EventTrigger> </i:Interaction.Triggers> </Button>同时API还能够了显示地图坐标的行为,一般不建议采用。可以自己写代码实现类似的功能。
5.地图坐标的显示
先看前台Xaml代码
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5"
Background="#DD919191" Width="220" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,200,0,0"> <Border.Effect> <DropShadowEffect ShadowDepth="2"></DropShadowEffect> </Border.Effect> <StackPanel Orientation="Vertical" Margin="5" Background="White"> <TextBlock Text="屏幕坐标"></TextBlock> <StackPanel Orientation="Horizontal"> <TextBlock Text="X:"></TextBlock> <TextBlock x:Name="txtX"></TextBlock> <TextBlock Text="Y:" Margin="3,0,0,0"></TextBlock> <TextBlock x:Name="txtY"></TextBlock> </StackPanel> <StackPanel> <TextBlock Text="地图坐标"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="X:"></TextBlock> <TextBlock x:Name="MapX"></TextBlock> <TextBlock Margin="3,0,0,0" Text="Y:"></TextBlock> <TextBlock x:Name="MapY"></TextBlock> </StackPanel> </StackPanel> </Border>前台设计坐标的显示,用Textblock显示
后台代码
private void MyMap_MouseMove(object sender, MouseEventArgs e)
{ if (MyMap.Extent != null) { System.Windows.Point point = e.GetPosition(MyMap); txtX.Text = e.GetPosition(MyMap).X.ToString(); txtY.Text = e.GetPosition(MyMap).Y.ToString(); ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(); mapPoint = MyMap.ScreenToMap(point); if (MyMap.WrapAroundIsActive) { mapPoint = ESRI.ArcGIS.Client.Geometry.Geometry.NormalizeCentralMeridian(mapPoint) as ESRI.ArcGIS.Client.Geometry.MapPoint; } if (mapPoint != null) {MapX.Text = string.Format("{0}", Math.Round(mapPoint.X, 4));
MapY.Text = string.Format("{0}", Math.Round(mapPoint.Y, 4)); } } }在mouseover事件获取地图的屏幕坐标,通过ScreenToMap 获取地图的坐标。期间需要借助MapPoint实现坐标的从Point转换。使用的时候,需要谨记对象的初始化。
7.获取地图初始化的坐标
有时需要获取地图加载过程中的地图显示范围。通过地图的ExtentChanged事件。
private void MyMap_ExtentChanged(object sender, ExtentEventArgs e)
{ txtExtent.Text = string.Format("地图范围:\nMinX:{0}\nMinY:{1}\nMaxX:{2}\nMaxY:{3}" ,e.NewExtent.XMin,e.NewExtent.YMin,e.NewExtent.XMax,e.NewExtent.YMax); }8.地图缩放和地图移动的时间设置
通过Api 我们可以设置地图的缩放的时间和地图移动的时间,有时候会有更好的效果。通过Silder控件来实现事件ValueChanged。
private void ZoomAnimation_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{ int seconds = Convert.ToInt32(e.NewValue); MyMap.ZoomDuration = new TimeSpan(0,0,seconds); lalZoom.Text = string.Format("value:{0}",seconds); }private void PanAnimation_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{ int sendcons = Convert.ToInt32(e.NewValue); MyMap.PanDuration = new TimeSpan(0, 0, sendcons); lalPan.Text = string.Format("Value:{0}",sendcons); }前台代码如下:
<Border BorderBrush="Black" BorderThickness="1" Background="DarkGray" HorizontalAlignment="Right" Margin="0,500,0,0" Height="200">
<Border.Effect> <DropShadowEffect></DropShadowEffect> </Border.Effect> <StackPanel Orientation="Vertical" Background="White" Margin="5"> <StackPanel> <TextBlock Text="设置地图缩放的速度"></TextBlock> <TextBlock Text="Value:0" x:Name="lalZoom"></TextBlock> <Slider x:Name="ZoomAnimation" Minimum="0" Maximum="20" SmallChange="1" LargeChange="5" Width="200" Cursor="Hand" ValueChanged="ZoomAnimation_ValueChanged"></Slider> </StackPanel> <StackPanel> <TextBlock Text="设置地图移动速度"></TextBlock> <TextBlock Text="Value:0" x:Name="lalPan"></TextBlock> <Slider x:Name="PanAnimation" Minimum="0" Maximum="20" SmallChange="1" LargeChange="5" Width="200" Cursor="Hand" ValueChanged="PanAnimation_ValueChanged"></Slider> </StackPanel> </StackPanel> </Border>8.地图加载的进度条
当我们需要加载海量的地理信息数据时,地图加载的速度会变慢许多,这时候就需要地图进度条来实时显示地图加载的过程。API为我们提供了MapProcess,
为该控件绑定地图对象即可
<!--<esri:MapProgressBar Width="150" Map="{Binding ElementName=MyMap}" Height="30"></esri:MapProgressBar>-->
也可以使用silverlight的ProcessBar控件来实现。这时需要借助map的process事件。
前台代码
<ProgressBar Minimum="0" Maximum="100" Width="150" Height="30" x:Name="MyProcess"></ProgressBar>
<TextBlock x:Name="txtProcess" Text="100%" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>后台代码
private void MyMap_Progress(object sender, ProgressEventArgs e)
{ if (e.Progress < 100) { processGrid.Visibility = Visibility.Visible;//获取处理的进程
MyProcess.Value = e.Progress; txtProcess.Text = string.Format("正在加载地图:{0}%", e.Progress); } else { processGrid.Visibility = Visibility.Collapsed; } }10.图层切换
图层切换其实和图层控制是一个道理,有时候,我们需要切换图层,比如从影像图切换到TitleLayer等。一般通过图层地 Visiable来设置。
前台代码
<StackPanel Margin="5" Background="White" Orientation="Horizontal">
//通过radiobutton进行图层切换
<RadioButton x:Name="radImage" Content="卫星影像" Click="radImage_Click"></RadioButton> <RadioButton x:Name="radTitle" Content="矢量地图" Click="radImage_Click"></RadioButton> </StackPanel>后代代码
private void radImage_Click(object sender, RoutedEventArgs e)
{//实例化radiobutton控件
RadioButton radioButton = sender as RadioButton;//radiobutton的name判断
switch (radioButton.Name){ case"radImage":MyMap.Layers["MyBaseLayer"].Visible = false;MyMap.Layers["Imagery"].Visible = true;break;case"radTitle"://图层显示
MyMap.Layers["MyBaseLayer"].Visible = true;MyMap.Layers["Imagery"].Visible = false;break;}}