ArcGIS Engine的代码不能直接将MXD地图文档作为数据源进行发布,如果要发布的话,需要用ArcMap将MXD转成MSD,然后使用转换成功的MSD文档进行发布,代码如下:
public void Publish(string host,string username,string password, string service, string msdDocument, string outputDir)
{
//IAGSServerConnectionFactory3 pConnectionFactory = new AGSServerConnectionFactoryClass();
////admin connection file works fine, tested in ArcCatalog on the same server
//IAGSServerConnection4 server = pConnectionFactory.OpenFromFile(@"e:\admin-connection.ags", 0) as IAGSServerConnection4;
// IAGSServerConnectionAdmin pAGSServerConnectionAdmin = server as IAGSServerConnectionAdmin;
IPropertySet propertySet = new PropertySetClass();
propertySet.SetProperty("url", host);
propertySet.SetProperty("ConnectionMode", esriAGSConnectionMode.esriAGSConnectionModeAdmin);
propertySet.SetProperty("ServerType", esriAGSServerType.esriAGSServerTypeDiscovery);
propertySet.SetProperty("user", username);
propertySet.SetProperty("password", password);
propertySet.SetProperty("ALLOWINSECURETOKENURL", true); //设置为false会弹出一个警告对话框
IAGSServerConnectionName3 pConnectName = new AGSServerConnectionNameClass() as IAGSServerConnectionName3;//10.1新增接口
pConnectName.ConnectionProperties = propertySet;
IAGSServerConnectionAdmin pAGSAdmin = ((IName)pConnectName).Open() as IAGSServerConnectionAdmin;
IAGSServerConnectionAdmin pAGSServerConnectionAdmin = pAGSAdmin as IAGSServerConnectionAdmin;
IServerObjectAdmin pServerObjectAdmin = pAGSServerConnectionAdmin.ServerObjectAdmin;
IServerObjectConfiguration5 pConfiguration = (IServerObjectConfiguration5)pServerObjectAdmin.CreateConfiguration();
//Set the general configuration settings
pConfiguration.Name = service;
pConfiguration.TypeName = "MapServer";
pConfiguration.TargetCluster = "default";
pConfiguration.StartupType = esriStartupType.esriSTAutomatic;
pConfiguration.IsolationLevel = esriServerIsolationLevel.esriServerIsolationHigh;
pConfiguration.IsPooled = true;
pConfiguration.Description = "Modsim Map Output";
// pConfiguration.LoadBalancing = esriLoadBalancing.esriLoadBalancingNone;//没有集群的话可以不用设置
pConfiguration.MinInstances = 1;
pConfiguration.MaxInstances = 15;
pConfiguration.WaitTimeout = 60;
pConfiguration.UsageTimeout = 600;
pConfiguration.IdleTimeout = 1800;
//Set the configuration properties of the MapServer
IPropertySet pProps = pConfiguration.Properties;
pProps.SetProperty("FilePath", msdDocument);
pProps.SetProperty("OutputDir", outputDir);
pProps.SetProperty("MaxImageHeight", "2048");
pProps.SetProperty("MaxRecordCount", "1000");
pProps.SetProperty("MaxBufferCount", "100");
pProps.SetProperty("MaxImageWidth", "2048");
pConfiguration.Properties = pProps;
//MIME+URL (virtual directory)
IEnumServerDirectory dirs = pServerObjectAdmin.GetServerDirectories();
dirs.Reset();
IServerDirectory serverDir = dirs.Next();
while (serverDir != null)
{
if (((IServerDirectory2)serverDir).Type == esriServerDirectoryType.esriSDTypeOutput)
{
pProps.SetProperty("OutputDir", serverDir.Path);
pProps.SetProperty("VirtualOutputDir", serverDir.URL);
break;
// gp.AddMessage("[DEBUG] Outputpath: " + serverDir.Path + " || Virtual: " + serverDir.URL);
}
serverDir = dirs.Next();
}
//Set the info segment properties
IPropertySet info = pConfiguration.Info;
info.SetProperty("WebEnabled", "true");
info.SetProperty("WebCapabilities", "Map,Query,Data");
pConfiguration.Info = info;
//Set the recycle properties of the MapServer object
IPropertySet recycle = pConfiguration.RecycleProperties;
recycle.SetProperty("StartTime", "1:00 AM");
recycle.SetProperty("Interval", "86400");
pConfiguration.RecycleProperties = recycle;
//Add the configuration to the server
pServerObjectAdmin.AddConfiguration(pConfiguration);
pServerObjectAdmin.StartConfiguration(service, "MapServer");
}
ArcGIS 10.1 在发布服务的时候其实是按照下面的步骤来的,如果认真观察过也不难得出:
l 将MXD文档转成sddraft文件;
l 将sddraft文件转成sd文件;
l 将sd文件上传到ArcGIS for Server中
既然这个过程已经知道了,那么就可以通过Python按照这个流程来自动化的完成服务的发布:
import arcpy
# define local variables
wrkspc = 'C:/Project/'
mapDoc = arcpy.mapping.MapDocument(wrkspc + 'counties.mxd')
con = r'GIS Servers\arcgis on MyServer_6080 (admin).ags'
service = 'Counties'
sddraft = wrkspc + service + '.sddraft'
sd = wrkspc + service + '.sd'
# create service definition draft
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER', con, True, None)
# analyze the service definition draft
analysis = arcpy.mapping.AnalyzeForSD(sddraft)
# stage and upload the service if the sddraft analysis did not contain errors
if analysis['errors'] == {}:
# Execute StageService
arcpy.StageService_server(sddraft, sd)
# Execute UploadServiceDefinition
arcpy.UploadServiceDefinition_server(sd, con)
else:
# if the sddraft analysis contained errors, display them
print analysis['errors']
可以将上面的脚本创建为一个tbx文件,然后在ArcGIS Engine中通过GP来实现服务的发布.
其实Esri在官网上发布了一个tbx里面就包含了对server服务管理的功能(有兴趣的可以下载,文档所在的目录下也包含了):
ArcGIS for Server 10.1 增加了Admin API,那么,所谓的Admin API 其实就是一一http请求的方法,这些方法包含了对Server的管理,下面为Admin API 的代码:
namespace ServerAPIAdmin.ArcGIS.Rest { using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; using ESRI.ArcGIS.SOESupport;
///<summary> /// tipi di servizio arcgis server (mappa la tabella servizio tipo) ///</summary> public enum ServiceType { MapServer, GeocodeServer, SearchServer, IndexingLauncher, IndexGenerator, GeometryServer, GeoDataServer, GPServer, GlobeServer, ImageServer }
///<summary> /// Load Balancing ///</summary> public enum LoadBalancing { ROUND_ROBIN, FAIL_OVER }
///<summary> /// isolation level ///</summary> public enum IsolationLevel { LOW, HIGH }
///<summary> /// administrative API Rest ///</summary> public class AGSAdmin { private string username; private string password; private string urlRestAdmin; private string urlRestServer;
///<summary> /// Initializes a new instance of the <see cref="AGSAdmin"/> class. ///</summary> ///<param name="serverName">server name</param> ///<param name="port">port of server</param> ///<param name="username">username administrator</param> ///<param name="password">password administrator</param> public AGSAdmin(string serverName, int port, string username, string password) { this.username = username; this.password = password; string url = string.Format("http://{0}:{1}/arcgis", serverName, port.ToString()); this.urlRestAdmin = url + "/admin"; this.urlRestServer = url + "/server"; }
///<summary> /// Prevents a default instance of the <see cref="AGSAdmin"/> class from being created. ///</summary> private AGSAdmin() { }
///<summary> /// Create arcgis server folder ///</summary> ///<param name="folderName">Folder name</param> ///<param name="description">Description of the folder</param> ///<returns>True if successfully created</returns> public bool CreateServerFolder(string folderName, string description) { try { string token = this.GenerateAGSToken(); string folderUrl = this.urlRestAdmin + "/services/" + folderName + "?f=json&token=" + token; string resultExistsFolder = this.GetResult(folderUrl); if (!this.HasError(resultExistsFolder)) { return true; // exists } else { string createFolderUrl = this.urlRestAdmin + "/services/createFolder"; string postContent = string.Format("folderName={0}&description={1}&f=json&token={2}", folderName, description, token); string result = this.GetResult(createFolderUrl, postContent); return this.HasSuccess(result); } } catch { return false; } }
///<summary> /// Get physical Path and virtual Path from directory ags ///</summary> ///<param name="directory">directory ags</param> ///<param name="physicalPath">physical Path</param> ///<param name="virtualPath">virtual Path</param> ///<returns>True if successfully return path</returns> public bool GetServerDirectory(string directory, out string physicalPath, out string virtualPath) { physicalPath = null; virtualPath = null; try { string token = this.GenerateAGSToken(); string directoryUrl = this.urlRestAdmin + "/system/directories/" + directory + "?f=json&token=" + token;
string result = this.GetResult(directoryUrl);
JsonObject jsonObject = new JsonObject(result); if (!jsonObject.Exists("physicalPath") || !jsonObject.TryGetString("physicalPath", out physicalPath)) { throw new Exception(); }
jsonObject = new JsonObject(result); if (!jsonObject.Exists("virtualPath") || !jsonObject.TryGetString("virtualPath", out virtualPath)) { throw new Exception(); }
return true; } catch { return false; } }
///<summary> /// Delete Service ///</summary> ///<param name="serviceName">Service Name</param> ///<param name="serviceType">Server Type</param> ///<returns>True if successfully deleted</returns> public bool DeleteService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/delete"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } }
///<summary> /// Start Service ///</summary> ///<param name="serviceName">Service Name</param> ///<param name="serviceType">Server Type</param> ///<returns>True if successfully started</returns> public bool StartService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/start"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } }
///<summary> /// Stop Service ///</summary> ///<param name="serviceName">Service Name</param> ///<param name="serviceType">Server Type</param> ///<returns>True if successfully stopped</returns> public bool StopService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/stop"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } }
///<summary> /// list of services ///</summary> public void ListServices() { this.ListServices(null); }
///<summary> /// list of services in folder ///</summary> ///<param name="folder">name of folder</param> public void ListServices(string folder) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + folder; string postcontent = "f=json&token=" + token; string result = this.GetResult(serviceUrl, postcontent);
JsonObject jsonObject = new JsonObject(result); object[] folders = null; if (jsonObject.Exists("folders") && jsonObject.TryGetArray("folders", out folders)) { foreach (string subfolder in folders) { this.ListServices(subfolder); } }
object[] services = null; if (jsonObject.Exists("services") && jsonObject.TryGetArray("services", out services)) { IEnumerable<JsonObject> jsonObjectService = services.Cast<JsonObject>(); jsonObjectService.ToList().ForEach(jo => { string serviceName; jo.TryGetString("serviceName", out serviceName); string folderName; jo.TryGetString("folderName", out folderName); Console.WriteLine(folderName + "/" + serviceName); }); } } catch { throw; } }
///<summary> /// create service type MapServer ///</summary> ///<returns>>True if successfully created</returns> public bool CreateService(String msdPath) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/createService";
JsonObject jsonObject = new JsonObject(); jsonObject.AddString("serviceName", "Test"); jsonObject.AddString("type", Enum.GetName(typeof(ServiceType), ServiceType.MapServer)); jsonObject.AddString("description", "This is an example"); jsonObject.AddString("capabilities", "Map,Query,Data"); jsonObject.AddString("clusterName", "default"); jsonObject.AddLong("minInstancesPerNode", 1); jsonObject.AddLong("maxInstancesPerNode", 2); jsonObject.AddLong("maxWaitTime", 60); jsonObject.AddLong("maxStartupTime", 300); jsonObject.AddLong("maxIdleTime", 1800); jsonObject.AddLong("maxUsageTime", 600); jsonObject.AddLong("recycleInterval", 24); jsonObject.AddString("loadBalancing", Enum.GetName(typeof(LoadBalancing), LoadBalancing.ROUND_ROBIN)); jsonObject.AddString("isolationLevel", Enum.GetName(typeof(IsolationLevel), IsolationLevel.HIGH));
JsonObject jsonObjectProperties = new JsonObject();
// see for a list complete http://resources.arcgis.com/en/help/server-admin-api/serviceTypes.html jsonObjectProperties.AddLong("maxBufferCount", 100); // optional 100 jsonObjectProperties.AddString("virtualCacheDir", this.urlRestServer + "/arcgiscache"); // optional jsonObjectProperties.AddLong("maxImageHeight", 2048); // optional 2048 jsonObjectProperties.AddLong("maxRecordCount", 1000); // optional 500
// Other service types do not require you to use arcpy.mapping or create an MSD. jsonObjectProperties.AddString("filePath", msdPath); // required
jsonObjectProperties.AddLong("maxImageWidth", 2048); // optional 2048 jsonObjectProperties.AddBoolean("cacheOnDemand", false); // optional false jsonObjectProperties.AddString("virtualOutputDir", this.urlRestServer + "/arcgisoutput"); jsonObjectProperties.AddString("outputDir", @"C:\arcgisserver\directories\arcgisoutput"); // required jsonObjectProperties.AddString("supportedImageReturnTypes", "MIME+URL"); // optional MIME+URL jsonObjectProperties.AddBoolean("isCached", false); // optional false jsonObjectProperties.AddBoolean("ignoreCache", false); // optional false jsonObjectProperties.AddBoolean("clientCachingAllowed", false); // optional true jsonObjectProperties.AddString("cacheDir", @"C:\arcgisserver\directories\arcgiscache"); // optional
jsonObject.AddJsonObject("properties", jsonObjectProperties);
string result = this.GetResult(serviceUrl, "service=" + HttpUtility.UrlEncode(jsonObject.ToJson()) + "&f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } }
///<summary> /// check is status is equal success ///</summary> ///<param name="result">result of request</param> ///<returns>True if status is equal success</returns> private bool HasSuccess(string result) { JsonObject jsonObject = new JsonObject(result); string status = null; if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status)) { return false; }
return status == "success"; }
///<summary> /// check is status is equal error ///</summary> ///<param name="result">result of request</param> ///<returns>True if status is equal error</returns> private bool HasError(string result) { JsonObject jsonObject = new JsonObject(result); string status = null; if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status)) { return false; }
return status == "error"; }
///<summary> /// Get request rest ///</summary> ///<param name="url">url of request</param> ///<returns>return response</returns> private string GetResult(string url) { try { WebRequest request = WebRequest.Create(url); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } catch { throw; } }
///<summary> /// Post request rest ///</summary> ///<param name="url">url of request</param> ///<param name="postContent">content of post</param> ///<returns>return response</returns> private string GetResult(string url, string postContent) { try { WebRequest request = WebRequest.Create(url); byte[] content = Encoding.UTF8.GetBytes(postContent); request.ContentLength = content.Length; request.ContentType = "application/x-www-form-urlencoded"; request.Method = WebRequestMethods.Http.Post; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(content, 0, content.Length); requestStream.Close(); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } } catch { throw; } }
///<summary> /// Generate a token ///</summary> ///<returns>A token that has default expiration time</returns> private string GenerateAGSToken() { try { string urlGenerateToken = string.Format("{0}/generateToken", this.urlRestAdmin); string credential = string.Format("username={0}&password={1}&client=requestip&expiration=&f=json", this.username, this.password); string result = this.GetResult(urlGenerateToken, credential);
JsonObject jsonObject = new JsonObject(result); string token = null; if (!jsonObject.Exists("token") || !jsonObject.TryGetString("token", out token)) { throw new Exception("Token not found!"); }
return token; } catch { return string.Empty; } } } }
|