I'd like to re-order webmap layers with Python. I'm using the arcgis package (the ArcGIS API for Python) to add a layer, but the newest layer just goes to the top of the layer list (table of content), which may not be where I want it. How do I re-order it after I add it?
I'd also be interested to know if the WebMap.add_layer() function can just put the layer in the right order in the first place.
thanks!
Anyone at Esri following the forums?
You can change the layers order by changing the order of WebMap object's definition['operationalLayers'] list.
e.g. to switch the order between 1st and last having 6 layers:
wm = WebMap(wm_item)
tempLayerDefinition = wm.definition['operationalLayers'][5]
wm.definition['operationalLayers'][5] = wm.definition['operationalLayers'][0]
wm.definition['operationalLayers'][0] = tempLayerDefinition
wm.update()
I can't get this to work in anyway shape or form?
web_map = gis.content.get("1852725785754747")
wm = WebMap(web_map)
tmplyrdef = wm.definition.operationalLayers[15]
wm.definition.operationalLayers[15] = wm.definition.operationalLayers[0]
wm.definition.operationalLayers[0] = tmplyrdef
wm.update()
wm
In the absence of doubt, I also tried it this way
web_map = gis.content.get("572727827257578547")
wm = WebMap(web_map)
print(wm.definition.spatialReference)
print(wm.definition['operationalLayers'][15])
tempLayerDefinition = wm.definition['operationalLayers'][15]
wm.definition['operationalLayers'][15] = wm.definition['operationalLayers'][0]
wm.definition['operationalLayers'][0] = tempLayerDefinition
wm.update(item_properties=wip)
wm
This works. You need to be aware that the indexing starts at the bottom layer and not the top. The below will switch the bottom layer with the second last layer.
from arcgis import GIS
conn = GIS("home")
item = conn.content.get("wm_item_id")
item_data = item.get_data()
tmp = item_data['operationalLayers'][1]
item_data['operationalLayers'][1] = item_data['operationalLayers'][0]
item_data['operationalLayers'][0] = tmp
item_properties = {"text":item_data}
item.update(item_properties=item_properties)
Just taking this a bit further, I have tens of maps that will eventually be over a couple of hundred +, where I want standard layers in the same order, users have potential to reorder and some older maps do not fit the standard order but the layer naming does. Below is the base script created, I can put the list of webmap ids in a file and iterate through when I want or schedule for intermittent quality control runs. The below is for one run on a single webmap.
from arcgis import GIS
## dictionary
## key: standard layer name
## value: list, index of layer (from bottom up), the definition will be added to this list.
lyr_order_dict = {
"standard_lyr_name_1" : [0],
"standard_lyr_name_2" : [1],
"standard_lyr_name_3" : [2],
"standard_lyr_name_4" : [3],
"standard_lyr_name_5" : [4],
"standard_lyr_name_6" : [5],
"standard_lyr_name_7" : [6],
"standard_lyr_name_8" : [7],
"standard_lyr_name_9" : [8],
"standard_lyr_name_10" : [9],
"standard_lyr_name_11" : [10],
"standard_lyr_name_12" : [11],
"standard_lyr_name_13" : [12],
"standard_lyr_name_14" : [13]
}
conn = GIS("home")
item = conn.content.get("wm_id")
item_data = item.get_data()
## iterate through the layers
for index, i in enumerate(item_data["operationalLayers"]):
## get the name of the layer
title = item_data["operationalLayers"][index]["title"]
## add the definition to the entry in the dictionary
if title in lyr_order_dict:
lyr_order_dict[title] = lyr_order_dict[title] + [item_data['operationalLayers'][index]]
## iterate through the dictionary and reorder the layers
for key, value in lyr_order_dict.items():
item_data['operationalLayers'][value[0]] = value[1]
item_properties = {"text":item_data}
item.update(item_properties=item_properties)
Thanks, will check if this works for me tomorrow; a dict was going to be my next stab.
I have tested it, quite a lot, and it doesn't move any of the layers at all.
I'll work on it again tomorrow, but implementing this, as above, didn't work for me.
That's interesting, I've ran this a few times now and works perfectly, I wonder what the difference is?
Hi there,
Sorry for the late reply, but I have been ill.
This is the function I have, inside a utilities class and I get list index errors, and when I checkl the contents, it's not being populated.
def reorder_layers(self):
print("*********Re-ordering layers********** \n\n")
## dictionary
## key: standard layer name
## value: list, index of layer (from bottom up), the definition will be added to this list.
lyr_order_dict = {
"Open Work Orders" : [0],
"Pressure Control Valves" : [1],
"Others Repairs" : [2],
"Dry Holes" : [3],
"Open CSL" : [4],
"GISID RAG Status" : [5],
"Secondary Pipe Status" : [6],
"DMA" : [7],
"NMA" : [8],
"FMZ" : [9],
"Network Operation Valve" : [10],
"Fire Hydrant" : [11],
"Hot Spot" : [12],
"Property Info" : [13]
}
web_map = self.gis.content.get(self.web_map_id)
item_data = web_map.get_data()
## iterate through the layers
for index, i in enumerate(item_data["operationalLayers"]):
## get the name of the layer
title = item_data["operationalLayers"][index]["title"]
## add the definition to the entry in the dictionary
if title in lyr_order_dict:
print(f"{lyr_order_dict[title]} \n")
lyr_order_dict[title] = lyr_order_dict[title] + [item_data['operationalLayers'][index]]
print(f"{lyr_order_dict[title]} \n")
print(f"{item_data['operationalLayers'][index]} \n")
## iterate through the dictionary and reorder the layers
for key, value in lyr_order_dict.items():
item_data['operationalLayers'][value[0]] = value[1]
item_properties = {"text":item_data}
self.wm.update(item_properties=item_properties)
This gives me an indexError: list index out of range, which on investigating, the data in there isn't good.
IndexError: list index out of range
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<command-2193284686337018> in <module>
42
43 agsutil.get_feature_layer_size()
---> 44 agsutil.reorder_layers()
45 agsutil is None
46 print("Finished")
<command-2193284686336187> in reorder_layers(self)
147 ## iterate through the dictionary and reorder the layers
148 for key, value in lyr_order_dict.items():
--> 149 item_data['operationalLayers'][value[0]] = value[1]