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,获得图层列表

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

    
    
    
    
    
  • 相关阅读:
    加入页面切换动画, 避免冷启动
    Spark Shuffle模块——Suffle Read过程分析
    java使用线程请求訪问每次间隔10分钟连续5次,之后停止请求
    二叉排序树(BST)构造与应用
    L贪心基础
    leetcode笔记:Ugly Number II
    Android API Guides---Layouts
    红外目标图像中阈值切割方法的比較与研究
    IOS开发证书变成“此证书的签发者无效”解决方法
    Web前端开发规范收集
  • 原文地址:https://www.cnblogs.com/potential/p/2818582.html
Copyright © 2011-2022 走看看