Server操作Mxd文件详细讲解

Server操作Mxd文件详细讲解

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

下面函数实现添加一个图层到mxd文件,并设置样式。为更好的表达,函数使用返回操作结果的字符串。
/// <summary>
        /// 添加图层到Mxd文件
        /// </summary>
        /// <param name="serverContext">IServerContext</param>
        /// <param name="nfc">新图层对应的要素集</param>
        /// <param name="groupIndex">复合图层的序号</param>
        /// <param name="mxdPath">mxd所在的路径</param>
        /// <param name="picPath">用于对图层渲染的图片</param>
        /// <returns></returns>
        public string addLayerInMxd(IServerContext serverContext, IFeatureClass nfc, int groupIndex, string mxdPath,string picPath)
        {
            IMapServer pMapServer = serverContext.ServerObject as IMapServer;
            IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
            IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
            bool hasLayer = hasTheLayer(pMap, nfc.AliasName);
            if (hasLayer) return "已存在该命名图层,操作未能完成";  //如果图层已经存在了,那就不添加
            if (groupIndex >= pMap.LayerCount) return "组合图层序号越界,操作未能完成";
            IMapLayers mapLayer = pMap as IMapLayers;
            IGroupLayer gLayer = pMap.get_Layer(groupIndex) as IGroupLayer;
            IFeatureLayer fl = serverContext.CreateObject("esriCarto.FeatureLayer") as IFeatureLayer;
            fl.FeatureClass = nfc;
            fl.Name = nfc.AliasName;
            //设置样式
            ISimpleRenderer pRen = serverContext.CreateObject("esriCarto.SimpleRenderer") as ISimpleRenderer;
            IGeoFeatureLayer pGeoLayer = fl as IGeoFeatureLayer;
            IPictureMarkerSymbol picMark = serverContext.CreateObject("esriDisplay.PictureMarkerSymbol") as IPictureMarkerSymbol;
            picMark.Size = 20;
            picMark.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, picPath);
            pRen.Symbol = (ISymbol)picMark;
            pGeoLayer.Renderer = (IFeatureRenderer)pRen;
            mapLayer.InsertLayerInGroup(gLayer, pGeoLayer as ILayer, false, 3);

            //获取pMapDocument对象
            IMxdContents pMxdC;
            pMxdC = pMap as IMxdContents;
            IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;
            pMapDocument.Open(mxdPath, "");
            pMapDocument.ReplaceContents(pMxdC);
            if (pMapDocument == null) return "文档为空不能完成操作";
            //检查地图文档是否是只读
            if (pMapDocument.get_IsReadOnly(mxdPath) == true)
            {
                return "地图文档只读,未能完成操作";
            }
            //根据相对的路径保存地图文档
            pMapDocument.Save(pMapDocument.UsesRelativePaths, false);
            return "操作成功";
        }

/// <summary>
        /// 是否存在layerName为别名的图层
        /// </summary>
        /// <param name="pMap"></param>
        /// <param name="layerName"></param>
        /// <returns></returns>
        public bool hasTheLayer(IMap pMap, string layerName)
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                if (pLayer.Name == layerName)
                    return true;
                if (pLayer is ICompositeLayer)
                {
                    ICompositeLayer comLayer = pLayer as ICompositeLayer;
                    for (int j = 0; j < comLayer.Count; j++)
                    {
                        ILayer cLayer = comLayer.get_Layer(j);
                        if (cLayer.Name == layerName)
                            return true;
                    }
                }
            }
            return false;
        }


下面是根据图层名删除图层的操作
public string removeLayerFromMxd(IServerContext serverContext, layerName,string mxdPath)
        {
            IMapServer pMapServer = serverContext.ServerObject as IMapServer;
            IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
            IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
            IMapLayers pMapLayers = pMap as IMapLayers;
            
            ILayer removeLayer = getLayerByName(serverContext, layerName);
            if (removeLayer == null)
                return "操作失败,找不到要删除的图层";
            pMapLayers.DeleteLayer(removeLayer);
            //获取pMapDocument对象
            IMxdContents pMxdC = pMap as IMxdContents; ;
            IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;
            pMapDocument.Open(mxdPath, "");
            pMapDocument.ReplaceContents(pMxdC);
            if (pMapDocument == null) return "操作失败,地图文档为空";
            //检查地图文档是否是只读
            if (pMapDocument.get_IsReadOnly(mxdPath) == true)
            {
                return "操作失败,地图文档只读";
            }
            //根据相对的路径保存地图文档
            pMapDocument.Save(pMapDocument.UsesRelativePaths, false);
            return "操作成功";
        }

