Hosted feature layer view does not inherit labels?

1383
3
09-26-2019 07:46 AM
mingster
New Contributor III

Is it possible to have the hosted feature layer view inherit the label styles from the hosted feature layer (parent layer)? The parent layer with label classes was published from ArcGIS Pro. There are three label classes, one for each symbol class in the hosted feature layer, so I would like to retain those labels in the hosted feature layer view. I have to create new labels for the hosted feature layer view when adding it to a map, but AGOL is limited to only one style option. I have attached screenshots - left image is the hosted feature layer, right image is the view layer. Thanks. 

0 Kudos
3 Replies
EarlMedina
Esri Regular Contributor

Hi Ming,

Thank you for presenting this interesting scenario. I don't think this is possible through the ArcGIS Online UI (at least I'm not seeing where you might accomplish this), but you can accomplish this through some clever use of the ArcGIS API for Python.

You mentioned your current workflow is to publish from ArcGIS Pro and then create the view in ArcGIS Online. That is a key detail: this means that the labeling information of the original service is stored within the service definition itself and not at the item level. Indeed, if you create a view from the original service, you can even see that the same exact labeling properties are defined. The problem, however, is for some reason they are not exposed. The good news is, you can expose those dormant properties by modifying the item after the fact. 

If all this is getting a bit confusing, it may help to read this post where I explain the levels at which you can set properties on a layer: https://community.esri.com/groups/arcgis-python-api/blog/2019/04/09/updating-layer-symbology-with-th... 

  • I talk about symbology in the post, but other properties like labeling apply as well.

Okay, let me start with a very rough example I prepared for the sake of illustration. Let's suppose we publish some historic earthquake data in ArcGIS Pro and label events as follows:

  • Red for earthquakes of magnitude greater than 6
  • Blue for earthquakes of magnitude less than 6.

The published service (named eqpro) looks like this when loaded into a Web Map (the labels look terrible I know, but it's the colors we're interested in!):

 

Our starting code is like so:

import json
from arcgis import GIS
from arcgis.features import FeatureLayerCollection

conn = GIS("https://www.arcgis.com", "Hari", "Seldon")

def search_layer(conn,layer_name):
    search_results = conn.content.search(layer_name, item_type='Feature Layer')
    proper_index = [i for i, s in enumerate(search_results) 
                    if '"' + layer_name + '"' in str(s)]
    found_item = search_results[proper_index[0]]
    flc = FeatureLayerCollection.fromitem(found_item)
    return flc

def search_item(conn,layer_name):
    search_results = conn.content.search(layer_name, item_type='*')
    proper_index = [i for i, s in enumerate(search_results) if '"' + layer_name + '"' in str(s)]
    found_item = search_results[proper_index[0]]
    get_item = conn.content.get(found_item.id)
    return get_item‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
  • You don't have to worry so much about the functions here. They just help us locate the content easily.

Next, we locate the eqpro service, load it as a Feature Collection object (source_flc), and create a view from the object (eqpro_view😞

source_flc = search_layer(conn, 'eqpro')
source_flc.manager.create_view(name='eqpro_view')‍‍‍‍‍‍

The created view already has those labeling properties defined at the service level. What we need to do now is expose them at the item level. So, we locate the view item and update its properties to include the ones defined in the dictionary. Here, the dictionary you'll use may differ depending on how many layers are in the service, but you can use the one shown as a rough guide. 

update = {'layers': [{'id': 0, 'showLabels': True,
          'layerDefinition': {'defaultVisibility': True}}]}‍‍

view_item = search_item(conn, "eqpro_view")
item_properties = {"text": json.dumps(update)}
view_item.update(item_properties=item_properties)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Lastly, we apply a view definition to the view to show only earthquakes of magnitude greater than 5. We do this at the service level:

view_def = {"viewDefinitionQuery" : "magnitude > 5"}
view_flc = search_layer(conn, "eqpro_view")

view_layer = view_flc.layers[0]
view_layer.manager.update_definition(view_def)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The final result looks like this:

Note the blue labels still exist and some of the features (which were labeled in blue) have been filtered out (black boxes added to help illustrate the latter).

Hopefully this helps. I know this is probably not the solution you had in mind, but at the very least it may be a viable alternative. If you're interested, the below posts go into more detail on how to create views with the ArcGIS API for Python:

Kind regards,

Earl

mingster
New Contributor III

Thank you Earl for the detailed explanation and workaround for this scenario. I am a novice with ArcGIS API Python, so this will take me a little time to learn and process. Out of curiosity, why do label classes publish to AGOL for some layers but not for others? I have other hosted features that I created in a similar fashion, but the label classes did not transfer. 

0 Kudos
EarlMedina
Esri Regular Contributor

Hi Ming,

My apologies for the delay. I'm glad the information was helpful! I am not sure about label classes and would have to test that out. Perhaps there is a limitation for label classes someone else can expand on?

-Earl

0 Kudos