[C#] [Server] [Engine] 运用 ArcGIS Engine 管理 ArcGIS Server、发布地图服务、加载地图服务

目录

1.Intro

2.Details

(1) 使用ArcGIS Engine管理服务

<1> 服务器操作

<2> 服务操作

(2) 发布地图服务

<1> Engine发布地图服务(有问题)

<2> GP工具发布地图服务

(3) 加载地图服务

<1> 遍历整个目录,找到匹配服务名称的地图服务进行加载。

<2> 直接通过地图服务提供的Rest链接加载。

3.Environment

4.Conclusion


1.Intro

这几个月一直在忙Coding,大概就是啥空间数据管理、质检、三调之类的,都没有时间整理技术路线和发布代码,最近要做的就是某空间数据管理系统,leader的意思是把整个县的影像图都放在本地目录下(50个G左右...)然后调用加载。如果配置不是顶配,本机加载那么大的影像肯定会卡的要死,而且放在本地目录下又占空间,不如用在线加载的方式,但是数据又涉及到涉密问题,不能连接外网,用的人只限于某政府部门,so只能组建局域网。

大概思路是这样,架设一台高性能的服务器作为存储站,然后搭建交换机组网,在服务器上部署ArcGIS Server,然后用Engine写一个ArcGIS Server管理器,在设置权限的情况下可以对ArcGIS Server中的服务进行管理,并且能够发布地图服务。


2.Details

从搭建ArcGIS Server,到用Engine管理服务、发布地图服务、加载地图服务,遇到不少问题和值得注意的细节,因为已经做了一周了而且没总结笔记(臭毛病),所以有些地方可能会想不起来,其实所有问题都可以通过百度或者ArcGIS知乎搜到并解决,至少我是这样。

(1) 使用ArcGIS Engine管理服务

搭了个基本框架,分别有服务器操作(连接、断开)、服务操作(启动、停止、重启、删除、刷新)、地图操作服务(发布服务)三个简单的功能模块,基本满足对ArcGIS Server简单功能的使用,但上传Sd文件并发布服务、修改地图服务属性、设置用户权限等功能还没有实现。

<1> 服务器操作

*连接服务器

注意:①服务器URL地址是 http://[你安装ArcGIS Server的ip地址]:6080/arcgis/admin

注意:②如果连接在本机安装的ArcGIS Server,则URL地址为 http://localhost:6080/arcgis/admin

注意:③如果连接局域网内服务器上的ArcGIS Server提示失败,或提示无法创建Server连接时,可能是服务器端防火墙对6080端口的限制,打开服务器端防火墙新建6080端口的出站入站规则如下:

*连接服务器代码:返回的SOA对象可以对服务进行管理但是不能发布(从ArcGIS 10.1开始,由于Server架构的调整,不能使用Engine直接发布服务了,所以会用到GP工具来发布,这个后面再讲)

        /// <summary>
        /// 连接 ArcGIS Server 服务器
        /// </summary>
        /// <param name="url">服务器URL地址</param>
        /// <param name="userName">用户名</param>
        /// <param name="passWord">密码</param>
        /// <param name="isConnect">是否连接成功</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回连接对象</returns>
        public static IServerObjectAdmin ConnectAGS(string url, string userName, string passWord, out bool isConnect, out string message)
        {
            try
            {
                IPropertySet pPropertySet = new PropertySetClass();
                pPropertySet.SetProperty("url", url);
                // 登录模式,分别为访客、登陆用户、发布者
                pPropertySet.SetProperty("ConnectionMode", esriAGSConnectionMode.esriAGSConnectionModeAdmin);
                pPropertySet.SetProperty("ServerType", esriAGSServerType.esriAGSServerTypeDiscovery);
                pPropertySet.SetProperty("user", userName);
                pPropertySet.SetProperty("password", passWord);
                pPropertySet.SetProperty("ALLOWINSECURETOKENURL", true);
                IAGSServerConnectionName3 pConnectName = new AGSServerConnectionNameClass() as IAGSServerConnectionName3;
                pConnectName.ConnectionProperties = pPropertySet;
                IAGSServerConnectionAdmin pAGSAdmin = ((IName)pConnectName).Open() as IAGSServerConnectionAdmin;
                message = "连接成功!";
                isConnect = true;
                return pAGSAdmin.ServerObjectAdmin;
            }
            catch (Exception ex)
            {
                message = String.Format("连接失败:{0}\rMessage:{1}", url, ex.Message.ToString());
                isConnect = false;
                return null;
            }
        }

<2> 服务操作

*自己声明了一个枚举用于存储地图服务的类型参数

        /// <summary>
        /// 服务类型
        /// </summary>
        public enum ServerType
        { 
            MapServer,
            WMS,
            KML,
            WFS
        }

*启动服务

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="serverName">服务名称</param>
        /// <param name="serverType">服务类型</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回启动结果</returns>
        public static bool StartServer(IServerObjectAdmin pSOA, string serverName, ServerType serverType, out string message)
        {
            try
            {
                pSOA.StartConfiguration(serverName, serverType.ToString());
                message = String.Format("{0}已启动", serverName);
                return true;
            }
            catch (Exception ex)
            {
                message = String.Format("启动失败\r{0}", ex.Message.ToString());
                return false;
            }
            
        }

*停止服务

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="serverName">服务名称</param>
        /// <param name="serverType">服务类型</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回停止结果</returns>
        public static bool StopServer(IServerObjectAdmin pSOA, string serverName, ServerType serverType, out string message)
        {
            try
            {
                pSOA.StopConfiguration(serverName, serverType.ToString());
                message = String.Format("{0}已停止", serverName);
                return true;
            }
            catch (Exception ex)
            {
                message = String.Format("停止失败\r{0}", ex.Message.ToString());
                return false;
            }
        }

*重启服务

        /// <summary>
        /// 重启服务
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="serverName">服务名称</param>
        /// <param name="serverType">服务类型</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回重启结果</returns>
        public static bool RestartServer( IServerObjectAdmin pSOA, string serverName, ServerType serverType, out string message)
        {
            try
            {
                pSOA.StopConfiguration(serverName, serverType.ToString());
                pSOA.StartConfiguration(serverName, serverType.ToString());
                message = String.Format("{0}重启成功", serverName);
                return true;
            }
            catch (Exception ex)
            {
                message = String.Format("重启失败\r{0}", ex.Message.ToString());
                return false;
            }       
        }

*删除服务

        /// <summary>
        /// 删除服务
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="serverName">服务名称</param>
        /// <param name="serverType">服务类型</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回删除结果</returns>
        public static bool DeleteServer(IServerObjectAdmin pSOA, string serverName, ServerType serverType, out string message)
        {
            try
            {
                pSOA.DeleteConfiguration(serverName, serverType.ToString());
                message = String.Format("{0}已删除", serverName);
                return true;
            }
            catch (Exception ex)
            {
                message = String.Format("删除失败\r{0}", ex.Message.ToString());
                return false;
            }
        }

*暂停服务(调用时会出错,因为官方还没有实现这个方法,所以可以忽略)

        /// <summary>
        /// 暂停服务(官方没有实现这个方法)
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="serverName">服务名称</param>
        /// <param name="serverType">服务类型</param>
        /// <param name="message">输出消息</param>
        /// <returns>返回暂停结果</returns>
        public static bool PauseServer(IServerObjectAdmin pSOA, string serverName, ServerType serverType, out string message)
        {
            try
            {
                pSOA.PauseConfiguration(serverName, serverType.ToString());
                message = String.Format("{0}已暂停", serverName);
                return true;
            }
            catch (Exception ex)
            {
                message = String.Format("暂停失败\r{0}", ex.Message.ToString());
                return false;
            }
        }

*获取服务列表

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <returns>返回服务列表</returns>
        public static List<Dictionary<string, string>> GetListService_Admin(IServerObjectAdmin pSOA)
        {
            List<Dictionary<string, string>> list_data = new List<Dictionary<string, string>>();
            
            IEnumServerObjectConfiguration pESOC = pSOA.GetConfigurations();
            IServerObjectConfiguration pSOC = pESOC.Next();
            while (pSOC != null)
            {
                Dictionary<string, string> dict_tmp = new Dictionary<string, string>();
                if (pSOC.StartupType == esriStartupType.esriSTAutomatic)
                    dict_tmp["服务状态"] = "已启动";
                else
                    dict_tmp["服务状态"] = "已停止";
                
                dict_tmp["服务名称"] = pSOC.Name;
                dict_tmp["服务类型"] = pSOC.TypeName;
                dict_tmp["描述"] = pSOC.Description;
                dict_tmp["最大实例数"] = pSOC.MaxInstances.ToString();
                dict_tmp["最小实例数"] = pSOC.MinInstances.ToString();
                list_data.Add(dict_tmp);
                pSOC = pESOC.Next();
            }
            return list_data;
        }

*获取目录列表(有更新)

        /// <summary>
        /// 获取目录列表
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <returns>返回目录列表</returns>
        public static List<string> GetDir_Admin(IServerObjectAdmin pSOA)
        {
            List<string> list_Dir = new List<string>();

            IServerObjectAdmin5 pSOA5 = pSOA as IServerObjectAdmin5;
            IEnumBSTR BSTR = pSOA5.GetFolders("arcgisoutput");
            string path = BSTR.Next();
            while (path != null)
            {
                list_Dir.Add(path);
                path = BSTR.Next();
            }

            // 下面这种方法只能获取ArcGIS Server的存储目录,而不是管理服务的目录
            //IEnumServerDirectory pESD = pSOA.GetServerDirectories();
            //IServerDirectory pSD = pESD.Next();
            //while (pSD != null)
            //{
                
            //    Dictionary<string, string> dict_tmp = new Dictionary<string, string>();      
            //    dict_tmp["最大文件生命周期"] = pSD.MaxFileAge.ToString();
            //    dict_tmp["路径"] = pSD.Path;
            //    dict_tmp["URL地址"] = pSD.URL;
            //    dict_tmp["描述"] = pSD.Description;
            //    list_Dir.Add(dict_tmp);
            //    pSD = pESD.Next();
            //}
            return list_Dir;
        }

*注意:这些操作都是不带Token验证的,如果需要获取token,可以参考下面这段代码(网上扒的)

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="url">服务器Url地址</param>
        /// <param name="userName">用户名</param>
        /// <param name="passWord">密码</param>
        /// <returns>Token值</returns>
        public static string GetAGSToken_RESTAdmin(string url, string userName, string passWord)
        {
            try
            {
                if (url.EndsWith("\\"))
                    url = url.Substring(0, url.Length - 1);
                if (url.EndsWith("services"))
                    url = url.Substring(0, url.Length - 9);

                string loginUrl = url + "/generateToken";
                // 构建Request请求
                WebRequest request = WebRequest.Create(loginUrl);
                request.Method = "POST";
                // 构造Json请求链接
                string credential = "username=" + userName + "&password=" + passWord + "&client=requestip&expiration=&f=json";
                byte[] content = Encoding.UTF8.GetBytes(credential);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                // 获取Reponse响应
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();

                // 解析Json数据
                IJSONReader2 pJsonReader = new JSONReaderClass();
                IJSONObject pJob = pJsonReader.ParseJSONString(result) as IJSONObject;
                string token = "";
                if (pJob.TryGetValueAsString("token", out token))
                    return token;
                else
                    return "";
            }
            catch
            {
                return "";
            }
        }

(2) 发布地图服务

发布地图服务可以直接在ArcGIS中进行,同时也方便做切片和检查异常,但是咱们说好用ArcGIS Engine来发布,就不去再强调ArcGIS如何连接Server并发布服务了,百度上一搜一大堆,废话不多说,直接上代码。

<1> Engine发布地图服务(有问题)

之前说过,从ArcGIS 10.1开始,由于Server架构的调整,不能使用Engine直接发布服务了,不过下面这段代码我测试过,除了发布的那段有问题外,别的都没有问题,还是值得参考的。

        /// <summary>
        /// 发布服务
        /// </summary>
        /// <param name="pSOA">SOA对象</param>
        /// <param name="message">消息</param>
        /// <param name="mxdPath">发布文件的路径</param>
        /// <param name="serverName">发布服务的名称</param>
        /// <param name="serverType">发布服务的类型</param>
        /// <param name="allowOperate">允许的操作</param>
        /// <param name="targetCluster">托管此服务的集群</param>
        /// <param name="startupType">服务启动的类型</param>
        /// <param name="isolationLevel">隔离性等级</param>
        /// <param name="isPooled">是否池化</param>
        /// <param name="maxInstances">最大实例数</param>
        /// <param name="minInstances">最小实例数</param>
        /// <param name="waitTimeout">客户端获取服务将等待的最长时间</param>
        /// <param name="usageTimeout">客户端可使用服务的最长时间</param>
        /// <param name="idleTimeout">空闲实例可持续运行的最长时间</param>
        /// <param name="desc">项目描述</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="interval">回收此配置的时间间隔</param>
        /// <param name="maxRecordCount">服务器返回的最大记录数</param>
        public static void PublishMapServer(
            IServerObjectAdmin pSOA, 
            out string message,
            string mxdPath,
            string serverName, 
            string serverType = "MapServer",
            string allowOperate = "Map,Query,Data",
            string targetCluster = "default",
            esriStartupType startupType = esriStartupType.esriSTAutomatic,
            esriServerIsolationLevel isolationLevel = esriServerIsolationLevel.esriServerIsolationHigh,
            bool isPooled = true,
            int maxInstances = 2,
            int minInstances = 1,
            int waitTimeout = 60,
            int usageTimeout = 600,
            int idleTimeout = 1800,
            string desc = "",
            string startTime = "00:00",
            string interval = "24",
            string maxRecordCount = "1000"
            )
        {
            try
            {
                IServerObjectConfiguration5 pSOC5 = pSOA.CreateConfiguration() as IServerObjectConfiguration5;
                pSOC5.Name = serverName; // 发布服务的名称
                pSOC5.TypeName = serverType; // 发布服务的类型
                pSOC5.TargetCluster = targetCluster; // 托管此服务的集群
                pSOC5.StartupType = startupType; // 服务启动的类型
                pSOC5.IsolationLevel = isolationLevel; // 隔离性等级
                pSOC5.IsPooled = isPooled; // 是否池化
                pSOC5.MaxInstances = maxInstances; // 最大实例数
                pSOC5.MinInstances = minInstances; // 最小实例数
                pSOC5.WaitTimeout = waitTimeout; // 客户端获取服务将等待的最长时间
                pSOC5.UsageTimeout = usageTimeout; // 客户端可使用服务的最长时间
                pSOC5.IdleTimeout = idleTimeout; // 空闲实例可持续运行的最长时间
                pSOC5.Description = desc; // 项目描述

                // 进程
                IPropertySet pPropertySet_Recycle = pSOC5.RecycleProperties;
                pPropertySet_Recycle.SetProperty("StartTime", startTime); // 开始时间
                pPropertySet_Recycle.SetProperty("Interval", interval); // 回收此配置的时间间隔

                // 设置SOC参数
                IPropertySet pPropertySet = pSOC5.Properties;
                pPropertySet.SetProperty("FilePath", mxdPath); // MXD文件路径
                pPropertySet.SetProperty("MaxRecordCount", maxRecordCount); // 服务器返回的最大记录数
                pPropertySet.SetProperty("SupportedImageReturnTypes", "MIME + URL"); // 支持的图片类型

                // 目录设置
                IEnumServerDirectory dirs = pSOA.GetServerDirectories();
                dirs.Reset();
                IServerDirectory serverDir = dirs.Next();
                while (serverDir != null)
                {
                    if (((IServerDirectory2)serverDir).Type == esriServerDirectoryType.esriSDTypeOutput)
                    {
                        pPropertySet.SetProperty("OutputDir", serverDir.Path); // 输出目录
                        pPropertySet.SetProperty("VirtualOutputDir", serverDir.URL); // 输出虚拟目录
                        break;
                    }
                    serverDir = dirs.Next();
                }

                // 设置服务功能
                IPropertySet pPropertySetInfo = pSOC5.Info;
                pPropertySetInfo.SetProperty("WebEnabled", "true");
                pPropertySetInfo.SetProperty("WebCapabilities", allowOperate); // 允许的操作

                // 添加服务到Server
                pSOA.AddConfiguration(pSOC5);
                // 启动服务
                // pSOA.StartConfiguration(serverName, serverType);
                message = String.Format("发布成功!\r服务名称:{0}", serverName);
            }
            catch (Exception ex)
            {
                message = String.Format("发布失败!\r错误:{0}\r服务名称:{1}", ex.Message, serverName);
            }
            
        }

<2> GP工具发布地图服务

由于ArcGIS Engine不能直接发布服务,只好换个思路,通过Python来实现服务发布,先实现Python发布地图服务的脚本。

注意:①这里编码为cp936,不推荐使用utf-8,在使用中文路径或者中文字符时可能会报错,Python对中文编码的支持不是特别友好。

#!/usr/bin/env python
# -*- coding: cp936 -*-
'''
# Time    : 2019/12/1 16:35
# Author  : YSW
# File    : publishserver.py
# Software: PyCharm
# Desc    : 自动发布地图服务
'''

import arcpy
import gc
import os
from arcpy import env

arcpy.AddMessage("[*] 开始执行服务发布脚本")
# server_username = 'arcgis'
# server_password = '123456'
# env.workspace = r"E:\Python for ArcGIS\Server"
# wrkspc = "E:\\Python for ArcGIS\\Server\\"
# connection_type = 'PUBLISH_GIS_SERVICES'
# out_folder_path = r"E:\Python for ArcGIS\Server"
# out_name = 'test1.ags'
# server_url = 'http://192.168.1.186:6080/arcgis/admin'
# use_arcgis_desktop_staging_folder = False
# staging_folder_path = out_folder_path
# mapDoc = arcpy.mapping.MapDocument(u"F:\\PublishTools\\影像发布.mxd")
# service_name = 'test1'
# sddraft = wrkspc + service_name + '.sddraft'
# sd = wrkspc + service_name + '.sd'
# summary = 'this is test'
# tags = 'this is test'
# con = wrkspc + out_name

server_url = arcpy.GetParameterAsText(0)  # 服务器Url地址
server_username = arcpy.GetParameterAsText(1)  # 用户名
server_password = arcpy.GetParameterAsText(2)  # 密码
server_catalog = arcpy.GetParameterAsText(3)  # 存储服务的目录
service_name = arcpy.GetParameterAsText(4)  # 服务名称
connection_type = arcpy.GetParameterAsText(5)  # 连接类型
global_catalog = arcpy.GetParameterAsText(6)  # 工作空间
env.workspace = global_catalog  # 工作空间
wrkspc = global_catalog + "\\"
out_folder_path = global_catalog
mapDoc = arcpy.GetParameterAsText(7)  # 地图文档路径
out_name = service_name + ".ags"  # ags文件名称
sddraft = wrkspc + service_name + '.sddraft'  # sddraft文件路径
sd = wrkspc + service_name + '.sd'  # sd文件路径
use_arcgis_desktop_staging_folder = False  # 是否使用ArcGIS桌面的暂存文件夹
staging_folder_path = out_folder_path  # 暂存文件夹路径
summary = arcpy.GetParameterAsText(8)  # 概要
tags = arcpy.GetParameterAsText(9)  # 标签
con = wrkspc + out_name  # 输出的ags文件路径

# 存储要删除的临时文件
list_delete = []
list_delete.append(sd)
list_delete.append(con)

arcpy.AddMessage("[+] 开始创建GIS服务连接文件...")
# 1.创建server连接
arcpy.mapping.CreateGISServerConnectionFile(connection_type, out_folder_path, out_name, server_url,
                                            'ARCGIS_SERVER', use_arcgis_desktop_staging_folder,
                                            staging_folder_path, server_username, server_password,
                                            "SAVE_USERNAME")
arcpy.AddMessage("[+] 创建成功!")

arcpy.AddMessage("[+] 开始创建地图sd草案文件...")
# 2.将mxd文档变为服务定义草稿(.sddraft)文件,服务定义草稿文件会在服务定义文件(sd)后自动删除
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service_name, 'ARCGIS_SERVER',
                                          con, False, server_catalog, summary, tags)
