Adding WebTiledLayer via ArcGIS Python API

1394
7
03-12-2019 09:39 AM
TrevorMcDonald
New Contributor II

I would like to add a WebTiledLayer via the ArcGIS Python API similar to addItem in the REST API.

My understanding is that I would use `gis.content.add` as shown blelow:

import arcgis

from arcgis.gis import GIS

from arcgis.mapping import WebMap

gis = GIS ('https://www.arcgis.com', 'username', password')

layer = ({'operationalLayers': [ 

                  {'title' : 'TITLE-HERE',

                   'type' : 'WebTiledLayer'

                   'templateUrl': 'URL-HERE',

                   'id': 'ID-HERE',

                  'copyright': 'COPYRIGHT-HERE'

                  'fullExtent': {

                        ...

                        'spatialReference': {

                           'wkid': ...

                     }

                  },

                  'visibility': 'true',

                  'opacity': 1,

                  'layerType' : 'WebTiledLayer',

         }

]

})

item_properties = { 'title': 'TITLE-HERE',

                                 'type': 'Map Service',

                                 'snippet', 'SOMETHING-HERE'

                                 'tags': 'tiles-testing'

                                 'url' : 'SAME AS TEMPLATE URL ABOVE'

                                 'text': json.dumps(layer)

                              }

test_item = gis.content.add(item_properties=item_properties)

test_item.share(True)

When I try to use the link created, open it in Map Viewer and get a response of:

   Error

      The layer, {TITLE FROM ITEM PROPERTIES}, cannot be added to the map.

Any help is appreciated. If there is a notebook or other python snippet you can provide that would be ideal. Documentation lacks clear examples of how to implement the addItem cousin in ArcGIS Python API.

7 Replies
EarlMedina1
Occasional Contributor III

Hi Trevor,

Do you have this working with addItem? I ask because I'm not certain that you can add a Web Tiled Layer as an Item - that seems to be one of the types that you can only add when you're in the Map Viewer. I don't see anywhere that you can set the required x, y, z values when adding as an item.

In that case, you may have to settle for adding the Web Tiled Layer to a Web Map like so:

from arcgis.gis import GIS
gis = GIS("https://www.arcgis.com","user","pass")

# This is the JSON used to create the Web Map, which includes a default basemap and a sample Web Tiled Layer
data={"operationalLayers":[{"templateUrl":"https://{subDomain}.tile.thunderforest.com/cycle/{level}/{col}/{row}.png",
"copyright":"Maps © <a href='https://www.thunderforest.com'>Thunderforest<\/a>, Data © <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap contributors<\/a>",
"fullExtent":{"xmin":-2.0037508342787E7,"ymin":-2.003750834278E7,"xmax":2.003750834278E7,"ymax":2.0037508342787E7,
"spatialReference":{"wkid":102100}},"subDomains":["a","b","c"],"id":"WebTiled_7161","title":"OpenCycleMap","type":"WebTiledLayer",
"layerType":"WebTiledLayer","visibility":True,"opacity":1}],"baseMap":{"baseMapLayers":[{"id":"defaultBasemap",
"layerType":"ArcGISTiledMapServiceLayer","url":"https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
"visibility":True,"opacity":1,"title":"Topographic"}],"title":"Topographic"},"spatialReference":{"wkid":102100,"latestWkid":3857},
"authoringApp":"WebMapViewer","authoringAppVersion":"4.3","version":"2.1"}

# Fill this out as you see fit, the key part is the "text" attribute
item_properties_dict = {"type": "Web Map","title": "Test Map","tags": ["WebTiledLaye","pythonapi"],"snippet":"", "text":data}

newmap = gis.content.add(item_properties = item_properties_dict)
newmap‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
TrevorMcDonald
New Contributor II

Thanks Earl, very helpful... The issue I am running into now is when I try and `arcgis.gis.content.add` multiple XYZ `templateUrl` dictionaries. I have the output webmap I can share with you that has odd behavior the the multiple layers that hvae been added. I must click ALL the layers on or off to render or remove... and when I do that it only renders or removes and single XYZ tile from the webmap iteslf.  For example:

{"operationalLayers":[


{"templateUrl":"https://tiles3.planet.com/v1/experimental/tiles/PSScene4Band/20190206_173912_101c,20190206_173913_101c,20190206_173914_101c,20190206_173915_101c,20190206_181216_1034,20190206_181217_1034,20190206_181218_1034,20190206_181255_1044,20190206_181257_1044/{level}/{col}/{row}.png?api_key=accessCode","copyright":"planet","fullExtent":{"xmin":-20037508.342787,"ymin":-20037508.34278,"xmax":20037508.34278,"ymax":20037508.342787,"spatialReference":{"wkid":102100}},"opacity":1,"visibility":true,"id":"WebTiled_7441","title":"first-tiles","type":"WebTiledLayer","layerType":"WebTiledLayer"},

{"templateUrl":"https://tiles3.planet.com/v1/experimental/tiles/PSScene4Band/20190206_173912_101c,20190206_173913_101c,20190206_173914_101c,20190206_173915_101c,20190206_181216_1034,20190206_181217_1034,20190206_181218_1034,20190206_181255_1044,20190206_181257_1044/{level}/{col}/{row}.png?api_key=accessCode","copyright":"Planet","fullExtent":{"xmin":-20037508.342787,"ymin":-20037508.34278,"xmax":20037508.34278,"ymax":20037508.342787,"spatialReference":{"wkid":102100}},"opacity":1,"visibility":true,"id":"WebTiled_6777","title":"another-tile-set","type":"WebTiledLayer","layerType":"WebTiledLayer"}

]

,"baseMap":{"baseMapLayers":[

{"id":"defaultBasemap","layerType":"ArcGISTiledMapServiceLayer","url":"https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer","visibility":true,"opacity":1,"title":"Topographic"}],"title":"Topographic"},"spatialReference":{"wkid":102100,"latestWkid":3857},"authoringApp":"WebMapViewer","authoringAppVersion":"6.4","version":"2.13"}

Here is the cURL command from the browser, when I tried doing in AGOL only. It is using the `/update` endpoint in REST API but I cannot find the equivalent in ArcGIS Python API. cURL below:

curl'https://planetlabs.maps.arcgis.com/sharing/rest/content/users/Planeteer/items/60d8f5d883e344dcb5308e8855298ba6/update'-H'Referer:http://planetlabs.maps.arcgis.com/home/webmap/viewer.html?webmap=60d8f5d883e344dcb5308e8855298ba6'-H'Origin:http://planetlabs.maps.arcgis.com'-H'User-Agent:Mozilla/5.0(X11;Linuxx86_64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/72.0.3626.96Safari/537.36'-H'Content-Type:application/x-www-form-urlencoded'--data'title=20190214_x2---&tags=planet-tiles&extent=-119.2888,33.7976,-118.0391,34.753&text={"operationalLayers":[{"templateUrl":"https://tiles3.planet.com/v1/experimental/tiles/PSScene4Band/20190206_173912_101c,20190206_173913_101c,20190206_173914_101c,20190206_173915_101c,20190206_181216_1034,20190206_181217_1034,20190206_181218_1034,20190206_181255_1044,20190206_181257_1044/{level}/{col}/{row}.png?api_key=accessCode","copyright":"planet","fullExtent":{"xmin":-20037508.342787,"ymin":-20037508.34278,"xmax":20037508.34278,"ymax":20037508.342787,"spatialReference":{"wkid":102100}},"opacity":1,"visibility":true,"id":"WebTiled_7441","title":"first-tiles","type":"WebTiledLayer","layerType":"WebTiledLayer"},{"templateUrl":"https://tiles3.planet.com/v1/experimental/tiles/PSScene4Band/20190206_173912_101c,20190206_173913_101c,20190206_173914_101c,20190206_173915_101c,20190206_181216_1034,20190206_181217_1034,20190206_181218_1034,20190206_181255_1044,20190206_181257_1044/{level}/{col}/{row}.png?api_key=accessCode","copyright":"Planet","fullExtent":{"xmin":-20037508.342787,"ymin":-20037508.34278,"xmax":20037508.34278,"ymax":20037508.342787,"spatialReference":{"wkid":102100}},"opacity":1,"visibility":true,"id":"WebTiled_6777","title":"another-tile-set","type":"WebTiledLayer","layerType":"WebTiledLayer"}],"baseMap":{"baseMapLayers":[{"id":"defaultBasemap","layerType":"ArcGISTiledMapServiceLayer","url":"https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer","visibility":true,"opacity":1,"title":"Topographic"}],"title":"Topographic"},"spatialReference":{"wkid":102100,"latestWkid":3857},"authoringApp":"WebMapViewer","authoringAppVersion":"6.4","version":"2.13"}&type=WebMap&typeKeywords=ArcGISOnline,ExplorerWebMap,Map,OnlineMap,WebMap&overwrite=true&f=json&token=potmyJp0-hie_IM8d1s-AYHsMWsBvfk2ExQ6q0huS5nkI6N4ynFiMBCVD-oxnG06_HWKyvAZ9D3AnnThJC27YPjggnZ9FHpsqRae7ZFvA8RymOAwedcmx2F5QlKjmlEa9NEjDB4HMl9PPtgvOu3srVIPR61kJhueqFkXN1_GKEDWj2ZIfQovJrUntQN90ScKcEe4GKf6rEXwNqkdsjAv1Q..'--compressed

0 Kudos
EarlMedina1
Occasional Contributor III

Hi Trevor,

Try approaching it this way:

  1. Create the Web Map manually exactly as you want it to appear.
  2. Save the Web Map and make a note of the Item ID that is generated.
  3. Optional: share the Web Map publicly - you don't have to, it just makes the next step easier since you won't require a token. You can unshare/delete the Web Map when you're done.
  4. If this is a Portal Web Map, go to https://machine.domain/portal/sharing/rest/content/items/<itemID>/data. For ArcGIS Online this will be: https://www.arcgis.com/sharing/content/items/<itemID>/data
    • You'll need to append a token (?token=<token>) to the URL if you didn't share publicly.

The result will be the JSON you need to be using for the Item Properties text value.

0 Kudos
TrevorMcDonald
New Contributor II

Earl,

I was hardcoding the `id` in each `templateUrl`...

Fixed that. Thanks for the help thus far!

0 Kudos
TrevorMcDonald
New Contributor II

Last question of the day is how would I set the extent of the WebMap itself, not the layers... I have tried adding "extent"

  item_properties_dict = {"type": "Web Map","title": now ,"tags": ["WebTiledLayer","pythonapi"],"snippet":"", "text":data, "extent": [leftcoord, bottomcoord, rightcoord, topcoord]}

I see "extent" as a Key:Value Dictionary Options for Argument item_properties

 https://esri.github.io/arcgis-python-api/apidoc/html/arcgis.gis.toc.html#arcgis.gis.ContentManager.a...

I tried reversing engineer like we did above with a map where I zoom to my preferred extent, saved it and that's where the map loads up. I noticed when I did this that the maps .../<itemID>/data did not have the Web Map extent set in the output at https://www.arcgis.com/sharing/content/items/<itemID>/data 

Thank you again!

0 Kudos
EarlMedina1
Occasional Contributor III

Happy to help Trevor. You do that like this:

def search_item(item_name):
search_results = portal.content.search(item_name, item_type="Web Map")
item = search_results[0]
return item.id

search = search_item('Name of Web Map')
item = portal.content.get(search)

# Print the current extent
print(item.extent)

# Update the extent
new_extent = [[-124.35, 32.54], [-114.31, 41.95]]
item.update(item_properties={'extent':new_extent})

# Confirm extent update
print(item.extent)
RobertWeber
New Contributor III

Earl Medina‌ or Trevor McDonald

have the WMTS layer rendering fine in the beta Map Viewer but when I zoom in and back out its seems like it stops rendering the tiles that it had previously been rendering.

data={"operationalLayers":[{
"templateUrl":f'{templateUrl}?api_key={api_key}',
"copyright":"Planet",
"fullExtent":{
"xmin":f'-{extent}',
"ymin":f'-{extent}',
"xmax":extent,
"ymax":extent,
"spatialReference":{"wkid":102100}
},
"id":"WebTiled_54", "title":"TestWebTiled",
"type":"WebTiledLayer",
"layerType":"WebTiledLayer",
"tileInfo": {},
"wmtsInfo": {
"url": f'{lyr.dataSource}',
"layerIdentifier": "Combined scene layer",
"tileMatrixSet": "GoogleMapsCompatible23"
},
"visibility":True,"opacity":1
}],
"baseMap":{"baseMapLayers":[{"id":"defaultBasemap", "layerType":"ArcGISTiledMapServiceLayer","url":"https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer", "visibility":True,"opacity":1,"title":"Topographic"}],"title":"Topographic"},"spatialReference":{"wkid":102100,"latestWkid":3857}, "authoringApp":"WebMapViewer","authoringAppVersion":"4.3","version":"2.1"}

Any thoughts on this based on the text parameters?

0 Kudos