Arcgis for Silverlight学习(一)

时间:2022-04-29
本文章向大家介绍Arcgis for Silverlight学习(一),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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;
}
}