MapImageSharingDraft

摘要

MapImageSharingDraft 类允许您为地图图像图层创建服务定义草稿文件 (.sddraft),该文件将向 ArcGIS Enterprise 复制所有数据或引用注册数据。

说明

要创建 MapImageSharingDraft 对象,可使用 Map 对象的 getWebLayerSharingDraft 方法并将 service_type 参数设置为 MAP_IMAGE。 随后即可通过设置服务级别属性和元数据属性来配置 MapImageSharingDraft 对象。 可以使用 federatedServerUrl 属性以指定将 web 图层发布到的联合服务器。

注:

如果未设置元数据属性(creditsdescriptionsummarytagsuseLimitations)或其具有空字符串,则 Web 图层项目将从地图或图层中获取元数据,具体取决于共享的内容。 有关 Web 图层如何获取元数据的详细信息,请参阅 Web 图层元数据

配置 MapImageSharingDraft 对象后,可以使用 exportToSDDraft 方法将其保存到服务定义草稿文件 (.sddraft)。 然后,可以使用过渡服务上传服务定义工具将其过渡并共享到 ArcGIS Enterprise。 有关详细信息,请参阅 arcpy.sharing 简介

代码示例可用于以下用途:

属性

属性说明数据类型
checkUniqueIDAssignment
(可读写)

一个布尔值,指示是否分析地图以确认启用了地图属性中的允许分配唯一数字 ID 以共享 web 图层选项。 有关详细信息,请参阅分配图层 ID

Boolean
copyDataToServer
(可读写)

用于指示地图中的数据是否复制到服务器的布尔值。 值为 True 时,将复制地图中的所有数据 - 包括在联合服务器中注册的数据。 值为 FalsFalse 时,将仅复制未在联合服务器中注册的数据 - 服务将引用已在联合服务器中注册的数据。

Boolean
credits
(可读写)

用于表示制作者名单的字符串。

String
description
(可读写)

用于表示描述的字符串。

String
federatedServerUrl
(可读写)

用于表示 ArcGIS Enterprise 门户联合服务器 URL 的字符串。

提示:

联合服务器 URL 也可以用于上传服务定义工具中的 in_server 参数。 以下代码示例对此进行了演示。

String
offline
(可读写)

决定是否使用门户连接的布尔值。 如果将 offline 设置为 False,则您必须登录门户,同时向 federatedServerUrl 属性提供 ArcGIS Enterprise 门户联合服务器 URL,从而使用 exportToSDDraft 函数创建服务定义草稿文件 (.sddraft)。 如果将 offline 设置为 True,则可以在不登录门户、不填充 federatedServerUrl 属性的情况下创建服务定义草稿文件。

Boolean
offlineTarget
(可读写)

此字符串用于确定将服务定义发布到的目标服务器版本。 指定一个版本可确保服务定义包含与服务器兼容的内容。 仅在 offline 设置为 True 时支持此属性。

  • ENTERPRISE_10x - 内容将与 ArcGIS Enterprise 10.9.1 或更早版本兼容。 这是默认设置。
  • ENTERPRISE_11 - 内容将与 ArcGIS Enterprise 11.0 或更高版本兼容。
String
overwriteExistingService
(可读写)

决定是否覆盖现有 web 图层的布尔值。

Boolean
portalFolder
(可读写)

表示要将 Web 图层发布到的现有门户文件夹的名称的字符串。 默认文件夹是“我的内容”中的根文件夹。

String
serverFolder
(可读写)

用于表示要将服务发布到的服务器文件夹名称的字符串。 默认文件夹是联合服务器的根文件夹。

String
serverType
(只读)

返回一个字符串,以表示根据地图类中的 getWebLayerSharingDraft 函数创建共享草稿时指定的服务器类型。 从 MapImageSharingDraftserverType 中返回的唯一可能的值为 FEDERATED_SERVERFEDERATED_SERVERserverType 表示支持共享至 ArcGIS Enterprise 门户联合服务器。

String
serviceName
(可读写)

