zoukankan      html  css  js  c++  java
  • Silverlight+WCF+ArcObjects获取地图服务图层列表的实现

    很久没有写博客了,最近一直忙考试,只是被悲催的数学物理方程真的把我给伤着了.....

    忙完了考试,又开始了导师的项目,然而发现项目的很多东西,用原始的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):

    下面我们就通过调用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,获得图层列表

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

    
    
    
    
    
  • 相关阅读:
    hdu 1290 献给杭电五十周年校庆的礼物 (DP)
    hdu 3123 GCC (数学)
    hdu 1207 汉诺塔II (DP)
    hdu 1267 下沙的沙子有几粒? (DP)
    hdu 1249 三角形 (DP)
    hdu 2132 An easy problem (递推)
    hdu 2139 Calculate the formula (递推)
    hdu 1284 钱币兑换问题 (DP)
    hdu 4151 The Special Number (DP)
    hdu 1143 Tri Tiling (DP)
  • 原文地址:https://www.cnblogs.com/potential/p/2818582.html
Copyright © 2011-2022 走看看