当前位置: 首页 > 编程日记 > 正文

ArcGIS API for Silverlight 入门学习笔记(三):基础地图实例

2011011316462592.png

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

前期准备工作

ContractedBlock.gifExpandedBlockStart.gif前台代码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>


ContractedBlock.gif代码<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.地图范围


ContractedBlock.gifExpandedBlockStart.gif前台代码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等。

ContractedBlock.gifExpandedBlockStart.gif后台代码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.地图坐标

ContractedBlock.gifExpandedBlockStart.gif前台代码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">

ContractedBlock.gifExpandedBlockStart.gif后台代码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里的动画效果

ContractedBlock.gifExpandedBlockStart.gif前台代码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类型的变量,合理的设置可以带来良好的用户体验。

ContractedBlock.gifExpandedBlockStart.gif后台代码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.设置全屏

 

ContractedBlock.gifExpandedBlockStart.gif前台代码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.比例尺

ContractedBlock.gifExpandedBlockStart.gif前台代码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.进度条

ContractedBlock.gifExpandedBlockStart.gif前台代码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" >

ContractedBlock.gifExpandedBlockStart.gif后台代码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

转载于:https://www.cnblogs.com/junyuz/archive/2011/01/13/1934742.html

相关文章:

BZOJ 4009 接水果

Description 风见幽香非常喜欢玩一个叫做osu!的游戏&#xff0c;其中她最喜欢玩的模式就是接水果。 由于她已经DT FC了The big black, 她觉得这个游戏太简单了&#xff0c;于是发明了一个更加难的版本。首先有一个地图&#xff0c;是一棵由\(n\)个顶点、\(n-1\)条边组成的树。这…

GitBook本地的安装与查看

1.安装nodejs 2.cnpm install -g gitbook-cli 查看版本&#xff1a;gitbook -V 3.gitbook init 注意npm加了代理&#xff0c;查看npm代理配置&#xff0c;将其注释即可 执行完后&#xff0c;你会看到多了两个文件 —— README.md 和 SUMMARY.md&#xff0c;它们的作用如下&…

用C++的random_shuffle()函数打乱int数组顺序

程序背景&#xff1a; 开组会&#xff0c;汇报人已确定&#xff0c;出一个随机的汇报顺序。 #include<bits/stdc.h> using namespace std;const int NUM 12;//汇报人数 int main() {string names[] {"SpongeBob","Patrick","Squidward"…

ios 绘制不规则 图形

最近才知道有一个软件 paintcode 它可以根据画出的图形自动的生成对应的 OC 代码 不用UI切图 我们也可以用代码实现自己想要的图形效果 使用教程可以百度&#xff1a;paintcode教程 http://blog.csdn.net/lujunelong/article/details/18899925 下载地址&#xff1a;http://www…

[转]Windows与VC命名规则

转自&#xff1a;http://hi.baidu.com/11158512/blog/item/0fbd5535cbfb5d1c91ef3970.html 匈牙利命名法是一种编程时的命名规范。基本原则是&#xff1a;变量名&#xff1d;属性&#xff0b;类型&#xff0b;对象描述。其中每一对象的名称都要求有明确含义&#xff0c;可以取对…

恢复误删的进程在使用的文件【转】

转自&#xff1a;https://www.cnblogs.com/276815076/p/5473185.html 原理&#xff1a;在Linux系统的/proc 分区下保存着进程的目录和名字&#xff0c;包含fd(文件描述符)和其下的子目录&#xff08;进程打开文件的链接&#xff09;&#xff0c;那么如果删除了一个文件&#xf…

编解码器架构中的桥(bridge)指什么

https://opennmt.net/OpenNMT-py/examples/Summarization.html?highlightbridge​​​​​​对于bridge做出如下解释 bridge: This is an additional layer that uses the final hidden state of the encoder as input and computes an initial hidden state for the decoder.…

控件包含代码块,因此无法修改控件集合

文章转载至: http://www.olnote.com/itlife/note/100000003.aspx控件包含代码块(即<% ... %>)&#xff0c;因此无法修改控件集合。 说明: 执行当前 Web 请求期间&#xff0c;出现未处理的异常。请检查堆栈跟踪信息&#xff0c;以了解有关该错误以及代码中导致错误的出处…