用于表示 web 图层名称的字符串。 用户可以看到该名称并使用该名称来识别服务。 名称只能包含字母数字字符和下划线。 不允许使用空格或特殊字符。 名称不能超过 120 个字符。

String
summary
(可读写)

用于表示摘要的字符串。

String
tags
(可读写)

用于表示标签的字符串。 可以添加多个标签,标签之间用逗号或分号进行分隔。

String
useLimitations
(可读写)

用于表示使用限制的字符串。

String

方法概述

方法说明
exportToSDDraft (out_sddraft)

MapImageSharingDraft 转换为服务定义草稿 (.sddraft) 文件。

方法

exportToSDDraft (out_sddraft)
参数说明数据类型
out_sddraft

A string that represents the path and file name for the output service definition draft (.sddraft) file.

String

MapImageSharingDraft 配置完成后,即可将其作为服务定义草稿 (.sddraft) 文件进行保存。 随后即可使用过渡服务上传服务定义工具将其过渡和共享给 ArcGIS Enterprise 门户联合服务器。

代码示例

将地图图像图层发布到门户文件夹

以下脚本将为地图创建地图图像图层服务定义草稿文件 (.sddraft),并设置元数据属性。 地图图像图层将发布到 ArcGIS Enterprise 中的文件夹并与所有人(公共)共享。 门户信息可从 SignInToPortal 函数中获得。

import arcpy
import os
import xml.dom.minidom as DOM

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft and set metadata, portal folder, and server folder properties
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
sddraft.credits = "These are credits"
sddraft.description = "This is description"
sddraft.summary = "This is summary"
sddraft.tags = "tag1, tag2"
sddraft.useLimitations = "These are use limitations"
sddraft.portalFolder = "my folder name"
sddraft.serverFolder = "MyServerFolder"

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Read the .sddraft file
docs = DOM.parse(sddraft_output_filename)
key_list = docs.getElementsByTagName('Key')
value_list = docs.getElementsByTagName('Value')

# Change following to "true" to share
SharetoOrganization = "false"
SharetoEveryone = "true"
SharetoGroup = "false"
# If SharetoGroup is set to "true", uncomment line below and provide group IDs
GroupID = ""    # GroupID = "f07fab920d71339cb7b1291e3059b7a8, e0fb8fff410b1d7bae1992700567f54a"

# Each key has a corresponding value. In all the cases value of key_list[i] is value_list[i]
for i in range(key_list.length):
    if key_list[i].firstChild.nodeValue == "PackageUnderMyOrg":
        value_list[i].firstChild.nodeValue = SharetoOrganization
    if key_list[i].firstChild.nodeValue == "PackageIsPublic":
        value_list[i].firstChild.nodeValue = SharetoEveryone
    if key_list[i].firstChild.nodeValue == "PackageShareGroups":
        value_list[i].firstChild.nodeValue = SharetoGroup
    if SharetoGroup == "true" and key_list[i].firstChild.nodeValue == "PackageGroupIDs":
        value_list[i].firstChild.nodeValue = GroupID

# Write to the .sddraft file
f = open(sddraft_output_filename, 'w')
docs.writexml(f)
f.close()

# Stage Service
print("Start Staging")
arcpy.server.StageService(sddraft_output_filename, sd_output_filename)

# Share to portal
print("Start Uploading")
arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

print("Finish Publishing")
覆盖地图图像图层

以下脚本将覆盖地图图像图层。 如果服务名称已存在,则将覆盖该服务。 否则,将创建新服务。

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft and set overwrite property
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
sddraft.overwriteExistingService = True

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Stage Service
print("Start Staging")
arcpy.server.StageService(sddraft_output_filename, sd_output_filename)

# Share to portal
print("Start Uploading")
arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

print("Finish Publishing")
发布具有相关联要素图层的地图图像图层

以下脚本可以创建地图图像图层服务定义草稿 (.sddraft) 文件。 它可通过使用 xml.dom.minidom 标准 Python 库,修改服务定义草稿文件,从而包含要素图层并设置要素图层和地图图像图层。 然后,会将修改后的服务定义草稿文件过渡并发布到 ArcGIS Enterprise 门户联合服务器。 必须已在服务器上注册数据存储,才能引用数据。

