1 ArcGIS Engine 10.2 如何釋出服務
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");
}
2 使用ArcGIS Engie中的GP釋出地圖文檔
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服務管理的功能(有興趣的可以下載下傳,文檔所在的目錄下也包含了):

3 使用Admin API 釋出文檔
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
}
/// Load Balancing
public enum LoadBalancing
ROUND_ROBIN,
FAIL_OVER
/// isolation level
public enum IsolationLevel
LOW,
HIGH
/// administrative API Rest
public class AGSAdmin
private string username;
private string password;
private string urlRestAdmin;
private string urlRestServer;
/// Initializes a new instance of the <see cref="AGSAdmin"/> class.
///<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";
/// Prevents a default instance of the <see cref="AGSAdmin"/> class from being created.
private AGSAdmin()
/// Create arcgis server folder
///<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;
/// Get physical Path and virtual Path from directory ags
///<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;
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))
return true;
/// Delete Service
///<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)
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/delete";
string result = this.GetResult(serviceUrl, "f=json&token=" + token);
/// Start Service
///<returns>True if successfully started</returns>
public bool StartService(string serviceName, ServiceType serviceType)
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/start";
/// Stop Service
///<returns>True if successfully stopped</returns>
public bool StopService(string serviceName, ServiceType serviceType)
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/stop";
/// list of services
public void ListServices()
this.ListServices(null);
/// list of services in folder
///<param name="folder">name of folder</param>
public void ListServices(string folder)
string serviceUrl = this.urlRestAdmin + "/services/" + folder;
string postcontent = "f=json&token=" + token;
string result = this.GetResult(serviceUrl, postcontent);
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);
});
throw;
/// create service type MapServer
///<returns>>True if successfully created</returns>
public bool CreateService(String msdPath)
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);
/// check is status is equal success
///<param name="result">result of request</param>
///<returns>True if status is equal success</returns>
private bool HasSuccess(string result)
string status = null;
if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status))
return status == "success";
/// check is status is equal error
///<returns>True if status is equal error</returns>
private bool HasError(string result)
return status == "error";
/// Get request rest
///<param name="url">url of request</param>
///<returns>return response</returns>
private string GetResult(string url)
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
return reader.ReadToEnd();
/// Post request rest
///<param name="postContent">content of post</param>
private string GetResult(string url, string postContent)
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();
{
}
/// Generate a token
///<returns>A token that has default expiration time</returns>
private string GenerateAGSToken()
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);
string token = null;
if (!jsonObject.Exists("token") || !jsonObject.TryGetString("token", out token))
throw new Exception("Token not found!");
return token;
return string.Empty;
}