/// <summary>
        /// 是否存在layerName为别名的图层
        /// </summary>
        /// <param name="pMap"></param>
        /// <param name="layerName"></param>
        /// <returns></returns>
        public bool hasTheLayer(IMap pMap, string layerName)
        {
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                if (pLayer.Name == layerName)
                    return true;
                if (pLayer is ICompositeLayer)
                {
                    ICompositeLayer comLayer = pLayer as ICompositeLayer;
                    for (int j = 0; j < comLayer.Count; j++)
                    {
                        ILayer cLayer = comLayer.get_Layer(j);
                        if (cLayer.Name == layerName)
                            return true;
                    }
                }
            }
            return false;
        }


从上面的函数可看出,对添加删除图层这些操作,步骤大概就是 获取图层对要素集,设置图层样式,打开当前地图,插入图层,保存Mxd,
所有的这些都是AO的操作,对于习惯使用AE的人来说,这些都很熟悉,唯一不同的是,Server不能用new去创建对象,细心人会发现在创建
地图文档的时候,使用的是CreateObject的方式,如下面语句
IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;



当然,通过代码对服务器文件进行读写,还必须要注意网络的安全设置。
首先要确保有足够的权限对Mxd进行修改。
懒羊羊要指出,所谓的权限,第一是确保你的Server具有足够的授权。第二,服务器文件必须有足够的写入权限。
对于第二点,主要是考虑磁盘格式。网络开发人员都知道,NTFS格式下面,要访问文件,必须设置安全属性。
设置方法如下。
1。在服务器Mxd文件右键属性--点击"安全"标签
2.查找soc用户
3.给soc用户写入的权限。
懒羊羊这里只是举个例子,看官们只管使用自己的soc用户就行了。

1.JPG
下载 (35.63 KB)
2008-10-22 20:29


2.JPG
下载 (34.97 KB)
2008-10-22 20:29


3.JPG
下载 (36.99 KB)
2008-10-22 20:29



如果是fat格式就不用上述设置,毕竟NTFS格式安全系数比较高。至于Linux,懒羊羊没有做过,尝试过的朋友可以发表一下心得体会




还有一点必须主要的,Mxd更改以后,地图服务是没有发生变化的,所发布的地图一直驻留在内存中。因此,这时候需要更新一下地图服务。
方法有很多,最傻瓜最直接的方法就是跑到机房去重启mxd所对应的service。但是,懒羊羊比较懒,所以,还是希望通过代码去控制,update
一下。下面是更新地图服务的函数
private void updateService(string serviceName,string serverName)
    {
        ServerConnection pServerConnection = new ESRI.ArcGIS.Server.WebControls.ServerConnection(serverName);//地图服务机器名
        pServerConnection.Connect();
        IServerObjectAdmin pServerSOA = pServerConnection.ServerObjectAdmin;
        IServerObjectConfiguration pConfig = pServerSOA.GetConfiguration(serviceName, "MapServer");
        pServerSOA.UpdateConfiguration(pConfig);
    }

细心的朋友应该注意到了,这里面主要是使用了IServerObjectAdmin 接口,IServerObjectAdmin 接口功能十分强大,建议去查一下帮助,
对其加深了解。
4.JPG
下载 (35.46 KB)
2008-10-22 20:42



5.JPG

下载 (155.91 KB)
2008-10-22 20:42



描述
RemarksAny application that runs as a user account in the agsadmin user group on the ArcGIS Server can use the IGISServerConnection interface to connect to the ArcGIS Server and to get a reference to the ServerObjectAdmin. If the user account is not part of the agsadmin user group the ServerObjectAdmin property on IServerConnection will return an error. Applications that are running as accounts that can connect to the server but are not part of the agsadmin user group can use the ServerObjectManager property on IGISServerConnection to get a reference on the ServerObjectManager.
The IServerObjectAdmin interface has the necessary methods for an application to adminstrate both the set of server object configurations and types associated with the server, and to administer aspects of the server itself. The following administration functionality of the ArcGIS Server is exposed by methods and properties on IServerObjectAdmin :
Adminster server object configurations:

  • Add and delete server object configurations
  • Update a server object configuration's properties
  • Start, stop and pause server object configurations
  • Report the status of a server object configuration
  • Get all server object configurations and their properties
  • Get all server object types and their properties

Administer aspects of the server itself:

  • Add and remove server container machines
  • Get all server container machines
  • Add and remove server directories
  • Get all server directories
  • Configure the server's logging properties


实际上,上述的操大多数都是常规的操作,AE程序员都能轻松搞定。但细微的地方还是要注意的,例如Server环境下创建新对象,文件的权限设置等等
对server的一些特性也必须了解。例如mxd更新以后必须重启服务,确保当前服务与地图文档一致,不然就可能导致灾难性的出错。