import arcpy
import os
import xml.dom.minidom as DOM

def configure_featureserver_capabilities(sddraftPath, capabilities):
    """Function to configure FeatureServer properties"""
    # Read the .sddraft file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the additional layers and capabilities are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == "FeatureServer":
            extension = typeName.parentNode
            for extElement in extension.childNodes:
                if extElement.tagName == 'Info':
                    for propSet in extElement.childNodes:
                        for prop in propSet.childNodes:
                            for prop1 in prop.childNodes:
                                if prop1.tagName == "Key":
                                    if prop1.firstChild.data == 'WebCapabilities':
                                        if prop1.nextSibling.hasChildNodes():
                                            prop1.nextSibling.firstChild.data = capabilities
                                        else:
                                            txt = doc.createTextNode(capabilities)
                                            prop1.nextSibling.appendChild(txt)
    # Write to the .sddraft file
    f = open(sddraftPath, 'w')
    doc.writexml(f)
    f.close()

def configure_mapserver_capabilities(sddraftPath, capabilities):
    """Function to configure MapServer properties"""
    # Read the .sddraft file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the additional layers and capabilities are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == "MapServer":
            extension = typeName.parentNode
            for extElement in extension.childNodes:
                if extElement.tagName == 'Definition':
                    for propArray in extElement.childNodes:
                        if propArray.tagName == 'Info':
                            for propSet in propArray.childNodes:
                                for prop in propSet.childNodes:
                                    for prop1 in prop.childNodes:
                                        if prop1.tagName == "Key":
                                            if prop1.firstChild.data == 'WebCapabilities':
                                                if prop1.nextSibling.hasChildNodes():
                                                    prop1.nextSibling.firstChild.data = capabilities
                                                else:
                                                    txt = doc.createTextNode(capabilities)
                                                    prop1.nextSibling.appendChild(txt)
    # Write to the .sddraft file
    f = open(sddraftPath, 'w')
    doc.writexml(f)
    f.close()

if __name__ == "__main__":
    # Sign in to portal
    arcpy.SignInToPortal("https://portal.domain.com/webadaptor", "MyUserName", "MyPassword")

    # Set output file names
    outdir = r"C:\Project\Output"
    service_name = "MapImageSharingDraftExample"
    sddraft_filename = service_name + ".sddraft"
    sddraft_output_filename = os.path.join(outdir, sddraft_filename)
    sd_filename = service_name + ".sd"
    sd_output_filename = os.path.join(outdir, sd_filename)

    # Reference map to publish
    aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
    m = aprx.listMaps('World')[0]

    # Create MapImageSharingDraft and set copyDataToServer property to False to reference registered data
    server_type = "FEDERATED_SERVER"
    federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
    sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
    sddraft.federatedServerUrl = federated_server_url
    sddraft.copyDataToServer = False

    # Create Service Definition Draft file
    sddraft.exportToSDDraft(sddraft_output_filename)

    """Modify the .sddraft file to include a feature layer and set map image layer and feature layer properties"""

    # Modify the .sddraft file to change map image layer properties
    # Defaults are Map,Query,Data
    # Comment out the line below if you do not want to modify map image layer properties
    configure_mapserver_capabilities(sddraft_output_filename, "Map,Data")

    # Modify the .sddraft file to include a feature layer
    # Read the file
    doc = DOM.parse(sddraft_output_filename)

    # Find all elements named TypeName
    # This is where the extensions are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == "FeatureServer":
            extension = typeName.parentNode
            for extElement in extension.childNodes:
                # Include a feature layer
                if extElement.tagName == 'Enabled':
                    extElement.firstChild.data = 'true'

    # Write to new .sddraft file
    sddraft_mod_xml = service_name + '_mod_xml' + '.sddraft'
    sddraft_mod_xml_file = os.path.join(outdir, sddraft_mod_xml)
    f = open(sddraft_mod_xml_file, 'w')
    doc.writexml(f)
    f.close()

    # Modify the .sddraft file to change feature layer properties
    # Defaults are Query,Create,Update,Delete,Uploads,Editing
    # Comment out the line below if you don't want to modify feature layer properties
    configure_featureserver_capabilities(sddraft_mod_xml_file, "Create,Sync,Query")

    # Stage Service
    print("Start Staging")
    arcpy.server.StageService(sddraft_mod_xml_file, sd_output_filename)

    # Share to portal
    print("Start Uploading")
    arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

    print("Finish Publishing")
