• ArcGIS Server操作Mxd文件详细讲解


    ArcGIS Server操作Mxd文件详细讲解

           Server发布地图都是基于Mxd去发布的,这点与IMS使用axl文件差不多。一般来说,发布后mxd尽可能不要修改,或者在通过使用arcMap进行编辑后在重新发布。
           修改mxd会导致地图服务发生变化,因此,相对来说是一种危险的操作。但有时客户需要对Mxd进行修改,自定义的添加修改图层,并重新发布服务。
           当然,这些苛刻的需求server同样可以应付,但懒羊羊还是不建议这样做。方法总是有的,越危险的事也就越有趣。懒羊羊还是跟大家分享一下这方面的心得吧。
    下面函数实现添加一个图层到mxd文件,并设置样式。为更好的表达,函数使用返回操作结果的字符串。
     

    C#代码
    1. /// <summary>   
    2.         /// 添加图层到Mxd文件   
    3.         /// </summary>   
    4.         /// <param name="serverContext">IServerContext</param>   
    5.         /// <param name="nfc">新图层对应的要素集</param>   
    6.         /// <param name="groupIndex">复合图层的序号</param>   
    7.         /// <param name="mxdPath">mxd所在的路径</param>   
    8.         /// <param name="picPath">用于对图层渲染的图片</param>   
    9.         /// <returns></returns>   
    10.         public string addLayerInMxd(IServerContext serverContext, IFeatureClass nfc, int groupIndex, string mxdPath,string picPath)   
    11.         {   
    12.             IMapServer pMapServer = serverContext.ServerObject as IMapServer;   
    13.             IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;   
    14.             IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);   
    15.             bool hasLayer = hasTheLayer(pMap, nfc.AliasName);   
    16.             if (hasLayer) return "已存在该命名图层,操作未能完成";  //如果图层已经存在了,那就不添加   
    17.             if (groupIndex >= pMap.LayerCount) return "组合图层序号越界,操作未能完成";   
    18.             IMapLayers mapLayer = pMap as IMapLayers;   
    19.             IGroupLayer gLayer = pMap.get_Layer(groupIndex) as IGroupLayer;   
    20.             IFeatureLayer fl = serverContext.CreateObject("esriCarto.FeatureLayer"as IFeatureLayer;   
    21.             fl.FeatureClass = nfc;   
    22.             fl.Name = nfc.AliasName;   
    23.             //设置样式   
    24.             ISimpleRenderer pRen = serverContext.CreateObject("esriCarto.SimpleRenderer"as ISimpleRenderer;   
    25.             IGeoFeatureLayer pGeoLayer = fl as IGeoFeatureLayer;   
    26.             IPictureMarkerSymbol picMark = serverContext.CreateObject("esriDisplay.PictureMarkerSymbol"as IPictureMarkerSymbol;   
    27.             picMark.Size = 20;   
    28.             picMark.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, picPath);   
    29.             pRen.Symbol = (ISymbol)picMark;   
    30.             pGeoLayer.Renderer = (IFeatureRenderer)pRen;   
    31.             mapLayer.InsertLayerInGroup(gLayer, pGeoLayer as ILayer, false, 3);   
    32.   
    33.             //获取pMapDocument对象   
    34.             IMxdContents pMxdC;   
    35.             pMxdC = pMap as IMxdContents;   
    36.             IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument"as IMapDocument;   
    37.             pMapDocument.Open(mxdPath, "");   
    38.             pMapDocument.ReplaceContents(pMxdC);   
    39.             if (pMapDocument == nullreturn "文档为空不能完成操作";   
    40.             //检查地图文档是否是只读   
    41.             if (pMapDocument.get_IsReadOnly(mxdPath) == true)   
    42.             {   
    43.                 return "地图文档只读,未能完成操作";   
    44.             }   
    45.             //根据相对的路径保存地图文档   
    46.             pMapDocument.Save(pMapDocument.UsesRelativePaths, false);   
    47.             return "操作成功";   
    48.         }   
    49.   
    50. /// <summary>   
    51.         /// 是否存在layerName为别名的图层   
    52.         /// </summary>   
    53.         /// <param name="pMap"></param>   
    54.         /// <param name="layerName"></param>   
    55.         /// <returns></returns>   
    56.         public bool hasTheLayer(IMap pMap, string layerName)   
    57.         {   
    58.             for (int i = 0; i < pMap.LayerCount; i++)   
    59.             {   
    60.                 ILayer pLayer = pMap.get_Layer(i);   
    61.                 if (pLayer.Name == layerName)   
    62.                     return true;   
    63.                 if (pLayer is ICompositeLayer)   
    64.                 {   
    65.                     ICompositeLayer comLayer = pLayer as ICompositeLayer;   
    66.                     for (int j = 0; j < comLayer.Count; j++)   
    67.                     {   
    68.                         ILayer cLayer = comLayer.get_Layer(j);   
    69.                         if (cLayer.Name == layerName)   
    70.                             return true;   
    71.                     }   
    72.                 }   
    73.             }   
    74.             return false;   
    75.         }  

    下面是根据图层名删除图层的操作

    C#代码
    1. public string removeLayerFromMxd(IServerContext serverContext, layerName,string mxdPath)   
    2.         {   
    3.             IMapServer pMapServer = serverContext.ServerObject as IMapServer;   
    4.             IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;   
    5.             IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);   
    6.             IMapLayers pMapLayers = pMap as IMapLayers;   
    7.                
    8.             ILayer removeLayer = getLayerByName(serverContext, layerName);   
    9.             if (removeLayer == null)   
    10.                 return "操作失败,找不到要删除的图层";   
    11.             pMapLayers.DeleteLayer(removeLayer);   
    12.             //获取pMapDocument对象   
    13.             IMxdContents pMxdC = pMap as IMxdContents; ;   
    14.             IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument"as IMapDocument;   
    15.             pMapDocument.Open(mxdPath, "");   
    16.             pMapDocument.ReplaceContents(pMxdC);   
    17.             if (pMapDocument == nullreturn "操作失败,地图文档为空";   
    18.             //检查地图文档是否是只读   
    19.             if (pMapDocument.get_IsReadOnly(mxdPath) == true)   
    20.             {   
    21.                 return "操作失败,地图文档只读";   
    22.             }   
    23.             //根据相对的路径保存地图文档   
    24.             pMapDocument.Save(pMapDocument.UsesRelativePaths, false);   
    25.             return "操作成功";   
    26.         }   
    27.   
    28. /// <summary>   
    29.         /// 是否存在layerName为别名的图层   
    30.         /// </summary>   
    31.         /// <param name="pMap"></param>   
    32.         /// <param name="layerName"></param>   
    33.         /// <returns></returns>   
    34.         public bool hasTheLayer(IMap pMap, string layerName)   
    35.         {   
    36.             for (int i = 0; i < pMap.LayerCount; i++)   
    37.             {   
    38.                 ILayer pLayer = pMap.get_Layer(i);   
    39.                 if (pLayer.Name == layerName)   
    40.                     return true;   
    41.                 if (pLayer is ICompositeLayer)   
    42.                 {   
    43.                     ICompositeLayer comLayer = pLayer as ICompositeLayer;   
    44.                     for (int j = 0; j < comLayer.Count; j++)   
    45.                     {   
    46.                         ILayer cLayer = comLayer.get_Layer(j);   
    47.                         if (cLayer.Name == layerName)   
    48.                             return true;   
    49.                     }   
    50.                 }   
    51.             }   
    52.             return false;   
    53.         }   

          当然,通过代码对服务器文件进行读写,还必须要注意网络的安全设置。
          首先要确保有足够的权限对Mxd进行修改。
          所谓的权限,第一是确保你的Server具有足够的授权。第二,服务器文件必须有足够的写入权限。对于第二点,主要是考虑磁盘格式。网络开发人员都知道,NTFS格式下面,要访问文件,必须设置安全属性。
    设置方法如下:

    1、在服务器Mxd文件右键属性--点击"安全"标签
    2、查找soc用户
    3、给soc用户写入的权限。
    这里例子就省了,浏览者只管使用自己的soc用户就行了

            还有一点必须主要的,Mxd更改以后,地图服务是没有发生变化的,所发布的地图一直驻留在内存中。因此,这时候需要更新一下地图服务。  方法有很多,最傻瓜最直接的方法就是跑到机房去重启mxd所对应的service。但是,懒羊羊比较懒,所以,还是希望通过代码去控制,update一下。下面是更新地图服务的函数
     

    C#代码
    1. private void updateService(string serviceName,string serverName)   
    2.     {   
    3.         ServerConnection pServerConnection = new ESRI.ArcGIS.Server.WebControls.ServerConnection(serverName);//地图服务机器名   
    4.         pServerConnection.Connect();   
    5.         IServerObjectAdmin pServerSOA = pServerConnection.ServerObjectAdmin;   
    6.         IServerObjectConfiguration pConfig = pServerSOA.GetConfiguration(serviceName, "MapServer");   
    7.         pServerSOA.UpdateConfiguration(pConfig);   
    8.     }   

    细心的朋友应该注意到了,这里面主要是使用了IServerObjectAdmin 接口,IServerObjectAdmin 接口功能十分强大,建议去查一下帮助,对其加深了解。

    如果是fat格式就不用上述设置,毕竟NTFS格式安全系数比较高。至于Linux,懒羊羊没有做过,尝试过的朋友可以发表一下心得体会
    实际上,上述的操大多数都是常规的操作,AE程序员都能轻松搞定。但细微的地方还是要注意的,例如Server环境下创建新对象,文件的权限设置等等
    对server的一些特性也必须了解。例如mxd更新以后必须重启服务,确保当前服务与地图文档一致,不然就可能导致灾难性的出错。

    前面漏掉的一个函数现在补上
     

    C#代码
    1. /// <summary>   
    2.     /// 通过图层名称返回图层   
    3.     /// </summary>   
    4.     /// <param name="pSOC">地图控件</param>   
    5.     /// <param name="LayerName">图层名称</param>   
    6.     /// <returns></returns>   
    7.     public static ILayer getLayerByName(IServerContext pSOC, string LayerName)   
    8.     {   
    9.         IMapServer pMapServer = pSOC.ServerObject as IMapServer;   
    10.         IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;   
    11.         IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);   
    12.         //获取所有的图层   
    13.         for (int i = 0; i < pMap.LayerCount; i++)   
    14.         {   
    15.             ILayer lyr = pMap.get_Layer(i);   
    16.             if (lyr.Name == LayerName)   
    17.             {   
    18.                 return lyr;   
    19.             }   
    20.             else if (lyr is ICompositeLayer)   
    21.             {   
    22.                 //图层为复合图层,查找其子图层   
    23.                 ICompositeLayer comLayer = lyr as ICompositeLayer;   
    24.                 for (int j = 0; j < comLayer.Count; j++)   
    25.                 {   
    26.                     ILayer cLayer = comLayer.get_Layer(j);   
    27.                     if (cLayer.Name == layerName)   
    28.                         return cLayer;   
    29.                 }   
    30.             }   
    31.         }   
    32.         return null;   
    33.     }   

    原作者:懒洋洋

    原地址:http://bbs.esrichina-bj.cn/ESRI/thread-35857-1-2.html



  • 相关阅读:
    移动端1px问题
    js几种数组排序及sort的实现
    从零开始搭建vue移动端项目到上线
    Maven项目常见错误解决方法汇总
    重读《Java编程思想》
    ubuntu开发环境下eclipse的alt+/自动补全功能不能用
    Linux环境下解压rar文件
    Ubuntu 16.04下deb文件的安装
    优化Ubuntu 16.04系统的几件事
    Ubuntu16.04 安装 “宋体,微软雅黑,Consolas雅黑混合版编程字体” 等 Windows 7 下的字体
  • 原文地址:https://www.cnblogs.com/moonvan/p/2045438.html
Copyright © 2020-2023  润新知