1. 程式人生 > 其它 >Arcgis for Silverlight學習(一)

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