When you inspect the JSON Data for a hosted feature service content item using the Item object get_data() method, you will either be returned an empty dictionary or a populated dictionary with the layers and tables definitions defined. We'll call this dictionary "JSON Data". If the feature service was created with the ArcGIS API for Python it is more than likely an empty dictionary, unless you opened the Visualization tab and clicked Save, which will populate the JSON Data with the layers and tables definitions.
Now, the insert_layer() method for a FeatureLayerCollection object works just fine if the returned JSON Data is empty, but not so fine if it is populated with definitions. You see, when the JSON Data is empty, the FeatureLayer and Table object properties rule for defining many components such as symbology, labeling, and scale ranges. However, if the definitions exist in the JSON Data, then that rules supreme! You cannot set a filter or apply popup definitions via the FeatureLayer and Table object, but you can with the JSON Data.
Here's what happens, when you use insert_layer() the Feature Layer gets created and added to the service, but the JSON Data does not get updated. This will make it look like your Feature Layer was not actually added as it won't display in the Overview, Data, or Visualization tabs. You need to add the layer definition to the JSON Data to rectify.
Let's take a look at the example from the video.
I have a feature service published from ArcGIS Pro that contains a single feature layer and I want to add a second feature layer from a feature class in a zipped file geodatabase.
Below, I create an Item object and a FeatureLayerCollection object, both represent the feature service in different ways
from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
## access ArcGIS Online
agol = GIS("home")
## get the item object
item = agol.content.get("FS_ITEM_ID")
## create the FeatureLayerObject
flc = FeatureLayerCollection.fromitem(
item = item
)
At this point, you can check what the Item object get_data() returns. For me it is a dictionary with one key, layers, that is a list containing a single layer definition represented by a dictionary.
print(item.get_data())
I will use the insert_layer() method from the FeatureLayerCollection object to insert the feature class.
## filepath to file geodatabase
gdb_path = r"C:\path\to\zipped\gdb.zip"
## use the flc object insert_layer() method to create a feature layer
status = flc.manager.insert_layer(
data_path=gdb_path,
name="LAYER NAME" # this is not honoured
)
print(status)
If successful, the status variable will be the updated Item object.
You can check to see if the new feature layer can be found in the FeatureLayerCollection (or Item) object layers property. (Comment out the insert_layer() snippet and re-run)
print(*flc.layers, sep="\n")
print(*item.layers, sep="\n")
You will see that two FeatureLayer objects are returned.
However, if you pay the feature service a visit in ArcGIS Online, this second feature layer is nowhere to be seen. Let's fix that!
## item data layer dictionary template
lyr_dict = {
"id" : None,
"blendMode" : "normal",
"layerDefinition" : {},
"disablePopup" : False,
"popupInfo" : {
"popupElements" : [
{
"type" : "fields",
"fieldInfos" : None
}
]
}
}
## get the FeatureLayer object
fl = flc.layers[1]
## update the id key
lyr_dict["id"] = fl.properties.id
## update the layerDefinition key (symbology))
lyr_dict["layerDefinition"]["drawingInfo"] = fl.properties.drawingInfo
## get the field info for the popup
field_infos = []
for field in fl.properties.fields:
field = dict(field)
field_dict = {
"fieldName" : field["name"],
"isEditable" : field["editable"],
"label" : field["alias"],
"visible" : True
}
field_infos.append(field_dict)
## apply the field infos
lyr_dict["popupInfo"]["popupElements"][0]["fieldInfos"] = field_infos
## get the item JSON data
item_data = item.get_data()
## update layers
item_data["layers"] = item_data["layers"] + [lyr_dict]
## update the Item
update_dict = {
"text" : item_data
}
status = item.update(
item_properties = update_dict
)
print(status)
The lyr_dict represents what was printed to screen for a layer definition from item.get_data(). The id gets populated based on the id from the newly inserted feature layer. The layerDefinition is populated with the symbology, and we have the popup enabled and with one popup element for the fields. The fieldInfos need to be populated so we grab all fields from the feature layer and make them visible in the popup.
Next, the layers key from the returned JSON Data is updated to add in the new definition, and finally the Item object JSON Data is updated to commit the change.
Now, when we visit the feature service Overview, Data, or Visualization table, the newly inserted feature layer is present.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.