您的位置:首页 > 移动开发 > Objective-C

Silverlight+WCF+ArcObjects获取地图服务图层列表的实现

2012-12-15 11:32 323 查看
很久没有写博客了,最近一直忙考试,只是被悲催的数学物理方程真的把我给伤着了.....
忙完了考试,又开始了导师的项目,然而发现项目的很多东西,用原始的ArcGIS Api for Silverlight根本无法实现。于是开始接触强大的ArcObject。虽然之前接触过一些ArcGIS Engine,但还是觉得学的云里雾里的,现在都忘得差不多了,于是又一次的被AO给伤了。
本文算是自己初学AO的一点总结吧,在此和大家分享,不对之处,恳请指教。
一、Silverlight调用AO需要什么?
安装ArcOjects for .net Framework
需要借助WCF或者WebService
在Web项目中添加ArcGIS引用
关于AO的基本知识,本人初学,在此就不卖弄了。可以查看官方的帮助文档,前提是你需要一定的英语知识。
ArcObject官方在线文档: http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html 关于WCF和WebService,本人觉得用法差不多,但是WCF要更强大一些,所以建议使用WCF。至于什么是WCF或者WebService可以参考微软的官方文档:
WCF官方文档及示例: http://msdn.microsoft.com/en-us/library/dd456779.aspx 二、实现过程
我们这实现的功能很简单,就是获得某一地图服务(MapServer)下的所有图层。例如本文的发布的地图服务如下:



那么我们可以知道这里又是个图层(Layers):
Route (0)
RiverCenterLine
RiverDataSet_ND
Riverpolygon
下面我们就通过调用AO的方式获取这些图层。
1.新建Silverlight项目



选中Enable WCF RIA Service



2.在Web项目中添加ArcGIS相关的引用,如下图所示:



3.在Web项目中添加Silverlight-enabled WCF Service



选择Silverlight-enabled WCF Service,并设置服务名称,点击Add



此时Web部分的基本工作已经完成,接下来看看WCF服务器端如何实现。
4.WCF端实现的代码
首先我们需要连接到GIS服务,例如之前说的MapService,然后才能获取该服务的所有图层,连接到GIS服务的大致过程如下图所示:



关于连接GIS服务器的详细说明,可参考ESRI中国社区diligentpig的这篇文章:
http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=42676
以及官网的指导说明:
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Connecting_to_a_GIS_server/000100000200000000/
(1):WCF服务器端的连接代码:
首先添加如下引用:
using ESRI.ArcGIS.Carto;  using ESRI.ArcGIS.esriSystem;  using ESRI.ArcGIS.Server;  using ESRI.ArcGIS.Geodatabase;  using ESRI.ArcGIS.Geometry;  using System.Text;  using ESRI.ArcGIS.Location;

并定义如下变量:
//用来存储GIS服务所有图层的名称          public string[] LayerName = null;          //获得主机的SOM对象          public ESRI.ArcGIS.Server.IServerObjectManager pSOM = null;          //获取GIS服务的Context          public ESRI.ArcGIS.Server.IServerContext pServerContext = null;          //服务器连接          ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconnection = null;          //身份识别          ESRI.ArcGIS.ADF.Identity identity = null;          //GIS服务          ESRI.ArcGIS.Carto.IMapServer2 pMapServer=null;          //GIS服务的对象          ESRI.ArcGIS.Carto.IMapServerObjects2 pMapServerObject = null;          //GIS服务对象对应的地图,包含服务的所有图层          ESRI.ArcGIS.Carto.IMap pMap = null;