arcpy.AddMessage("[+] 创建成功!")

arcpy.AddMessage("[+] 开始发布服务")
# 3.上传服务定义,发布服务
if analysis['errors'] == {}:
    arcpy.StageService_server(sddraft, sd)
    arcpy.UploadServiceDefinition_server(sd, con)
    # arcpy.SignOutFromPortal_server()
    arcpy.AddMessage("[+] 发布成功!")
else:
    arcpy.AddMessage("[-] 发布失败{0}".format(analysis['errors']))

# 4.删除临时文件,清理内存
arcpy.AddMessage("[+] 删除临时文件")
if len(list_delete) > 0:
    for f in list_delete:
        os.remove(f)

arcpy.AddMessage("[+] 清理缓存")
gc.collect()
arcpy.AddMessage("[+] 发布完成")

注意:②在创建脚本工具时最好保存在单独的工具箱中,然后工具箱也保存在单独的文件夹下,便于之后程序加载GP工具。如下:

*调用GP工具

首先打开VS2012,在右击引用,找到 ArcGIS Toolbox Reference 

选择设置好的地图服务发布工具箱,并设置参数,点击OK

会发现已经把GP工具转换成*.Dll并添加到引用中

注意:③把PublishTool引用先删掉,再重新浏览添加。因为之前已经生成过*.Dll文件,所以可以在你的程序包里就能找到。