发布缓存地图图像图层。

以下脚本通过调用管理地图服务器缓存切片工具以创建地图服务缓存切片,来发布缓存地图图像图层。

import arcpy
import os
import xml.dom.minidom as DOM

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

"""Modify the .sddraft to enable caching"""
# Read the file
doc = DOM.parse(sddraft_output_filename)

configProps = doc.getElementsByTagName('ConfigurationProperties')[0]
propArray = configProps.firstChild
propSets = propArray.childNodes
for propSet in propSets:
    keyValues = propSet.childNodes
    for keyValue in keyValues:
        if keyValue.tagName == 'Key':
            if keyValue.firstChild.data == "isCached":
                keyValue.nextSibling.firstChild.data = "true"

# Write to a new .sddraft file
sddraft_mod_xml = service_name + '_mod_xml' + '.sddraft'
sddraft_mod_xml_file = os.path.join(outdir, sddraft_mod_xml)
f = open(sddraft_mod_xml_file, 'w')
doc.writexml(f)
f.close()

try:
    # Stage Service
    print("Start Staging")
    arcpy.server.StageService(sddraft_mod_xml_file, sd_output_filename)
    warnings = arcpy.GetMessages(1)
    print(warnings)

    # Share to portal
    print("Start Uploading")
    arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)
    print("Finish Publishing")

    # Manage Map server Cache Tiles
    # For cache, use multiple scales separated by semicolon (;)
    # For example, "591657527.591555;295828763.795777"
    arcpy.server.ManageMapServerCacheTiles(federated_server_url + "/" + "rest/services" + "/" + service_name + "/" + "MapServer", "591657527.591555", "RECREATE_ALL_TILES")
except Exception as stage_exception:
    print("Analyzer errors encountered - {}".format(str(stage_exception)))

except arcpy.ExecuteError:
    print(arcpy.GetMessages(2))
发布从现有缓存中提取的地图图像图层

以下脚本可以创建地图图像图层服务定义草稿 (.sddraft) 文件。 然后该脚本可通过使用 xml.dom.minidom 标准 Python 库,修改服务定义草稿文件,从而使用现有缓存绘制服务。 然后,会将修改后的服务定义草稿文件过渡并发布到 ArcGIS Enterprise 门户联合服务器。

import arcpy
import os
import xml.dom.minidom as DOM

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

"""Modify the .sddraft file to keep existing cache"""
# Read the file
doc = DOM.parse(sddraft_output_filename)
# Turn off caching
configProps = doc.getElementsByTagName('ConfigurationProperties')[0]
propArray = configProps.firstChild
propSets = propArray.childNodes
for propSet in propSets:
    keyValues = propSet.childNodes
    for keyValue in keyValues:
        if keyValue.tagName == 'Key':
            if keyValue.firstChild.data == "isCached":
                keyValue.nextSibling.firstChild.data = "false"

# Use existing cache
configProps = doc.getElementsByTagName('KeepExistingMapCache')[0]
configProps.firstChild.data = "true"

# Write to a new .sddraft file
sddraft_mod_xml = service_name + '_mod_xml' + '.sddraft'
sddraft_mod_xml_file = os.path.join(outdir, sddraft_mod_xml)
f = open(sddraft_mod_xml_file, 'w')
doc.writexml(f)
f.close()

# Stage Service
print("Start Staging")
arcpy.server.StageService(sddraft_mod_xml_file, sd_output_filename)

# Share to portal
print("Start Uploading")
arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

print("Finish Publishing")
分析并注册数据存储

