copy layers between webmaps?

791
3
Jump to solution
12-03-2019 05:07 PM
dcafdg
by
Occasional Contributor II

SHORT VERSION: I have a webmap for a national set of layers, plus several webmaps containing regional data sets. My goal is to start with the national webmap and add in the layers from the relevant regional webmap for the area where we're working at the moment. I want to save the combined layers from both webmaps to a new webmap. I have figured out how to trace each layer from one webmap back to its source and add that to the other webmap, but this loses any settings that were made in the webmap (e.g.: symbology). How do I merge the layers in two webmaps while preserving the webmap's settings?

LONG VERSION:

I get each webmap as an arcgis.gis.Item and cast it to an arcgis.mapping.WebMap. My regional WebMap object is called reg_webmap, and I loop through the layers like this:

for layer in reg_webmap.layers:

The layer object in the loop is of type PropertyMap. Is there anything I can do with those objects directly to add them to another WebMap? I would like to copy them over with any custom symbology and settings for opacity, title, visibility, etc.

I tried two different methods of adding the regional WebMap's layer objects to the national WebMap:

  1. If I add a hosted feature service to the regional WebMap: As I loop through the layers, each layer object has an itemID, which links me back to the hosted feature layer. I can create an Item object which I can add to the national WebMap.
  2. If I add layers one-by-one to the regional WebMap using the layer-specific URL: The layer won't have an itemID, but will have an URL, which is used to create a FeatureLayer object, which I can add to the national WebMap object.

In either case, the problem is that I'm NOT adding the layer from one WebMap to the other WebMap. Instead, I am using the layers in one WebMap to find their source, and then adding that to the other WebMap. While the end result works, any custom settings in the regional webmap (i.e.: symbology, title, opacity, visibility) are not reflected. In the output.

0 Kudos
1 Solution

Accepted Solutions
FC_Basson
MVP Regular Contributor

This sounds like a job for the Python API.  Once you have installed the Conda environment and Jupyter Notebook, it's fairly easy to access and manage items such as layers and web maps.  Have a look at this blog post for a similar question.

I could achieve copying layers from one Web Map to another in ArcGIS Online with the following code:

from arcgis.gis import *
gis = GIS(username="username", password="password")

from IPython.display import display
items = gis.content.search(query="title:Map* AND owner:username", item_type="Web Map")
for item in items:
    print(item.title + ": " + item.id)

# select Web Maps from item id
mapitem1 = gis.content.get('<Item ID of source Web Map>')
display(mapitem1)

mapitem2 = gis.content.get('<Item ID of destination Web Map>')
display(mapitem2)

# get Web Map Objects
from arcgis.mapping import WebMap
wmo1 = WebMap(mapitem1)
wmo2 = WebMap(mapitem2)

# output operational layers
wmo1.definition['operationalLayers']
wmo2.definition['operationalLayers']

# copy second layer from first WM to second WM
wmo2.definition['operationalLayers'].append(wmo1.definition['operationalLayers'][1])
wmo2.update()
wmo2.definition['operationalLayers']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

3 Replies
FC_Basson
MVP Regular Contributor

This sounds like a job for the Python API.  Once you have installed the Conda environment and Jupyter Notebook, it's fairly easy to access and manage items such as layers and web maps.  Have a look at this blog post for a similar question.

I could achieve copying layers from one Web Map to another in ArcGIS Online with the following code:

from arcgis.gis import *
gis = GIS(username="username", password="password")

from IPython.display import display
items = gis.content.search(query="title:Map* AND owner:username", item_type="Web Map")
for item in items:
    print(item.title + ": " + item.id)

# select Web Maps from item id
mapitem1 = gis.content.get('<Item ID of source Web Map>')
display(mapitem1)

mapitem2 = gis.content.get('<Item ID of destination Web Map>')
display(mapitem2)

# get Web Map Objects
from arcgis.mapping import WebMap
wmo1 = WebMap(mapitem1)
wmo2 = WebMap(mapitem2)

# output operational layers
wmo1.definition['operationalLayers']
wmo2.definition['operationalLayers']

# copy second layer from first WM to second WM
wmo2.definition['operationalLayers'].append(wmo1.definition['operationalLayers'][1])
wmo2.update()
wmo2.definition['operationalLayers']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
dcafdg
by
Occasional Contributor II

FC Basson‌, thanks, that works great.

Now what if I want to tinker with the properties of the layer a bit? The following code prepends some text to the title and turns the layer off, but is that the best way?

for layer in webmap1.definition['operationalLayers']:
    layer['title'] = 'Region F - ' + layer['title']
    layer['visibility'] = False
    webmap2.definition['operationalLayers'].append(layer)
‍‍‍‍‍‍‍‍‍‍‍

The reason I ask is that in my debugger, if I look at WebMap.layers['operationalLayers'], each layer in the list is of type arcgis._impl.common._mixins.PropertyMap. When I see leading underscores in the package structure, I assume they don't want me to play with that too much.That said, the API docs say each layer is a dict, and as I loop through the elements in the list, those show they are type dict. Is the code above the best way to modify individual layer properties within the context of the solution you provided? thanks!

0 Kudos
FC_Basson
MVP Regular Contributor

I don't think your method for setting individual layer properties is incorrect.  The only other way I could think of changing the dictionary item properties would be with a more simplified syntax e.g.

for layer in webmap1.definition.operationalLayers:
   layer.title = 'Region F - ' + layer.title
   layer.visibility = False
   webmap2.definition.operationalLayers.append(layer)
0 Kudos