*程序调用自定义的GP工具

注意:④如果直接调用GP工具进行使用,由于权限分配的问题,可能会出现 “COM 组件的调用返回了错误 HRESULT E_FAIL ” 的错误,这里需要初始化一下Advanced许可,才能调用我们自定义的GP工具。代码如下:

ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
#region 初始化许可
IAoInitialize m_AoInitialize = new AoInitializeClass();
esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable;
licenseStatus = m_AoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
if (licenseStatus == esriLicenseStatus.esriLicenseNotInitialized)
{
    MessageBox.Show("没有Advanced许可!");
    Application.Exit();
}
#endregion

然后再调用我们之前写好的GP工具,注意参数不要写错了。

Geoprocessor GP = new Geoprocessor();
// 创建自定义GP服务对象
PublishTool.PublishServer ps = new PublishTool.PublishServer();
// 设置参数 (自己设) 
ps.服务器URL地址 = "";
ps.用户名 = "";
ps.密码 = "";
ps.存储目录 = ""; // Server的目录
ps.服务名称 = ""; 
ps.连接类型 = ""; // PUBLISH_GIS_SERVICES、USE_GIS_SERVICES、ADMINISTER_GIS_SERVICES
ps.工作空间 = ""; // 要上传的Mxd文件所在的文件夹
ps.MXD文件路径 = "";
ps.摘要 = "";
ps.标签 = "";
// 执行
GP.Execute(ps, null);

