zoukankan      html  css  js  c++  java
  • ArcGIS API for Silverlight 入门学习笔记(三):基础地图实例

    该实例主要是包含六部分:地图范围、坐标、动画效果、全屏、比例尺、进度条。

    前期准备工作

    前台代码0
    <UserControl x:Class="APIforSilverlightSamp.s2"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ESRI
    ="clr-namespace:ESRI.ArcGIS.Client;assembly=ESRI.ArcGIS.Client"
    mc:Ignorable
    ="d">
    <Grid x:Name="LayoutRoot" Background="White">
    <ESRI:Map x:Name="mymap">
    <ESRI:Map.Layers>
    <ESRI:ArcGISTiledMapServiceLayer ID="WorldImageLayer" x:Name="WorldImageLayer" Initialized="WorldImageLayer_Initialized"
    Url
    ="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer" />
    </ESRI:Map.Layers>
    </ESRI:Map>
    </Grid>
    </UserControl>


    代码<Application.Resources>
    <Application.Resources>
    <Style x:Key="rectBottom" TargetType="Rectangle">
    <Setter Property="RadiusX" Value="10" />
    <Setter Property="RadiusY" Value="10" />
    <Setter Property="Fill" Value="#22000000" />
    <Setter Property="Canvas.Left" Value="5" />
    <Setter Property="Canvas.Top" Value="5" />
    <Setter Property="Width" Value="215" />
    <Setter Property="Height" Value="110" />
    </Style>
    <Style x:Key="rectMiddle" TargetType="Rectangle">
    <Setter Property="RadiusX" Value="10" />
    <Setter Property="RadiusY" Value="10" />
    <Setter Property="Fill" Value="#775C90B2" />
    <Setter Property="Canvas.Left" Value="0" />
    <Setter Property="Canvas.Top" Value="0" />
    <Setter Property="Width" Value="215" />
    <Setter Property="Height" Value="110" />
    <Setter Property="Stroke" Value="Gray" />
    </Style>
    <Style x:Key="rectTop" TargetType="Rectangle">
    <Setter Property="RadiusX" Value="5" />
    <Setter Property="RadiusY" Value="5" />
    <Setter Property="Fill" Value="#FFFFFFFF" />
    <Setter Property="Canvas.Left" Value="10" />
    <Setter Property="Canvas.Top" Value="10" />
    <Setter Property="Width" Value="195" />
    <Setter Property="Height" Value="90" />
    <Setter Property="Stroke" Value="DarkGreen" />
    </Style>
    </Application.Resources>
    它们就相当于网页中的css。

    1.地图范围


    前台代码1
    所有的布局工作都在一个Grid中进行,给它起个名字叫LayoutRoot。Grid里面放了一个ESRI:Map元素(Map控件),它继承自Silverlight的Control,所以拥有Width和Height属性,默认是Auto,自动填充整个Grid。Map.Layers是一个集合,可以往里面添加layer,这里的layer指的是ArcGIS Server或其他软件发布的地图服务,目前SilverlightAPI中支持的能够直接使用的有ArcGISDynamicMapServiceLayer,ArcGISTiledMapServiceLayer,ArcGISImageServiceLayer,分别对应ArcGIS Server发布的动态地图服务,缓存地图服务(两种Map Service)和ImageService,这三种图层是拿来即用的,如果你想加入别的地图服务,比如WMS服务,则需要自己继承相应类型的的Layer;此外还有GraphicsLayer,ElementLayer,SilverlightAPI特有的FeatureLayer等。

    后台代码1
    private void WorldImageLayer_Initialized(object sender, EventArgs e)
    {
    Map1.ExtentChanged
    += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(Map1_ExtentChange);
    Map1.ExtentChanging
    += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(Map1_ExtentChange);
    }

    private void Map1_ExtentChange(object sender, ESRI.ArcGIS.ExtentEventArgs e)
    {
    TBextent.Text
    = string.Format("地图范围:\nMinX:{0}\nMinY:{1}\nMaxX:{2}\nMaxY:{3}",
    e.NewExtent.XMin, e.NewExtent.YMin, e.NewExtent.XMax, e.NewExtent.YMax);
    }


    Map控件里面已经封装了一些事件来供我们使用,我们可以在需要的时候捕获它们来进行处理。如果做过ArcGIS产品的二次开发,你应该已经想到我们要捕获的就是Map的ExtentChanged事件;而要在地图移动或者缩放的过程中也实时显示地图范围,则还要对ExtentChanging事件做处理。


    2.地图坐标

    前台代码2
    <!--mouse coords-->
    <Canvas Width="215" Height="110" Margin="0,120,0,0" VerticalAlignment="Top">
    <Rectangle Style="{StaticResource rectBottom}" />
    <Rectangle Style="{StaticResource rectMiddle}" />
    <Rectangle Style="{StaticResource rectTop}" />
    <StackPanel Orientation="Vertical" Margin="20,15,15,0">
    <TextBlock x:Name="TBscreencoords"
    HorizontalAlignment
    ="Left" VerticalAlignment="Center" Text="屏幕坐标:" TextWrapping="Wrap" FontWeight="Bold" />
    <TextBlock x:Name="TBmapcoords"
    HorizontalAlignment
    ="Left" VerticalAlignment="Center" Text="地图坐标:" TextWrapping="Wrap" FontWeight="Bold" />
    </StackPanel>
    </Canvas>


    那么接下来要捕捉那个事件呢?当然就是MouseMove啦。不过如果查看SilverlightAPI中的Map类,发现并没有这个事件。但要记住Map是继承自xaml中的Control,Control继承自FrameworkElement,FrameworkElement继承自UIElement,这里就有一个MouseMove事件了。所以Map控件的MouseMove是xaml中而不是Siverlight API中的事件(当然整个SilverlightAPI都是建立在xaml基础上的)。ESRI:Map标签中添加一个MouseMove事件<ESRI:Map x:Name="Map1" MouseMove="Map1_MouseMove">

    后台代码2
    private void Map1_MouseMove(object sender, MouseEventArgs e)
    {
    if (Map1.Extent != null)
    {
    System.Windows.Point screenPnt
    = e.GetPosition(Map1);
    TBscreencoords.Text
    = string.Format("屏幕坐标:\nX:{0},Y:{1}", screenPnt.X, screenPnt.Y);

    ESRI.ArcGIS.Geometry.MapPoint mapPnt
    = Map1.ScreenToMap(screenPnt);
    TBmapcoords.Text
    = string.Format("地图坐标:\nX:{0}\nY:{1}", Math.Round(mapPnt.X, 4), Math.Round(mapPnt.Y, 4));
    }
    }


    可以看到Map控件提供了屏幕与地图坐标之间转换的方法,好比开发人员的一座桥梁,用来往返于Silverlight特性与地图之间,非常方便。需要说明的是,这里GetPosition(Map1)获得的屏幕坐标是相对于Map控件的,而不是显示器的左上角。ok,继续来看第三部分。


    3.Map里的动画效果

    前台代码3
    <!--map animation slider-->
    <Canvas Width="215" Height="130" Margin="0,240,0,0" VerticalAlignment="Top">
    <Rectangle Style="{StaticResource rectBottom}" Height="130" />
    <Rectangle Style="{StaticResource rectMiddle}" Height="130" />
    <Rectangle Style="{StaticResource rectTop}" Height="110" />
    <StackPanel Orientation="Vertical" Margin="20,15,15,0">
    <TextBlock HorizontalAlignment="Left" Text="设置地图缩放动作持续时间:" TextWrapping="Wrap" FontWeight="Bold" />
    <TextBlock x:Name="TBzoomdurationvalue" HorizontalAlignment="Left" Text="当前值:" TextWrapping="Wrap" FontWeight="Bold" />
    <Slider x:Name="sliderzoomanimation" Orientation="Horizontal" Minimum="0" Maximum="20" SmallChange="1"
    LargeChange
    ="5" Cursor="Hand" ValueChanged="slideranimation_ValueChanged" Width="180" />
    <TextBlock HorizontalAlignment="Left" Text="设置地图平移动作持续时间:" TextWrapping="Wrap" FontWeight="Bold" />
    <TextBlock x:Name="TBpandurationvalue" HorizontalAlignment="Left" Text="当前值:" TextWrapping="Wrap" FontWeight="Bold" />
    <Slider x:Name="sliderpananimation" Orientation="Horizontal" Minimum="0" Maximum="20" SmallChange="1"
    LargeChange
    ="5" Cursor="Hand" ValueChanged="slideranimation_ValueChanged" Width="180" />
    </StackPanel>
    </Canvas>


    当地图放大和平移时都可以看到平滑的效果,这归功于Silverlight的动画功能。Map在封装完动画效果后,给了我们两个属性来对它们进行设置:PanDuration和ZoomDuration,用于设置这两个动作持续的时间。它们都是TimeSpan类型的变量,合理的设置可以带来良好的用户体验。

    后台代码3
    private void slideranimation_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
    Slider s
    = sender as Slider;
    if (s.Name == "sliderzoomanimation")
    {
    Map1.ZoomDuration
    = new TimeSpan(0, 0, Convert.ToInt32(sliderzoomanimation.Value));
    TBzoomdurationvalue.Text
    = string.Format("当前值:{0}秒", Convert.ToInt32(sliderzoomanimation.Value));
    }
    else
    {
    Map1.PanDuration
    = new TimeSpan(0, 0, Convert.ToInt32(sliderpananimation.Value));
    TBpandurationvalue.Text
    = string.Format("当前值:{0}秒", Convert.ToInt32(sliderpananimation.Value));
    }
    }


    对应着地图效果,应该很容易理解。但是细心的朋友可能会发现,初始时值没有显示,不要紧,有办法解决,在页面初始函数中加入下面两句就可以了

    TBzoomdurationvalue.Text = string.Format("当前值:{0}.{1}秒", Map1.ZoomDuration.Seconds, Map1.ZoomDuration.Milliseconds);

     TBpandurationvalue.Text = string.Format("当前值:{0}.{1}秒", Map1.PanDuration.Seconds, Map1.PanDuration.Milliseconds);

    4.设置全屏

     

    前台代码4
    <!--operation info-->
    <Canvas Width="215" Height="110" Margin="0,0,0,30" VerticalAlignment="Bottom">
    <Rectangle Style="{StaticResource rectBottom}" />
    <Rectangle Style="{StaticResource rectMiddle}" Fill="#77FF0000" />
    <Rectangle Style="{StaticResource rectTop}" />
    <TextBlock Margin="20,15,15,0" Text="地图操作提示: " >
    <LineBreak></LineBreak>双击放大
    <LineBreak></LineBreak>Shift+拖拽:放大到指定范围
    <LineBreak></LineBreak> Ctrl+Shift+拖拽:缩小到指定范围
    </TextBlock>
    <ToggleButton x:Name="TBfullscreen" Content="点击切换地图全屏" HorizontalAlignment="Center" Canvas.Left="100" Canvas.Top="15" Height="30" Click="TBfullscreen_Click" />
    </Canvas>

    把以上代码放到Gridright Grid中

    后台代码:

    private void TBfullscreen_Click(object sender, RoutedEventArgs e)
    {
    System.Windows.Interop.Content content
    = Application.Current.Host.Content;
    content.IsFullScreen
    =!content.IsFullScreen;
    }

    5.比例尺

     

    前台代码5
    <!--scale bar 放在LayoutRoot Grid中-->
    <Canvas HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="10,0,0,20">
    <ESRI:ScaleBar x:Name="scalebar" MapUnit="DecimalDegrees" DisplayUnit="Kilometers" Background="Red" FillColor1="Black" FillColor2="White" FontSize="14" TextColor="Black"/>
    </Canvas>

     

    在页面初始函数中加入

    scalebar.Map = Map1;


    6.进度条

    前台代码6
    <!--progressbar 放在LayoutRoot中-->
    <Grid HorizontalAlignment="Center" x:Name="progressGrid" VerticalAlignment="Center" Width="200" Height="20" Margin="5,5,5,5">
    <ProgressBar x:Name="MyProgressBar" Minimum="0" Maximum="100" />
    <TextBlock x:Name="ProgressValueTextBlock" Text="100%" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
    ESRI:Map标签中添加一个Progress事件

     <ESRI:Map x:Name="Map1" MouseMove="Map1_MouseMove" Progress="Map1_Progress" >

    后台代码6
    private void Map1_Progress(object sender, ESRI.ArcGIS.Client.ProgressEventArgs e)
    {
    if (e.Progress < 100)
    {
    progressGrid.Visibility
    = Visibility.Visible;
    MyProgressBar.Value
    = e.Progress;
    ProgressValueTextBlock.Text
    = String.Format("正在处理 {0}%", e.Progress);
    }
    else
    {
    progressGrid.Visibility
    = Visibility.Collapsed;
    }
    }

    按照上面的步骤,就可以实现地图的一些基本操作,效果如开始的图片所示,在添加前台代码时注意添加的位置。我现在也是刚刚开始学习,欢迎大家提出问题,交流学习心得

    事例源码下载

    参考资料:http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.ScaleBar~TextColor.html

  • 相关阅读:
    Android_1_渐变背景色
    js 数组常用方法说明
    js模拟键盘按键事件
    SqlServer中截取字符串
    SqlServer将日期格式DateTime转换成varchar类型
    如何经营好(开好)一家淘宝店铺
    如何才能学好javascript
    前端常用的正则表达式
    淘宝中的一些基本CSS代码
    CSS样式中伪类和伪类元素的区别(css中一个冒号和两个冒号的区别)
  • 原文地址:https://www.cnblogs.com/junyuz/p/1934742.html
Copyright © 2011-2022 走看看