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