以下脚本可以为地图图像图层创建服务定义草稿 (.sddraft) 文件。 在过渡期间,将对服务定义草稿文件进行分析。 如果返回分析器 24011,警告未将数据源注册到服务器,则将使用 ArcGIS API for Python 中的 arcgis.gis 模块注册数据存储。

import arcpy
import os

# Add a data store item on the portal and register it with a federated server
def register_datastore_item(portal_url, username, password, sde_conn_file, data_store_name, federated_server_url):
    from arcgis.gis import GIS

    tags = "tag1, tag2"
    description = "Data Store Item created from ArcGIS API for Python"
    federated_server_url = federated_server_url.rstrip('/')
    federated_server_adminurl = federated_server_url + "/admin"

    # Connect to your portal using ArcGIS API for Python
    gis = GIS(url=portal_url, username=username, password=password)

    # Get federated server ID
    server_list = gis.servers["servers"]
    fedserver_dict = [srvr for srvr in server_list if srvr["url"] == federated_server_url][0]
    fedserver_id = fedserver_dict["id"]
    print("Server id: " + fedserver_id)

    # Get federated server's DatastoreManager object
    fedserver = [srvr for srvr in gis.admin.servers.list() if srvr.url == federated_server_adminurl][0]
    fedserver_dsmgr = fedserver.datastores

    # Create a connection string from .sde file connection
    conn_file = sde_conn_file
    conn_string = fedserver_dsmgr.generate_connection_string(conn_file)
    print("Connection string generated")

    # Create a dictionary for data store configuration
    ds_config = {"type": "egdb",
                 "path": "/enterpriseDatabases/" + data_store_name,
                 "info": {"isManaged": "false",
                          "dataStoreConnectionType": "shared",
                          "connectionString": conn_string}
                 }

    # Create a dictionary for the item properties
    item_properties = {"title": data_store_name,
                       "type": "Data Store",
                       "tags": tags,
                       "snippet": description}

    # Add the data store item to the portal
    ds_item = gis.content.add(item_properties=item_properties,
                              text=ds_config)
    print("Data store item added")

    # Get portal data store
    portal_ds = gis.datastore
    
    # Validate the data store item can be connected to before registering
    validation_state = portal_ds.validate(server_id=fedserver_id,
                                          item=ds_item)
    print("Data store item validated")

    # Register the database with the federated server
    portal_ds.register(item=ds_item,
                       server_id=fedserver_id,
                       bind=False)
    print("Data store item registered to server")
    return True


if __name__ == "__main__":
    arcpy.env.overwriteOutput = True
    portal_url = "https://portal.domain.com/webadaptor"
    username = "MyUserName"
    password = "MyPassword"

    # Sign in to portal
    arcpy.SignInToPortal(portal_url, username, password)

    # Set output file names
    outdir = r"C:\Project\Output"
    service_name = "registerdatastore_example"
    sddraft_filename = service_name + ".sddraft"
    sddraft_output_filename = os.path.join(outdir, sddraft_filename)
    sd_filename = service_name + ".sd"
    sd_output_filename = os.path.join(outdir, sd_filename)
    sde_conn_file = r"C:\Project\db_conn.sde"
    data_store_name = "PortalDSItem"

    # Reference map to publish
    aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
    m = aprx.listMaps('Map')[0]

    # Create MapImageSharingDraft and set copyDataToServer property to False to reference registered data
    server_type = "FEDERATED_SERVER"
    federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
    sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
    sddraft.federatedServerUrl = federated_server_url
    sddraft.copyDataToServer = False

    # Create Service Definition Draft file
    sddraft.exportToSDDraft(sddraft_output_filename)

    # Stage the service and analyze the .sddraft file for registered data store
    # Continue publishing only if data store is registered
    print("Start Staging")
    stage_service = True
    while stage_service:
        arcpy.server.StageService(sddraft_output_filename, sd_output_filename)
        # Get analyzer warnings to check if data store is registered
        warnings = arcpy.GetMessages(1)
        print(warnings)
        # If data store is not registered
        if "24011" in warnings:
            # Register data store
            register_res = register_datastore_item(portal_url, username, password, sde_conn_file, data_store_name,
                                                   federated_server_url)
            if not register_res:
                print("Unable to register the data store, skipping upload")
                exit()
            # Stage the service again
            stage_service = True
        else:
            stage_service = False

    # Share to portal
    print("Start Uploading")
    arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

    print("Finish Publishing")
