Select to view content in your preferred language

Add a feature layer (published from a csv file) to a webmap

1058
5
Jump to solution
08-08-2023 11:11 AM
Labels (2)
DonaldPike
New Contributor III

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)

 

 

Tags (1)
1 Solution

Accepted Solutions
DonaldPike
New Contributor III

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")

 

View solution in original post

0 Kudos
5 Replies
DonaldPike
New Contributor III

BTW, this is using version 2.1.0.3 of the arcgis python package.

0 Kudos
jcarlson
MVP Esteemed Contributor

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.

- Josh Carlson
Kendall County GIS
DonaldPike
New Contributor III

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

 

0 Kudos
Clubdebambos
Occasional Contributor III

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)

~ learn.finaldraftmapping.com
DonaldPike
New Contributor III

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")

 

0 Kudos