Hi all,
I was wondering how modify service defition draft for cache level before uploading to server.
Following sample 6 of help page (CreateMapSDDraft—Help | ArcGIS Desktop) I was able to insert some further steps from the original code:
Here is my code
import arcpy
from arcpy import env
import xml.dom.minidom as DOM
import os, sys, time, datetime, traceback, string
pathFile = arcpy.GetParameterAsText(0)
server = arcpy.GetParameterAsText(1)
serviceFolder = arcpy.GetParameterAsText(2)
serviceName = arcpy.GetParameterAsText(3)
summary = arcpy.GetParameterAsText(4)
tags = arcpy.GetParameterAsText(5)
# define local variables
arcpy.env.overwriteOutput = True
wrkspc = arcpy.env.scratchFolder
connectionFolder = r"C:\Users\<User>\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog"
mapServer = os.path.join(connectionFolder, server, serviceName + '.MapServer')
connectionFile = os.path.join(connectionFolder, server +'.ags')
# create service definition draft
copy_data_to_server = True
sddraft = os.path.join(wrkspc, serviceName + '.sddraft')
sd = os.path.join(wrkspc, serviceName + '.sd')
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, serviceName, 'ARCGIS_SERVER', connectionFile, copy_data_to_server, serviceFolder, summary, tags)
# The Server Object Extension (SOE) to disable.
soe = 'KmlServer'
# Read the sddraft xml.
doc = DOM.parse(sddraft)
# Find all elements named TypeName. This is where the server object extension (SOE) names are defined.
typeNames = doc.getElementsByTagName('TypeName')
for typeName in typeNames:
# Get the TypeName we want to disable.
if typeName.firstChild.data == soe:
extension = typeName.parentNode
for extElement in extension.childNodes:
# Disabled SOE.
if extElement.tagName == 'Enabled':
extElement.firstChild.data = 'false'
# turn on caching in the configuration properties
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":
# turn on caching
keyValue.nextSibling.firstChild.data = "true"
for keyValue in keyValues:
if keyValue.tagName == 'Key':
if keyValue.firstChild.data == "cacheOnDemand":
# turn on caching on demand
keyValue.nextSibling.firstChild.data = "true"
for keyValue in keyValues:
if keyValue.tagName == 'Key':
if keyValue.firstChild.data == "minScale":
# set min scale
keyValue.nextSibling.firstChild.data = "591657527,591555"
for keyValue in keyValues:
if keyValue.tagName == 'Key':
if keyValue.firstChild.data == "maxScale":
# set max scale
keyValue.nextSibling.firstChild.data = "1128,497176"
# Output to a new sddraft.
outXml = os.path.join(wrkspc, serviceName + 'Update.sddraft')
f = open(outXml, 'w')
doc.writexml( f )
f.close()
sddraft = outXml
# 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, connectionFile)
else:
# if the sddraft analysis contained errors, display them
print analysis['errors']
But this is the result
Anyone can help me?
Stefano
Solved! Go to Solution.
Solved! The problem is the decimal separator!
Syntax is right, but in italian decimal mark is comma not point, so this is the correct string for min scale
keyValue.nextSibling.firstChild.data = "591657527.591555"
And the same for max scale...
Stefano
What if you were to create one SD draft with caching on, and another with it off? Then you can compare the two and figure out what you're missing. Another approach, (arguably easier), is to use GP tools once the service is created:
Create Map Server Cache—Help | ArcGIS Desktop
Manage Map Server Cache Tiles—Help | ArcGIS Desktop
and optionally
Thanks Jonathan,
actually I had already thought to follow the second road, adding create e manage cache (with XML tile scheme compatible with ESRI basemaps) after uploading service definition file. Maybe not very efficient, but working.
I'm trying to do something similar, using GP tools to create/manage the cache once the service has been created. However, none of the GP tools give me the ability to set the "Create tiles on demand" property... Is this something that can only be done by altering the SD draft prior to service creation?
Thanks,
Jason
You can edit that property after the service is created by going into the service information > Caching tab > Create tiles on demand:
If you're interested in doing this programatically, you'll likely need to update the cacheOnDemand property under the properties within the JSON for the service:
...
"properties": {
"maxDomainCodeCount": "25000",
"cacheDir": "C:\\arcgis\\arcgisserver\\directories\\arcgiscache",
"maxImageWidth": "4096",
"maxRecordCount": "1000",
"antialiasingMode": "None",
"enableDynamicLayers": "true",
"dynamicDataWorkspaces": "",
"isCached": "true",
"virtualOutputDir": "/rest/directories/arcgisoutput",
"exportTilesAllowed": "false",
"maxImageHeight": "4096",
"cacheOnDemand": "false",
"cacheExtent": "current",
"minScale": "591657527.591555",
"schemaLockingEnabled": "true",
"useLocalCacheDir": "false",
"outputDir": "C:\\arcgis\\arcgisserver\\directories\\arcgisoutput",
"maxScale": "72223.819285999998",
"filePath": "C:\\arcgis\\arcgisserver\\directories\\arcgissystem\\arcgisinput\\USA_Base_Map.MapServer\\extracted\\v101\\USA Base Map.msd",
"supportedImageReturnTypes": "URL",
"clientCachingAllowed": "true",
"textAntialiasingMode": "Force",
"maxExportTilesCount": "100000",
"ignoreCache": "false",
"tilingScheme": "0",
"maxBufferCount": "100",
"disableIdentifyRelates": "false",
"virtualCacheDir": "/rest/directories/arcgiscache"
...
Yes, my goal is to do this programatically through python. I was hoping I could find something in arcpy that could handle this for me, but it looks like I'll have to alter the json after the service has been published, and the map server cache has been created.
Thanks for pointing me in the right direction.
If you want to do it in the SDDraft, use the syntax in the original post to set cacheOnDemand to true:
Ex.
...
for keyValue in keyValues:
if keyValue.tagName == 'Key':
if keyValue.firstChild.data == "cacheOnDemand":
# turn on caching on demand
keyValue.nextSibling.firstChild.data = "true"
...
Solved! The problem is the decimal separator!
Syntax is right, but in italian decimal mark is comma not point, so this is the correct string for min scale
keyValue.nextSibling.firstChild.data = "591657527.591555"
And the same for max scale...
Stefano