How to create a WebMap layer from json

1316
7
11-30-2018 01:41 PM
JoeHershman
MVP Regular Contributor

Hi,

I had a tool before that let us do the popup configuration in an editor and then reload into the web map.  This was really easy because the WebMap was just a simple dictionary and I just had to replace the ['operationalLayers'] for a file.  This cannot be done in the newest API. 

What I am trying to do instead is remove the layers and then re-add them.  The issue is when trying to add the layer using WebMap.add_layer it does not allow it.  I have copied the exact layer object from a Map and then tried to add and it does not allow, so I know it is not an issue with the json.

How do I create a layer that can be added using WebMap.add_layer from the definition json?

Here is a code sample that shows the issue adding layers.  I use the identical definition to remove and works fine, try to add the same layer and it fails

web_map = arcgis.mapping.WebMap(web_map_item)

# create a copy of the layers
layers = []
layers.extend(web_map.layers)

# remove layers
for layer in layers:
    web_map.remove_layer(layer)

#try to add layers back - see error below
for layer in layers:
    web_map.add_layer(layer)
    


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-55-3865d40b28c6> in <module>()
      8 
      9 for layer in layers:
---> 10     web_map.add_layer(layer)
     11 

C:\Program Files (x86)\Microsoft Visual Studio\Shared\Anaconda3_64\lib\site-packages\arcgis\mapping\_types.py in add_layer(self, layer, options)
    339         else:
    340             raise TypeError("Input layer should either be a Layer object or an Item object. To know the supported layer types, refer" +
--> 341                                 'to https://developers.arcgis.com/web-map-specification/objects/operationalLayers/')
    342         # endregion
    343 

TypeError: Input layer should either be a Layer object or an Item object. To know the supported layer types, referto https://developers.arcgis.com/web-map-specification/objects/operationalLayers/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Thanks

-Joe 

Thanks,
-Joe
0 Kudos
7 Replies
JoeHershman
MVP Regular Contributor

Thought this would be answered by now.  If the valid json array element is not considered a valid Layer object how does one create in the API?  I don't see any 'Layer' object to instantiate in the help

Really frustrating that the API is 'upgraded' which results in breaking working code

Thanks

-Joe

Thanks,
-Joe
0 Kudos
JoeHershman
MVP Regular Contributor

Still nothing....

Thanks,
-Joe
0 Kudos
AgrimotionTeam
New Contributor II

Did you ever solve the issue?

0 Kudos
JoeHershman
MVP Regular Contributor

Nope, ended up rewriting the tool in C#.

Thanks,
-Joe
0 Kudos
AnttiKajanus
New Contributor III

I think that you cannot use the add layer functionality for this but you can just add the json to the layers collection. Here is rough example how to do that in the python but it's just working with the json and not API objects like layer. I haven't tested this implicitly but should work.. i think...

from arcgis.gis import GIS
import getpass

password = getpass.getpass("Enter password: ")

gis = GIS('org', 'user', password)
print("Connected to: {}\nConnected as: {}".format(
                 gis.properties.urlKey + "." + gis.properties.customBaseUrl,
                 gis.users.me.username))

# Enter password: ········
# Connected to: org
# Connected as: me

webmap_item = gis.content.get('ce80541f342546319d99308cbeb9f675')
webmap_item

# webmap item output

from arcgis.mapping import WebMap
webmap = WebMap(webmap_item)

for layer in webmap.layers:
    print(layer.title)
print(len(webmap.layers))

# TrekkingFinland - Reitit
# TrekkingFinland - Rakennelmat
# TrekkingFinland - Luonnonsuojelu Alueet
# 3

import copy

layer = webmap.layers[0]
layer_copy =copy.deepcopy(layer) # add this back to the map for test
layer

# layer json output

webmap.layers.remove(layer)
for layer in webmap.layers:
    print(layer.title)
print(len(webmap.layers))

# TrekkingFinland - Rakennelmat
# TrekkingFinland - Luonnonsuojelu Alueet
# 2

webmap.layers.insert(0, layer_copy)
for layer in webmap.layers:
    print(layer.title)
print(len(webmap.layers))

# TrekkingFinland - Reitit
# TrekkingFinland - Rakennelmat
# TrekkingFinland - Luonnonsuojelu Alueet
# 3‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The python API is nice and dandy but it doesn't provide good way to work with the maps through API objects so you basically just work with the json directly and have to make sure that the json you are adding is valid objects from arcgis point of view. It could be a bit easier and now it requires quite a bit understanding on the platform and it's json models.

I bet Joe has on this day already written his own C# library around REST 

0 Kudos
JoeHershman
MVP Regular Contributor

I had built out the layer in json, but was trying to use the add_layer method as opposed to what you do above and just modifying the layers array.

What was troubling was that there had been a change in the API at one point so a really simple approach that worked with the json was broken and then I was stuck to find something new. 

In the end the C# approach is an improvement because I have a GUI.  The user can log in and download the Web Map, which is converted to XML.  Then we can edit the popups in XmlSpy which is a lot easier than the Web UI.  Then use the GUI app to import.  We also use this approach to move environments.  We will create a blank Web Map in the new environment and then do an import using the previously defined Web Map after replacing the server names (assumes services are named the same).

Cheers

-Joe

Thanks,
-Joe
0 Kudos
AnttiKajanus
New Contributor III

I hope you are doing well Joe, it's been a while that chatted last time.

Not surprised here. I think that the tools for creating and managing webmaps / items could be a bit more user friendly and especially from the point of view of automated deployment / devops ways of doing things. Python seems to work the best from the Esri APIs but still there are plenty of things that you cannot really do well in it and you need to revert back to arcpy or other means. 

0 Kudos