Hello,
I have an existing feature layer published from a csv file that I'm trying to add to a webmap. I have the following code that runs without errors but when I go back into the GUI (through ArcGIS online) the layer doesn't show up as having been added.
from arcgis.gis import GIS
from arcgis.mapping import WebMap
from arcgis.features import FeatureLayer
from pprint import pprint
print("Logging in...")
gis = GIS("https://fotnf.maps.arcgis.com/", "friendsofthetonto", "XXXXXXXX")
print(f"Connected to {gis.properties.portalHostname} as {gis.users.me.username}")
webmap_item = gis.content.get('e1405425e52d43689cfdaecd43e0239d')
webmap = WebMap(webmap_item)
csv_item2 = gis.content.get('ec6e29fe17a44512887d761f5e3524d6')
csv_layer2 = FeatureLayer(csv_item2.url)
webmap.add_layer(csv_item2)
webmap_item.update(data=webmap)
Solved! Go to Solution.
I was eventually able to get this working. Here's the code that we ended up with to publish and add the csv layer to an existing webmap:
def update(_args):
data_layer_definition = (
get_polys_layout_default()
if _args.is_polys
else get_points_layout_default()
)
popup_config = (
get_polys_popup_config_default()
if _args.is_polys
else get_points_popup_config_default()
)
gis = _args.gis
# UPLOAD CSV
snake_case_random = uuid.uuid1()
points_or_polys_text = "polys" if _args.is_polys else "points"
csv_file_orig = _args.data_path / f"Joined.csv"
csv_file_new = _args.data_path / f"Joined_{snake_case_random}.csv"
shutil.copy(csv_file_orig.resolve(), csv_file_new.resolve())
csv_agol = gis.content.add(
item_properties={
"title": f"Temp CSV {points_or_polys_text} {snake_case_random}",
},
data=csv_file_new.as_posix(),
)
csv_agol.move(f"Oliver")
feature_layer = csv_agol.publish()
# ASSOCIATE CSV WITH WEBMAP
webmap_item = gis.content.get("a752f298d15c4767a34e0b4981245afc")
web_map_definition = webmap_item.get_data()
title = "Points Status Layer"
if _args.is_polys:
title = "Polys Status Layer"
layer_index = None
arcpy.AddMessage("Here 40")
arcpy.AddMessage(len(web_map_definition["operationalLayers"]))
for index, layer in enumerate(web_map_definition["operationalLayers"]):
if layer["title"].startswith(title):
layer_index = index
break
# arcpy.AddMessage("Here 50")
# arcpy.AddMessage(web_map_definition["operationalLayers"][layer_index])
arcpy.AddMessage(f"Layer index: {layer_index}")
arcpy.AddMessage("Here 50")
# arcpy.AddMessage(web_map_definition["operationalLayers"][layer_index]["popupInfo"])
# exit()
if layer_index is None:
# Add the layer since it doesn't already exist.
arcpy.AddMessage("Adding layer")
# Add the feature layer's URL to the web map definition's
# operationalLayers
web_map_definition["operationalLayers"].append(
{
"id": feature_layer.id,
"layerType": "ArcGISFeatureLayer",
"url": feature_layer.url,
"visibility": True,
"layerDefinition": data_layer_definition,
"opacity": 1,
"title": f"{title} {_args.current_day.strftime('%Y-%m-%d')}",
"popupInfo": popup_config,
}
)
else:
# Replace the existing layer
arcpy.AddMessage("Replacing layer")
web_map_definition["operationalLayers"][layer_index][
"id"
] = feature_layer.id
web_map_definition["operationalLayers"][layer_index][
"url"
] = feature_layer.url
# Update the title with the current date
web_map_definition["operationalLayers"][layer_index][
"title"
] = f"{title} {_args.current_day.strftime('%Y-%m-%d')}"
arcpy.AddMessage(web_map_definition["operationalLayers"])
# Add the feature layer's URL to the web map definition's operationalLayers
# Update the web map's definition
webmap_item.update(data=web_map_definition)
arcpy.AddMessage(f"Done")
BTW, this is using version 2.1.0.3 of the arcgis python package.
Creating a FeatureLayer requires the URL to be the full path to the individual layer. I might have a URL like this:
https://maps.co.kendall.il.us/server/rest/services/Hosted/Cemeteries/FeatureServer
But that's the URL for the service. The layer itself is:
https://maps.co.kendall.il.us/server/rest/services/Hosted/Cemeteries/FeatureServer/0
If your service only has a single layer in it, you can access it by using csv_item2.layers[0], which returns a FeatureLayer object, and you can bypass calling the FeatureLayer constructor.
Thanks for the suggestion.
I tried changing the code to the following (passing csv_item2.layers[0] directly into webmap.add_layer()):
from arcgis.gis import GIS
from arcgis.mapping import WebMap
from arcgis.features import FeatureLayer
from pprint import pprint
print("Logging in...")
gis = GIS("https://fotnf.maps.arcgis.com/", "friendsofthetonto", "XXXXXXXX")
print(f"Connected to {gis.properties.portalHostname} as {gis.users.me.username}")
webmap_item = gis.content.get('e1405425e52d43689cfdaecd43e0239d')
webmap = WebMap(webmap_item)
csv_item2 = gis.content.get('ec6e29fe17a44512887d761f5e3524d6')
# csv_layer2 = FeatureLayer(csv_item2.url)
webmap.add_layer(csv_item2.layers[0])
webmap_item.update(data=webmap)
But I'm still getting the same result where the code runs without errors but the new layer doesn't show up.
Here's a screencast of the issue:
https://d.pr/v/RNdZiv
Hi @DonaldPike
If your csv_item2 is a CSV item you will need to publish the CSV Item as a Feature Service first before you can add the Feature Layer from within this Feature Service to a WebMap. (it can aslo be published as a Table Service and added to a WebMap as a Table)
I was eventually able to get this working. Here's the code that we ended up with to publish and add the csv layer to an existing webmap:
def update(_args):
data_layer_definition = (
get_polys_layout_default()
if _args.is_polys
else get_points_layout_default()
)
popup_config = (
get_polys_popup_config_default()
if _args.is_polys
else get_points_popup_config_default()
)
gis = _args.gis
# UPLOAD CSV
snake_case_random = uuid.uuid1()
points_or_polys_text = "polys" if _args.is_polys else "points"
csv_file_orig = _args.data_path / f"Joined.csv"
csv_file_new = _args.data_path / f"Joined_{snake_case_random}.csv"
shutil.copy(csv_file_orig.resolve(), csv_file_new.resolve())
csv_agol = gis.content.add(
item_properties={
"title": f"Temp CSV {points_or_polys_text} {snake_case_random}",
},
data=csv_file_new.as_posix(),
)
csv_agol.move(f"Oliver")
feature_layer = csv_agol.publish()
# ASSOCIATE CSV WITH WEBMAP
webmap_item = gis.content.get("a752f298d15c4767a34e0b4981245afc")
web_map_definition = webmap_item.get_data()
title = "Points Status Layer"
if _args.is_polys:
title = "Polys Status Layer"
layer_index = None
arcpy.AddMessage("Here 40")
arcpy.AddMessage(len(web_map_definition["operationalLayers"]))
for index, layer in enumerate(web_map_definition["operationalLayers"]):
if layer["title"].startswith(title):
layer_index = index
break
# arcpy.AddMessage("Here 50")
# arcpy.AddMessage(web_map_definition["operationalLayers"][layer_index])
arcpy.AddMessage(f"Layer index: {layer_index}")
arcpy.AddMessage("Here 50")
# arcpy.AddMessage(web_map_definition["operationalLayers"][layer_index]["popupInfo"])
# exit()
if layer_index is None:
# Add the layer since it doesn't already exist.
arcpy.AddMessage("Adding layer")
# Add the feature layer's URL to the web map definition's
# operationalLayers
web_map_definition["operationalLayers"].append(
{
"id": feature_layer.id,
"layerType": "ArcGISFeatureLayer",
"url": feature_layer.url,
"visibility": True,
"layerDefinition": data_layer_definition,
"opacity": 1,
"title": f"{title} {_args.current_day.strftime('%Y-%m-%d')}",
"popupInfo": popup_config,
}
)
else:
# Replace the existing layer
arcpy.AddMessage("Replacing layer")
web_map_definition["operationalLayers"][layer_index][
"id"
] = feature_layer.id
web_map_definition["operationalLayers"][layer_index][
"url"
] = feature_layer.url
# Update the title with the current date
web_map_definition["operationalLayers"][layer_index][
"title"
] = f"{title} {_args.current_day.strftime('%Y-%m-%d')}"
arcpy.AddMessage(web_map_definition["operationalLayers"])
# Add the feature layer's URL to the web map definition's operationalLayers
# Update the web map's definition
webmap_item.update(data=web_map_definition)
arcpy.AddMessage(f"Done")