前面漏掉的一个函数现在补上
/// <summary>
    /// 通过图层名称返回图层
    /// </summary>
    /// <param name="pSOC">地图控件</param>
    /// <param name="LayerName">图层名称</param>
    /// <returns></returns>
    public static ILayer getLayerByName(IServerContext pSOC, string LayerName)
    {
        IMapServer pMapServer = pSOC.ServerObject as IMapServer;
        IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
        IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
        //获取所有的图层
        for (int i = 0; i < pMap.LayerCount; i++)
        {
            ILayer lyr = pMap.get_Layer(i);
            if (lyr.Name == LayerName)
            {
                return lyr;
            }
            else if (lyr is ICompositeLayer)
            {
                //图层为复合图层,查找其子图层
                ICompositeLayer comLayer = lyr as ICompositeLayer;
                for (int j = 0; j < comLayer.Count; j++)
                {
                    ILayer cLayer = comLayer.get_Layer(j);
                    if (cLayer.Name == layerName)
                        return cLayer;
                }
            }
        }
        return null;
    }








转载于:https://www.cnblogs.com/liuyang-1037/archive/2009/08/11/1543481.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识图谱入门知识(五)【转】秒懂词向量Word2Vec的本质

博文&#xff1a; 秒懂词向量Word2Vec的本质 什么是Word2Vec&#xff1f; 词性标注&#xff1a;是动词还是名词&#xff0c;样本&#xff08;x&#xff0c;y&#xff09;中&#xff0c;x是词语&#xff0c;y是它们的词性 f&#xff08;x&#xff09;->y 中的f&#xff08;…

af_netlink_2、netlink简介

Netlink 是一种特殊的 socket&#xff0c;它是 Linux 所特有的&#xff0c;类似于 BSD 中的AF_ROUTE 但又远比它的功能强大&#xff0c;目前在最新的 Linux 内核(2.6.14)中使用netlink 进行应用与内核通信的应用很多&#xff0c;包括&#xff1a;路由 daemon(NETLINK_ROUTE)&am…

LeetCode 819. 最常见的单词

1. 题目 给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。 返回出现次数最多&#xff0c;同时不在禁用列表中的单词。 题目保证至少有一个词不在禁用列表中&#xff0c;而且答案唯一。 禁用列表中的单词用小写字母表示&#xff0c;不含标点符号。段落中的单词不区分…

Java代码优化方案 J2ME内存优化

从几本书上&#xff0c;N个网站上整理的一些JAVA代码优化方案&#xff0c;最近的项目只有1M内存可用&#xff0c;必须很抠门了~J2ME项目更要注意的 避免内存溢出 l 不用的对象释放(置空) 如 &#xff1a; a不为空时 anew object()//这句代码执行时将有两个对象存在于内存中 较…

was 程序jvm_【保家护行航】WAS知识学习分享

文/王文平保家护行航&#xff1a;航是护航&#xff0c;是保障人真抓实干&#xff0c;持之以恒&#xff0c;切实做好运维保障本职工作&#xff0c;守护农行生产安全的务本崇实&#xff1b;航是领航&#xff0c;是保障人敬业敏学&#xff0c;精益求精&#xff0c;努力提高运维管理…

LeetCode 824. 山羊拉丁文

1. 题目 给定一个由空格分割单词的句子 S。每个单词只包含大写或小写字母。 我们要将句子转换为 “Goat Latin”&#xff08;一种类似于 猪拉丁文 - Pig Latin 的虚构语言&#xff09;。 山羊拉丁文的规则如下&#xff1a; 如果单词以元音开头&#xff08;a, e, i, o, u&am…

jQuery学习笔记:事件

一、页面载入1、ready(fn)当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。这是事件模块中最重要的一个函数&#xff0c;因为它可以极大地提高web应用程序的响应速度。 简单地说&#xff0c;这个方法纯粹是对向window.load事件注册事件的替代方法。通过使用这个方法&#…

torch.nn.Module()

torch.nn.Module() 如果自己想研究&#xff0c;官方文档 它是所有的神经网络的根父类&#xff01; 你的神经网络必然要继承&#xff01; 模块也可以包含其他模块&#xff0c;允许将它们嵌套在树结构中。所以呢&#xff0c;你可以将子模块指定为常规属性。常规定义子模块的方法…

dlib 怎么安装vs2017_win10中的dlib库安装过程

之前试过很多方法结果都失败&#xff0c;最后终于发现一个成功的方法&#xff0c;先记一下以防忘记。参考&#xff1a;记一次Win10环境python3.7安装dlib模块趟过的坑由于我是通过Anaconda安装的Python&#xff0c;所以环境与这位博主的有所不同&#xff0c;所以具体情况需要根…