设置时区并配置池化

以下脚本可以创建地图图像图层服务定义草稿 (.sddraft) 文件。 它为带有日期字段的图层设置时区,并通过使用 xml.etree.ElementTreexml.dom.minidom 标准 Python 库修改服务定义草稿文件来配置服务实例设置。 然后,会将修改后的服务定义草稿文件过渡并发布到 ArcGIS Enterprise 门户联合服务器。 必须已在服务器上注册数据存储,才能引用数据。

import arcpy
import os
import xml.dom.minidom as DOM
import codecs
import xml.etree.ElementTree as ET

def enable_extensions(sddraftPath, soe):
"""Function to enable extensions"""
    # Read the .sddraft file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the additional layers and capabilities are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == soe:
            extension = typeName.parentNode
            for extElement in extension.childNodes:
                # Include a feature layer
                if extElement.tagName == 'Enabled':
                    extElement.firstChild.data = 'true'

    # Write to the .sddraft file
    f = open(sddraftPath, 'w')
    doc.writexml(f)
    f.close()

# soe = extension for which properties must be added
def enable_configproperties(sddraftPath, soe, property_set):
"""Function to configure extension properties"""
    # Read the file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the extensions are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == soe:
            extension = typeName.parentNode
            # prp = extension.childNodes.getElementsByTagNameNS('PropertyArray')
            for extElement in extension.childNodes:
                if extElement.tagName == 'Definition':
                    for definition in extElement.childNodes:
                        if definition.tagName == 'ConfigurationProperties':
                            for config_prop in definition.childNodes:
                                if config_prop.tagName == 'PropertyArray':
                                    for prop in property_set:
                                        prop_set = doc.createElement("PropertySetProperty")
                                        attr = doc.createAttribute("xsi:type")
                                        attr.value = "typens:PropertySetProperty"
                                        prop_set.setAttributeNode(attr)

                                        prop_key = doc.createElement("Key")
                                        txt = doc.createTextNode(prop["key"])
                                        prop_key.appendChild(txt)
                                        prop_set.appendChild(prop_key)

                                        prop_value = doc.createElement("Value")
                                        attr = doc.createAttribute("xsi:type")
                                        attr.value = "xs:string"
                                        prop_value.setAttributeNode(attr)
                                        txt = doc.createTextNode(prop["value"])
                                        prop_value.appendChild(txt)
                                        prop_set.appendChild(prop_value)

                                        config_prop.appendChild(prop_set)
    # Write to the .sddraft file
    f = open(sddraftPath, 'w')
    doc.writexml(f)
    f.close()