驰骋工作流引擎JFlow与activiti的对比之4种包含多实例的模式

为什么80%的码农都做不了架构师&#xff1f;>>> 4种包含多实例的模式 无同步的多实例&#xff08;MIwithout&#xff09;在流程中&#xff0c;一个活动可以激活多个实例&#xff0c;每个实例相互独立&#xff0c;并不需要在后面进行同步。 例子&#xff1a;比如用户…

Embarcadero Dev C++ 中文输出乱码

解决方式&#xff1a;保证编译器和文件的编码方式一样。 1. 编译器的编码方式 Embarcadero Dev C 界面 2. cpp文件编码方式 Notepad界面

关于登录记住密码使用cookie的详解

下面是我看的一篇文章引用过来&#xff0c;很易懂 设置cookie每个cookie都是一个名/值对&#xff0c;可以把下面这样一个字符串赋值给document.cookie&#xff1a;document.cookie"userId828";如果要一次存储多个名/值对&#xff0c;可以使用分号加空格&#xff08;;…

Linux服务器---安装tftp-server

安装tftp-server1、安装tftp-server[rootlocalhost weijie]# yum install -y tftp-serverLoaded plugins: fastestmirror, refresh-packagekit, securityRunning TransactionInstalling : tftp-server-0.49-8.el6.i686 1/1 Verifying : tftp…

linux指令 2>1 到底是个啥

训练好深度学习模型之后对其进行测试&#xff0c;测试的脚本如上图。 我对第11行感到不解&#xff0c;经过检索Linux重定向和文件描述符相关知识后&#xff0c;明白了 2代表着标准错误 1代表者标准输出(默认是屏幕) >代表流向 那么第11行代码的含义也就是&#xff0c;将…

新生 语不惊人死不休 —— 《无限恐怖》读后有感

开篇声明&#xff0c;我博客中“小心情”这一系列&#xff0c;全都是日记啊随笔啊什么乱七八糟的。如果一不小心点进来了&#xff0c;不妨直接关掉。我自己曾经写过一段时间的日记&#xff0c;常常翻看&#xff0c;毫无疑问我的文笔是很差的&#xff0c;而且心情也是瞬息万变的…

中国大学MOOC-C程序设计(浙大翁恺)—— 时间换算

时间换算&#xff08;10分&#xff09;题目内容&#xff1a;UTC是世界协调时&#xff0c;BJT是北京时间&#xff0c;UTC时间相当于BJT减去8。现在&#xff0c;你的程序要读入一个整数&#xff0c;表示BJT的时和分。整数的个位和十位表示分&#xff0c;百位和千位表示小时。如果…

作为一个程序员,数学对你到底有多重要(转)

每个计算机系毕业的人&#xff0c;大都学过不少数学课&#xff0c;而且不少学校的计算机系的数学课&#xff0c;通常比一般的其他工科专业的数学要难一些&#xff0c;比如不上高等数学&#xff0c;而是学数学分析&#xff0c;不上线性代数而去上高等代数。但是&#xff0c;大部…

如何在vsc上选择远程miniconda特定的虚拟环境中的Python解释器(4步)

前提&#xff1a; 已经通过remote development插件连上了远程服务器 远程服务器上已经创建了安装了python的虚拟环境 步骤&#xff1a; 点击“查看” 点击“命令面板” 输入/选择 Python:Select Interpreter 然后就能选择远程miniconda中已经创建的虚拟环境了 我的minico…

Java数据类型简单认识

Java是一种强类型编程语言&#xff0c;因而在声明变量的时候必须声明数据类型&#xff0c;java语言有基本数据类型和引用数据类型这两大数据类型&#xff0c;基本数据类型有8种分别是4种整型、2种浮点类型、1种用于Unicode表示字符单元的字符类型和1种表示真值的布尔类型;引用数…

Intel 6系列芯片组设计缺陷 全球出货暂停