LeetCode 779. 第K个语法符号(找规律)

1. 题目 在第一行我们写上一个 0。 接下来的每一行&#xff0c;将前一行中的0替换为01&#xff0c;1替换为10。 给定行数 N 和序数 K&#xff0c;返回第 N 行中第 K个字符。&#xff08;K从1开始&#xff09; 例子: 输入: N 1, K 1 输出: 0输入: N 2, K 1 输出: 0输入: …

ADO.NET、ODP.NET、Linq to SQL、ADO.NET Entity 、NHibernate在Oracle下的性能比较

下面我对Oracle数据库在.NET平台下的主要几种数据访问方式进行测试。 下面是测试表&#xff1a; CREATE TABLE CUSTOMERS ( "CUSTOMER_ID" NUMBER NOT NULL , "FIRST_NAME" VARCHAR2(255 CHAR) NOT NULL , "LAST_NAME" VARCHAR2(255 CHAR) …

LeetCode 第 186 场周赛(1060/3107,前34.1%)

文章目录1. 比赛结果2. 题目1. LeetCode 5392. 分割字符串的最大得分 easy2. LeetCode 5393. 可获得的最大点数 medium3. LeetCode 5394. 对角线遍历 II medium4. LeetCode 5180. 带限制的子序列和 hard1. 比赛结果 做出来了 1、2 题&#xff0c;第3题模拟法&#xff0c;超时&…

torch.nn.embedding()

作者&#xff1a;top_小酱油 链接&#xff1a;https://www.jianshu.com/p/63e7acc5e890 来源&#xff1a;简书 内容&#xff1a;上述是以RNN为基础解析的 torch.nn.Embedding(num_embeddings, embedding_dim, padding_idxNone, max_normNone, norm_type2.0, scale_grad_by_fre…

oracle杀死进程时权限不足_在oracle中创建函数时权限不足

我对oracle有一点了解。我试图创建一个如下所示的函数。在oracle中创建函数时权限不足CREATE OR REPLACE FUNCTION "BOOK"."CONVERT_TO_WORD" (totpayable IN NUMBER) RETURN VARCHARAStotlength NUMBER;num VARCHAR2(14);word VARCHAR2(70);word1 VARCHAR…

哇塞,打开一个页面访问了这么多次数据库??

用SQL Server 事件探查器看了一下&#xff0c;哇塞&#xff0c;每打开一个页面都select了n多次数据库&#xff0c;而且很多都是类似的代码&#xff1f;为啥&#xff1f; (1)、二级嵌套绑定数据源 (2)、二级联动 (3)、……多着呢&#xff01; 解决方法&#xff1a; 对于数据不大…

torch.nn

torch.nn 与 torch.nn.functional 说起torch.nn&#xff0c;不得不说torch.nn.functional! 这两个库很类似&#xff0c;都涵盖了神经网络的各层操作&#xff0c;只是用法有点不同&#xff0c;比如在损失函数Loss中实现交叉熵! 但是两个库都可以实现神经网络的各层运算。其他包…

ORACLE使用JOB定时备份数据库

Oracle的备份一般都是在操作系统上完成&#xff0c;因此定时备份Oracle的功能一般都是由操作系统功能完成&#xff0c;比如crontab。但是Oracle的PIPE接口使得在Oracle数据库中通过JOB来备份Oracle变得可能。 这篇文章给出一个简单的例子&#xff0c;说明如何在JOB中定期备份数…

mysql 装载dump文件_mysql命令、mysqldump命令找不到解决

1、解决bash: mysql: command not found 的方法[rootDB-02 ~]# mysql -u root-bash: mysql: command not found原因:这是由于系统默认会查找/usr/bin下的命令&#xff0c;如果这个命令不在这个目录下&#xff0c;当然会找不到命令&#xff0c;我们需要做的就是映射一个链接到/u…

LeetCode 796. 旋转字符串

1. 题目 给定两个字符串, A 和 B。 A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A ‘abcde’&#xff0c;在移动一次之后结果就是’bcdea’ 。如果在若干次旋转操作之后&#xff0c;A 能变成B&#xff0c;那么返回True。 示例 1: 输入: A abcde, B cdeab …

【DKN】(一)KCN详解

_ init _&#xff08;&#xff09;函数 参数&#xff1a; self, config, pretrained_word_embedding, pretrained_entity_embedding, pretrained_context_embedding config&#xff1a; 设置的固定的参数&#xff01; pretrained_word_embedding&#xff1a; 根据下面的使用是…