if __name__ == "__main__":
    # Sign in to portal
    arcpy.SignInToPortal("https://portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

    # Set output file names
    outdir = r"C:\Project\Output"
    service_name = "MapImageSharingDraftExample"
    sddraft_filename = service_name + ".sddraft"
    sddraft_output_filename = os.path.join(outdir, sddraft_filename)
    sd_filename = service_name + ".sd"
    sd_output_filename = os.path.join(outdir, sd_filename)

    # Reference map to publish
    aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
    m = aprx.listMaps('World')[0]

    # Create MapImageSharingDraft and set copyDataToServer property to False to reference registered data
    server_type = "FEDERATED_SERVER"
    federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
    sddraft = m.getWebLayerSharingDraft(server_type, 'MAP_IMAGE', service_name)
    sddraft.federatedServerUrl = federated_server_url
    sddraft.copyDataToServer = False
    sddraft.exportToSDDraft(sddraft_output_filename)

    # Set time zone to UTC
    property_set = [{
        "key": "dateFieldsRespectsDayLightSavingTime",
        "value": "true"
    },
        {
            "key": "dateFieldsTimezoneID",
            "value": "UTC"
        }]
    enable_configproperties(sddraft_output_filename, soe="MapServer", property_set=property_set)

    # Enable extensions on map server
    enable_extensions(sddraft_output_filename, "FeatureServer")
    # enable_extensions(sddraft_output_filename, "VersionManagementServer")
    # enable_extensions(sddraft_output_filename, "LRServer")

    # Configure pooling options
    doc = DOM.parse(sddraft_output_filename)
    def_childnodes = doc.getElementsByTagName("Definition")[0].childNodes
    for def_node in def_childnodes:
        if def_node.nodeName == "Props":
            for node in def_node.childNodes[0].childNodes:
                # Change the provider to modify instance type
                # provider='DMaps' for shared or 'ArcObjects11' for dedicated
                if node.firstChild.firstChild.data == 'provider':
                    node.lastChild.firstChild.data = 'ArcObjects11'
                elif node.firstChild.firstChild.data == 'MinInstances':
                    node.lastChild.firstChild.data = '0'
                elif node.firstChild.firstChild.data == 'MaxInstances':
                    node.lastChild.firstChild.data = '2'

    # Write to the .sddraft file
    f = open(sddraft_output_filename, 'w')
    doc.writexml(f)
    f.close()

    # Stage Service
    print("Start Staging")
    arcpy.server.StageService(sddraft_output_filename, sd_output_filename)

    # Share to portal
    print("Start Uploading")
    arcpy.server.UploadServiceDefinition(sd_output_filename, federated_server_url)

    print("Finish Publishing")
发布图层和表

以下脚本可将图层和表作为地图图像图层发布至 ArcGIS Enterprise 门户。

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference layers to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
selected_layer = m.listLayers()[0]
selected_table = m.listTables()[0]

# Create MapImageSharingDraft
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name, [selected_layer, selected_table])
sddraft.federatedServerUrl = federated_server_url

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Stage Service
print("Start Staging")
arcpy.server.StageService(sddraft_output_filename, sd_output_filename)

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
创建并发布离线服务定义

以下脚本将为目标服务器版本创建离线服务定义,并将其发布为地图图像图层。

import arcpy
import os

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft and set offline and offlineTarget properties
server_type = "FEDERATED_SERVER"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.offline = True
# Set offlineTarget property to "ENTERPRISE_11" for ArcGIS Enterprise 11.0 or later
# The default is ArcGIS Enterprise 10.9.1 or earlier
sddraft.offlineTarget = "ENTERPRISE_10x"

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Stage Service
print("Start Staging")
arcpy.server.StageService(sddraft_output_filename, sd_output_filename)

# Sign in to portal to upload and publish
arcpy.SignInToPortal("https://portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Share to portal
print("Start Uploading")
arcpy.server.UploadServiceDefinition(sd_output_filename, "https://MyFederatedServer.domain.com/serverWebadaptor")

print("Finish Publishing")
分析以确认地图已设置为允许分配唯一数字 ID

以下脚本将创建启用了 checkUniqueIDAssignment 属性的地图图像图层服务定义草案文件 (.sddraft)。 在过渡期间,将对服务定义草稿文件进行分析。 如果地图未设置为允许分配用于共享 web 图层的唯一数字 ID,则会返回分析器错误 00374 并打印一条消息。 有关详细信息,请参阅分配图层 ID

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://portal.domain.com/webadaptor",
                     "MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]

# Create MapImageSharingDraft and set the check unique ID assignment property
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.domain.com/serverWebadaptor"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
sddraft.checkUniqueIDAssignment = True

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

try:
    # Stage Service
    print("Start Staging")
    arcpy.server.StageService(sddraft_output_filename, sd_output_filename)
    # Share to portal
    print("Start Uploading")
    arcpy.server.UploadServiceDefinition(sd_output_filename, server_type)

    print("Finish Publishing")
except Exception as stage_exception:
    if "00374" in str(stage_exception):
        print("The map is not set to allow assignment of unique IDs")
    print("Analyzer errors encountered - {}".format(str(stage_exception)))

except arcpy.ExecuteError:
    print(arcpy.GetMessages(2))

相关主题