然后再WCF的构造函数中实例化:
//设置用户名,密码及域名               identity = new ESRI.ArcGIS.ADF.Identity("ArcGISWebServices", "quzijing", "qzj");              //设置服务地址              agsconnection = new                  ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("localhost", identity);              agsconnection.Connect();              pSOM = agsconnection.ServerObjectManager;              //指定相应GIS服务的地址,以及GIS服务的类型             pServerContext = pSOM.CreateServerContext("NetworkAnalystServiceFolder/RiverMap", "MapServer");              //创建GIS服务对象及Map              pMapServer = pServerContext.ServerObject as ESRI.ArcGIS.Carto.IMapServer2;              pMapServerObject = pMapServer as ESRI.ArcGIS.Carto.IMapServerObjects2;              pMap = pMapServerObject.get_Map(pMapServer.DefaultMapName);

这里需要说明的是:
a.identify的设置。和我们的ArcGIS Server Manager的UserName(用户名),Domain(域名),Password(密码)一致。



b.设置ArcGIS Server服务器地址:一般我们使用localhost即可,也可使用ip地址,当部署应用程序的时候建议使用IP地址。
c.指定GIS服务地址及服务类型:
GIS服务地址是相对于我们ArcGIS Server服务器根目录来说的,假设我们已有的GIS服务如下图所示:



那么如果我们想连接ChinaMap对应的MapServer时,使用的地址则直接是:ChinaMap,相应的代码为:
pServerContext = pSOM.CreateServerContext("ChinaMap", "MapServer");
而如果是要获取RiverMap对应的MapServer时,那么需要指定其相对于GIS服务的路径,即:NetworkAnalystServiceFolder/RiverMap,示例代码则为:
pServerContext = pSOM.CreateServerContext("NetworkAnalystServiceFolder/RiverMap", "MapServer");
同时还需要注意的问题是第二个参数中的GIS服务类型必须一致。
(2).获取图层名称。
上面我们已经获得了指定服务的Map,通过该Map我们即可获得Map中包含的所有图层,示例代码如下:
if (pMap.LayerCount > 0)              {                  LayerName = new string[pMap.LayerCount];                  for (int i = 0; i < pMap.LayerCount; i++)                  {                      ILayer layer = pMap.Layer[i];                      LayerName[i] = string.Format("Map Layer {0}:{1}", i, layer.Name);                  }              }
此外,我们个还可以获得指定的图层以及其中的要素,示例代码:
IFeatureClass pFC = (pMap.get_Layer(1) as ESRI.ArcGIS.Carto.IFeatureLayer).FeatureClass;              IFeatureCursor pPolyLineCursor = pFC.Search(null, false);              IFeature pPolyFeature = pPolyLineCursor.NextFeature();
(3).定义WCF实现服务的契约
该契约方法返回制定GIS服务中所有的图层名称,即返回上面的LayerName字符数组,示例代码如下:
[OperationContract]          public string []GetLayerString()          {              if(LayerName==null)              {                  LayerName = new string[1];                  LayerName[0] = "错误:没有获得图层";              }              return LayerName;          }
以上过程我们便完成了服务器端的工作,接下来我们看看客户端的实现。
5.客户端的实现
首先添加WCF服务引用





此时我们的项目文件结构如下所示:



接下来实现客户端的功能,客户端的实现很简单,我们这里就只是获得制定GIS服务所有的图层名称,我们定义一个Button和一个ListBox
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="83,23,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />          <ListBox Margin="12,61,172,0" Name="listBox1" VerticalAlignment="Top" HorizontalAlignment="Left" />
后台代码:
AOServiceReference.ArcGIS_AOServiceClient client = new ArcGIS_AOServiceClient();          public MainPage()          {              InitializeComponent();              client.GetLayerStringCompleted += new EventHandler<GetLayerStringCompletedEventArgs>(client_GetLayerStringCompleted);          }            void client_GetLayerStringCompleted(object sender, GetLayerStringCompletedEventArgs e)          {              //将WCF结果绑定到ListBox              listBox1.ItemsSource = e.Result;          }            private void button1_Click(object sender, RoutedEventArgs e)          {              client.GetLayerStringAsync();          }
最后的效果:


点击Button,获得图层列表


(版权所有,转载请标明出处)
  

本文出自 “季默” 博客,请务必保留此出处http://potential.blog.51cto.com/6176930/1402086
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: