1.发布地图服务的流程
使用 ArcPy 将地图文档自动发布到 GIS 服务器的流程分为四步:
- 第一步,运行 CreateMapSDDraft 函数。CreateMapSDDraft 的输出是服务定义草稿 (.sddraft) 文件,服务定义草稿由地图文档、服务器信息和一组服务属性组合而成。
- 第二步,使用 AnalyzeForSD 函数分析输出的服务定义草稿文件的适用性和潜在性能问题。
- 第三步,使用 Stage Service 地理处理工具将服务定义草稿转换为完全合并的服务定义 (.sd) 文件。过渡过程会编译成功发布 GIS 资源所需的所有必要信息。如果选择将数据复制到服务器,则将在服务定义草稿阶段添加数据。
- 最后,使用 上载服务定义地理处理工具上载服务定义文件并将其作为 GIS 服务发布到特定的 GIS 服务器。此步骤将获取服务定义文件、将其复制到服务器、提取所需信息并发布 GIS 资源。
2.调用函数参数详解
第一步:创建草图文件
CreateMapSDDraft (map_document, out_sddraft, service_name, {server_type}, {connection_file_path}, {copy_data_to_server}, {folder_name}, {summary}, {tags})
参数 | 说明 | 类型 |
---|---|---|
map_document | Map Document 类型的对象,即一个mxd文档。 | Map Document |
out_sddraft | Service Definition Draft (.sddraft) 文件输出路径。 | String |
service_name | 服务的名字,由字母和数字组成,不允许使用空格或特殊字符,长度不得超过120。 | String |
server_type | 服务的类型,如果未提供「connection_file_path」参数,则必须提供「server_type」。如果提供了「connection_file_path」参数,则从连接文件中获取「 server_type」。 • ARCGIS_SERVER — ArcGIS for Server 服务类型,默认值。 • FROM_CONNECTION_FILE — 从 connection_file_path 参数获取服务类型。 • SPATIAL_DATA_SERVER — Spatial Data Server 服务类型,ArcGIS 10.2.1 版本之后就不再支持。 • MY_HOSTED_SERVICES — My Hosted Services 服务类型,应用与 ArcGIS Online 或者 Portal for ArcGIS 的托管服务。 |
String |
connection_file_path | ArcGIS for Server connection file (.ags) 文件的路径。通常在ArcCatalog创建后的路径为「C:\Users\Administrator\AppData\Roaming\ESRI\Desktop10.2\ArcCatalog」 | String |
copy_data_to_server | mxd文档的数据是否要拷贝到服务器中。当数据没有在服务器内被注册时,此参数应设为false,反之应设为true。 当「server_type」设置为SPATIAL_DATA_SERVER时,「copy_data_to_server」将始终为False。 Spatial Data Server 服务始终使用已注册的数据,因此不会将数据复制到服务器。 当「server_type」设置为MY_HOSTED_SERVICES时,「copy_data_to_server」将始终为True。My Hosted Maps services 服务始终将数据复制到服务器。 |
Boolean |
folder_name | 服务发布的文件夹名,如果不存在则会新建,默认值None对应的是根文件夹。 | String |
summary | 服务的摘要。 | String |
tags | 服务的标签。 | String |
第二、三、四步
可以直接在arcgis帮助文档内查看,有中文的。
3.实现代码
下面是一个发布服务的例子,实现的功能是遍历一个文件夹,将文件夹内.mxd结尾的文件都发布上服务器。
# -*- coding: utf-8 -*-
import arcpy
import os
import xml.dom.minidom as DOM
def SetSddraftParam(sddraft_file_path):
'''修改Sddraft文件的参数。(一般就修改开启WMS、WFS功能)
Args:
sddraft_file_path: .sddraft文件的路径。
'''
doc = DOM.parse(sddraft_file_path)
ext = doc.getElementsByTagName('Extensions')[0]
svcExts = ext.childNodes
for svcExt in svcExts:
typename_ele = svcExt.getElementsByTagName('TypeName')[0]
if typename_ele.firstChild.data == 'WMSServer':
enable_ele = svcExt.getElementsByTagName('Enabled')[0]
enable_ele.firstChild.data = 'true'
break
if os.path.exists(sddraft_file_path):
os.remove(sddraft_file_path)
f = open(sddraft_file_path, 'w')
doc.writexml(f)
f.close()
def GetAGSConnectionFile(out_folder_path):
'''在指定文件夹新建test.ags文件。
Args:
out_folder_path: .ags文件的输出文件夹路径。
Returns:
返回.ags文件的路径。
'''
out_name = 'test.ags'
server_url = 'http://localhost:6080/arcgis/admin'
use_arcgis_desktop_staging_folder = False
staging_folder_path = out_folder_path
username = 'siteadmin'
password = '123456'
out_file_path = os.path.join(out_folder_path, out_name)
if os.path.exists(out_file_path):
os.remove(out_file_path)
arcpy.mapping.CreateGISServerConnectionFile('ADMINISTER_GIS_SERVICES',
out_folder_path,
out_name,
server_url,
'ARCGIS_SERVER',
use_arcgis_desktop_staging_folder,
staging_folder_path,
username,
password,
True)
return out_file_path
def PublishMxd(mxd_file_path, mxd_folder_path, con_file_path):
'''发布服务。
Args:
mxd_file_path:mxd文档的路径。
mxd_folder_path:mxd文档所在文件夹的路径。
con_file_path:服务器连接文件路径
'''
#检查mxd文件是否存在
print "Checking mxd file path..."
if os.path.exists(mxd_file_path) == False:
print "mxd file is not exist!"
return
# 打开mxd文档
try:
print "Opening mxd file..."
mxd = arcpy.mapping.MapDocument(mxd_file_path)
except Exception, e:
print "open mxd error: ", e
return
# 获取默认的数据框
print "Loading mxd file default dataframes..."
df = ""
try:
frames = arcpy.mapping.ListDataFrames(mxd, "图层")
if len(frames) == 0:
frames = arcpy.mapping.ListDataFrames(mxd, "Layers")
df = frames[0]
except Exception, e:
print "load mxd file default dataframes failed:", e
return
# 组织参数发布服务
mxdNameWithExt = os.path.basename(mxd_file_path)
(serviceName, extension) = os.path.splitext(mxdNameWithExt)
sddraft_file_path = os.path.join(mxd_folder_path, serviceName + '.sddraft')
summary = 'Test'
tags = 'Test'
# 创建草图文件
print "CreateMapSDDraft..."
if os.path.exists(sddraft_file_path):
os.remove(sddraft_file_path)
arcpy.mapping.CreateMapSDDraft(mxd, sddraft_file_path, serviceName, 'ARCGIS_SERVER', con_file_path, False, None, summary, tags)
# 设置草图文件内的参数(开启WMS功能,WFS功能等)
SetSddraftParam(sddraft_file_path)
# 分析草图文件
analysis = arcpy.mapping.AnalyzeForSD(sddraft_file_path)
if analysis['errors'] == {}:
for message in analysis['messages']:
print analysis['messages'][message]
print message[0].encode("gb2312") + "(%s)" % message[1]
for warning in analysis['warnings']:
print analysis['warnings'][warning]
print warning[0].encode("gb2312") + "(%s)" % warning[1]
# 过渡服务
print "StageService..."
sdPath = os.path.join(mxd_folder_path1, serviceName + '.sd')
arcpy.StageService_server(sddraft_file_path, sdPath)
# 上传服务定义
print "UploadServiceDefinition_server..."
arcpy.UploadServiceDefinition_server(sdPath, con_file_path)
else:
for error in analysis['errors']:
print analysis['errors'][error]
print error[0].encode("gb2312") + "(%s)" % error[1]
def PublishAll(mxd_folder_path):
'''遍历指定文件夹内的所有mxd文档,并逐个发布服务。
Args:
mxd_folder_path:包含mxd文档的文件夹路径。
'''
print "Check folder path..."
if os.path.isdir(mxd_folder_path) == False:
print "folder path is not exist!"
return
print "Get .ags file..."
con_file_path = GetAGSConnectionFile(mxd_folder_path)
print "******************Traversing a folder******************"
files = os.listdir(mxd_folder_path)
mxdCount = 0
for f in files:
if f.endswith(".mxd"):
mxdCount = mxdCount + 1
mxdNo = 1
for f in files:
if f.endswith(".mxd"):
mxd_file_path = os.path.join(mxd_folder_path, f)
print "Publishing: " + f + "(%d/%d)" % (mxdNo, mxdCount)
mxdNo = mxdNo + 1
PublishMxd(mxd_file_path, mxd_folder_path, con_file_path)
else:
continue
mxd_folder_path = r'E:\MyCode\Mypy\py2\mxd'
publishServices.PublishAll(mxd_folder_path)
4.备注
针对上面的内容还有以下几点需要说明:
1.如果对编码不熟悉的话,建议过程中不要使用中文名。
2.通过arcmap界面发布服务时设置的参数可以在sddraft草图文件内找到,并通过修改文件配置来设置CreateMapSDDraft函数没囊括的参数。另外对没有函数可以修改已发布的服务参数问题,设想可以通过重复发布服务覆盖来实现需求,但是暂时还没有尝试。
3.切片缓存功能还没添加。