美国当地时间周一&#xff0c;Intel公司官方宣布&#xff0c;今年1月初刚刚伴随Sandy Bridge系列“第二代Core架构处理器”推出的6系列芯片组&#xff08;代号Cougar Point&#xff09;发现了设计方面的问题。虽然目前Intel已经对该设计在芯片级别进行了修正&#xff0c;但在新…

PrestaShop 网站漏洞修复如何修复

2019独角兽企业重金招聘Python工程师标准>>> PrestaShop网站的漏洞越来越多&#xff0c;该网站系统是很多外贸网站在使用的一个开源系统&#xff0c;从之前的1.0初始版本到现在的1.7版本&#xff0c;经历了多次的升级&#xff0c;系统使用的人也越来越多&#xff0c…

shell脚本中的case语句使用要点

1.双分号(;;) 用于case语句中一个分支的结束。 可类比C里面switch...case语句&#xff0c;在case语句之后&#xff0c;若所有语句都输完&#xff0c;后面跟着的"break;"。 2.星号加右小括号*) 可类比C里面switch...case语句中的"default:"。 3.结束符…

Netty - ByteBuf

2019独角兽企业重金招聘Python工程师标准>>> 1.ByteBuf类 - Netty的数据容器 ByteBuf维护了两个不同的索引&#xff1a; readerIndex&#xff1a;用于读取writerIndex&#xff1a;用于写入起始位置都从0开始&#xff1a; 名称以read或者write开头的方法会更新ByteBu…

不要做浮躁的嵌入式系统工程师

每天读一遍&#xff0c;思考一下&#xff1a;我是否浮躁&#xff1f; 1、不要看到别人的回复&#xff0c;第一句话就说&#xff1a;给个代码吧&#xff01;你应该想想为什么。当你自己想出来再参考别人的提示&#xff0c;就会知道自己和别人思路的差异。 2、初学者请不要看…

Codeforces Round #300 A. Cutting Banner 水题

A. Cutting Banner Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/538/problem/ADescription A large banner with word CODEFORCES was ordered for the 1000-th onsite round of Codeforcesω that takes place on the Miami beach. Unfo…

ImportError:cannot import name ‘display‘ File “XX“, line 5, in <module> from IPython import display

导入错误问题的一个解决思路是&#xff0c;推断这是模块间版本不兼容带来的问题&#xff0c;先把模块卸载掉&#xff0c;再用conda install安装上。也就是让conda去协调模块间兼容性。

[高级]android应用开发之intent的妙用二

相信做android应用开发的朋友对intent组件都已经是相当熟悉了&#xff0c;这里鄙人总结一下intent的妙用&#xff0c;希望对大家有帮助。 intent妙用之列出所有已安装的应用程序列表 装载&#xff1a;http://blog.csdn.net/android_tutor/article/details/5724634 这篇文章写的…

windows 自动化目录大纲(各企业架构不一样,按需选择)

有需要做自动化的联系979122932,一起交流学习转载于:https://blog.51cto.com/7763608/2338668

Java设计模式之虚拟代理模式

描述&#xff1a;虚拟代理模式(Virtual Proxy)是一种节省内存的技术&#xff0c;它建议创建那些占用大量内存或处理复杂的对象时&#xff0c;把创建这类对象推迟到使用它的时候。在特定的应用中&#xff0c;不同部分的功能由不同的对象组成&#xff0c;应用启动的时候&#xff…

(已解决)ImportError attempted relative import with no known parent package

想要调用同一目录下的另一个py文件中的类&#xff0c;以下或许是可行的解决方案。 需要做到两点 1. 将主调文件的名称改为__init__.py 2. from 被调文件的文件名称(删去末尾.py) import 类名 不要在被调文件的文件名称前面加点&#xff01; 我的目录结构 我的调用方式 fro…

小红点功能控件

写在前面 本意是想把做过的东西沉淀一下&#xff0c;防止重复造轮子。后来想想自己在实现这个的过程中还是走了一点弯路的。虽然网上找的轮子很多&#xff0c;其实大多都华而不实或者功能太多&#xff0c;工作中实现的东西最重要的不是功能炫&#xff0c;而是稳定&#xff0c;一…