Context:
I am extracting data from a S123 survey to pass to an external application (an ERP system). All data ends up in an HTML container within the external application. The architecture requires using the arcgis modules of the Python API. AGOL only client. Part of the data extract includes taking the coordinates of each feature, creating a ‘postage stamp’ image of the location using a OSM basemap, then passing that jpg on for further processing. A webmap is created from the S123 feature layer and the arcgis export_map() function used to create the JPG. This is my first significant coding using the Python API and AGOL, though I have some limited experience with arcpy and the REST API within an on-prem, server based environment.
Problem:
I am able to access the feature data within the S123 instance, but the export_map() fails.
“Error executing tool. Export Web Map Task : Failed to create layer from service at https://<operational layer URL>/FeatureServer/0”
I have some indications it may be an authentication issue as the code works with a public webmap/feature layer I used for dev/testing. I can access the feature class/features in S123 with no issues, but not this export_map function.
Issues researched and addressed:
I feel like I must be missing some detail in either the JSON setup or the code context (e.g. authentication?). Maybe there is something off in the Survery123 setup? This was created by someone else as a test target for the overall development and is new to all of us. Or is the problem with our AGOL account setup for the printing service?
Any suggestions on how to proceed on finding the cause of this error?
Code for the map export (to be placed within a function):
import json
from arcgis.gis import GIS
from arcgis.mapping import export_map
gis = GIS(PORTAL_URL, id, pw)
webmap_item = gis.content.get(WEB_MAP_ID)
# Get web map definition
webmap_json = webmap_item.get_data()
# Add needed components to web map definition per listed article (POINT is a geometry object passed in)
webmap_json['mapOptions'] = {
"extent" : {
"xmin": POINT['x'] + .0005,
"ymin": POINT['y'] - .0003,
"xmax": POINT['x'] - .0005,
"ymax": POINT['y'] + .0003,
"spatialReference": {"latestWkid": 4326, "wkid": 4326}
},
"spatialReference" : {"wkid" : 4326}
}
webmap_json['exportOptions'] = { "dpi" : 96,
"outputSize" : [300, 200]
}
# Filter for just the one point
defExpression = 'OBJECTID={}'.format(OBJECTID)
webmap_json['operationalLayers'][0]['layerDefinition'] = {'definitionExpression': defExpression}
# Add token per listed article. The getToken() function uses the same credentials internally as the GIS() call.
mapToken = getToken()
webmap_json['operationalLayers'][0]['token'] = mapToken
# Cannot find the article link, but had one post indicate to flatten the json structure, hence this line. Seemed to be related to a 10.2 bug, since fixed, not AGOL, but tried with and without this just in case.
webmap_json = json.dumps(webmap_json)
out = export_map(web_map_as_json=webmap_json, format='JPG', layout_template='MAP_ONLY', gis=gis)
Code for the S123 data extract, which works fine. Provided as reference. Same GIS object being passed between the functions within the module.
def get_s123data(shipID, gis, surveyInfo):
"""
Query the S123 feature layer and return data if available.
Downloads the image attachments to local storage.
Else return None.
"""
fdmItem = gis.content.get(surveyInfo['s123id'])
if fdmItem:
fdmLayers = fdmItem.layers # the layers in the feature class item
fdmDataLayer = fdmLayers[surveyInfo['layer_num']]
fdmFeature = query_S123(fdmDataLayer, surveyInfo['lookupField'], shipID)
if fdmFeature:
featureID = fdmFeature.attributes['objectid']
fdmAttachments = get_downloads(fdmDataLayer, featureID)
else:
fdmFeature = None
fdmAttachments = None
else:
logger.error('No content for Survey123 ID {}'.format(surveyInfo['s123id']))
raise SysAccessError('No Survey123 ID present')
return fdmFeature, fdmAttachments
As a bump on this, we never could get the export_map() to work with the Survey123 operational layer in the web map. The work around (hokey) was to create a dummy web map with an empty feature layer, both set to public access. Feed the points into the layer, do the export, delete the points. Same code for the export pieces.