注意:⑤调用GP发布服务时速度会变得特别慢,如果不用多线程或者异步,会造成程序假死。

(3) 加载地图服务

*这里通过两种方式加载地图服务并返回ILayer对象,直接上代码

<1> 遍历整个目录,找到匹配服务名称的地图服务进行加载。

        /// <summary>
        /// 加载地图服务
        /// </summary>
        /// <param name="servicesUrl">地图服务目录Url地址</param>
        /// <param name="mapServerName">地图服务名称</param>
        /// <returns>返回图层对象</returns>
        public static ILayer LoadMapService1(string servicesUrl, string mapServerName)
        {
            // 构建AGS服务
            IAGSServerObjectName pSOName_Tmp = null;
            IAGSServerObjectName pSOName = null;
            IAGSServerConnection con = new AGSServerConnection();
            IAGSServerConnectionFactory2 confactory = new AGSServerConnectionFactory() as IAGSServerConnectionFactory2;
            IPropertySet propertyset = new PropertySet();
            IMapServerLayer mapserverlayer = new MapServerLayerClass();

            // 设置Rest服务Url,例如"http://192.168.1.186:6080/arcgis/rest/services/"
            propertyset.SetProperty("URL", servicesUrl);
            // 连接服务
            con = confactory.Open(propertyset, 0);

            // 遍历获取指定地图服务
            IAGSEnumServerObjectName enumSOName = con.ServerObjectNames;
            pSOName_Tmp = enumSOName.Next();
            while (pSOName_Tmp != null)
            {
                if (pSOName_Tmp.Name == mapServerName)
                {
                    pSOName = pSOName_Tmp;
                    break;
                }
                pSOName_Tmp = enumSOName.Next();
            }

            // 根据名称打开地图服务
            IName pName = pSOName as IName;
            IMapServer mapserver = pName.Open() as IMapServer;

            // 连接地图服务并返回图层对象
            mapserverlayer.ServerConnect(pSOName_Tmp, mapserver.DefaultMapName);
            return mapserverlayer as ILayer;      
        } 

<2> 直接通过地图服务提供的Rest链接加载。

        /// <summary>
        /// 加载地图服务
        /// </summary>
        /// <param name="serverUrl">地图服务Url</param>
        /// <returns>返回图层对象</returns>
        public static ILayer LoadMapService2(string serverUrl)
        {
            IMapServerRESTLayer mapServerRESTLayer = new MapServerRESTLayerClass();
            // 例如 "http://192.168.1.186:6080/arcgis/rest/services/SampleWorldCities/MapServer"
            mapServerRESTLayer.Connect(serverUrl);
            return mapServerRESTLayer as ILayer;
        }

3.Environment

Device:①测试可以不用局域网,在同一个网段即可,例如192.168.1.x。②本机测试则用localhost。

Environment:Windows 7及以上、Windows Server 2012 R2 DataCenter

Language:C#、Python 2.7

IDE:Visual Studio 2012

SDK:ArcGIS Engine 10.2.2

Server:ArcGIS Server 10.2.2


4.Conclusion

写的比较凌乱,就如最近的我,人在代码中凌乱,不过也算是把遇到的问题都总结了一下,之后会在Github上,随缘投放ArcGIS Server服务管理器的源码。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dr_Asada

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值