Hi all,
Is there a posibility to filter an operational layer inside a webmap (similar to what definition query does in ArcMap) and after to save the webmap with the new updates?
I`m at the step where I iterate through my layers from my map but I cannot find the solution to apply a filter/definition query to them.
Thanks,
Ionut
Solved! Go to Solution.
Thanks for looking at that a bit more, The code I had on there was for applying the filter to the featurelayer.
Below is another code block for how you can access a web map isolate a layer in a webmap and change the filter.
To test the code below:
The one Dependency of the code below is the WorldTimeZones - World Regions operational layer in the webmap needs to have a filter set already.
There is a block of code below that will check to see if a Layerdefinition exists on the operational layer before it gets applied:
if 'layerDefinition' in tZoneLyr:
Code:
from arcgis.gis import GIS import copy from json import dumps from json import JSONDecoder from arcgis.mapping import WebMap #Connect to the Organization gis = GIS("https://www.arcgis.com", "<UserName>", "<passW>") #Search for the webmap webmapPub = gis.content.search("title:TimeZoneRegions",item_type = "Web Map") #Use a list comprehension to find the right one you are updating timeZoneWebMap = [wmap for wmap in webmapPub if wmap.title == 'TimeZoneRegions'][0] #Get the webmap json pubMapJson = timeZoneWebMap.get_data(try_json=True) # Filter Expression to apply to layer lyrFilter = "REGION = '{0}'".format("Antarctica") #Make a deepcopy of the json to modify fldMapJsonCopy = copy.deepcopy(pubMapJson) #List comprehension to find the one layer you need to modify by title #Here you could loop on all layers to modify the filter too. lyrT = [l for l in pubMapJson['operationalLayers'] if l['title']== 'WorldTimeZones - World Regions'] if len(lyrT) >0: tZoneLyr = lyrT[0] if 'layerDefinition' in tZoneLyr: z = [[x, y] for x, y in enumerate(pubMapJson['operationalLayers']) if y['title'] == 'WorldTimeZones - World Regions'][0] fldMapJsonCopy['operationalLayers'][z[0]]['layerDefinition']['definitionExpression'] = lyrFilter #Save the changes to the Webmap timeZoneWebMap.update(item_properties={'text':dumps(fldMapJsonCopy)})
Hi Ionut,
Take a look at the following post, the question is similar, although it was in regards to a single layer.
Thanks,
Jeff
Hi Jeff,
Thanks for the quick feedback!
I tried the solution you provided but for some reason, the get_data() method returns None..
I`d also like to point out that in the solution you provided, the item is obtained by searching the content and retrieving the Feature Layer; in my case, I have an operational layer in a web map; not sure if it`s the same thing.
As I can see, the sql expression is mounted on definitionExpression on the object, but in my case I cannot find this property on the layer object from my webmap.
Thanks,
Ionut
UPDATE:
You were right, I`ve used your solution to get a workflow.
I`ve managed to iterate through layers in the webmap, and for each one, I`ve replace it with the same, just that I applied the definitionExpression on it; something like this:
for layer in webMapLayers:
layerTitle = layer.title
srcResults = adminGIS.content.search(layerTitle)
featCollection = srcResults[0]
sql = "sql filter"
webMapItem.remove_layer(layer)
webMapItem.add_layer(featCollection)
webMapItem.layers[0]['layerDefinition']['definitionExpression'] = sql
webMapItem.update()
Thanks again,
Ionut
Thanks for looking at that a bit more, The code I had on there was for applying the filter to the featurelayer.
Below is another code block for how you can access a web map isolate a layer in a webmap and change the filter.
To test the code below:
The one Dependency of the code below is the WorldTimeZones - World Regions operational layer in the webmap needs to have a filter set already.
There is a block of code below that will check to see if a Layerdefinition exists on the operational layer before it gets applied:
if 'layerDefinition' in tZoneLyr:
Code:
from arcgis.gis import GIS import copy from json import dumps from json import JSONDecoder from arcgis.mapping import WebMap #Connect to the Organization gis = GIS("https://www.arcgis.com", "<UserName>", "<passW>") #Search for the webmap webmapPub = gis.content.search("title:TimeZoneRegions",item_type = "Web Map") #Use a list comprehension to find the right one you are updating timeZoneWebMap = [wmap for wmap in webmapPub if wmap.title == 'TimeZoneRegions'][0] #Get the webmap json pubMapJson = timeZoneWebMap.get_data(try_json=True) # Filter Expression to apply to layer lyrFilter = "REGION = '{0}'".format("Antarctica") #Make a deepcopy of the json to modify fldMapJsonCopy = copy.deepcopy(pubMapJson) #List comprehension to find the one layer you need to modify by title #Here you could loop on all layers to modify the filter too. lyrT = [l for l in pubMapJson['operationalLayers'] if l['title']== 'WorldTimeZones - World Regions'] if len(lyrT) >0: tZoneLyr = lyrT[0] if 'layerDefinition' in tZoneLyr: z = [[x, y] for x, y in enumerate(pubMapJson['operationalLayers']) if y['title'] == 'WorldTimeZones - World Regions'][0] fldMapJsonCopy['operationalLayers'][z[0]]['layerDefinition']['definitionExpression'] = lyrFilter #Save the changes to the Webmap timeZoneWebMap.update(item_properties={'text':dumps(fldMapJsonCopy)})
Hi Jeff,
That`s sweet! Thanks a lot!
Although, what if get_data() method on my layer returns None?
Because that`s what happened to me and I had replace the original layer with itself but with a filter applied...
Again, thanks a lot for your feedback!
Best,
Ionut
EDIT: Just needed to use the data correctly.
SOLUTION : webMapItem.layers[len(webMapItem.layers) - 1]['layerDefinition']['drawingInfo'] = json.loads(str(simbol))
where simbol is actualy the json data for symbology for the layer.
Hi Jeff,
In the same way 'definitionExpression' is set above, I`m trying to do with 'drawingInfo' property on the layer, but when I`m setting the info, I`m getting "Object of type 'PropertyMap' is not JSON serializable".
Basically, I`m iterating every layer in the webmap, remove each one, and after add it again, set the 'layerDefinition''definitionExpression' to filter the data and after I`m trying to also set the intial symbol, but somehow it`s not working...
Any idea??
Thanks,
Ionut
I'm looking to implement something nearly identical to this: modifying a filter to a feature layer within a web map and saving a new copy. I'm struggling to find what arguments (proper documentation) are expected for
fldMapJsonCopy['operationalLayers'][z[0]]['layerDefinition']['definitionExpression'] = lyrFilter
I've looked at your other example here and have tried to piece things together but I'm not having any luck. I don't fully understand what the enumeration process here is and don't think i need it.
from arcgis.gis import GIS
from arcgis.mapping import WebMap
import json, copy
gis = GIS("https://my/portal", "UseMe", "L1f3izGr@nd!")
webMapSearch = gis.content.search("title: NortheastFieldData2",item_type = "Web Map")
pubMapJson = webMapTest.get_data(try_json=True)
layerMod = [l for l in pubMapJson['operationalLayers'] if l ['title']=='NortheastCruisePoints']
lyrFilter = "LVI_CODE = '{0}'".format("7532")
fieldMapCopy = copy.deepcopy(pubMapJson)
fieldMapCopy['operationalLayers'][layerMod]['layerDefinition']['definitionExpression']=lyrFilter
Error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-37-aec78b329a7c> in <module>
----> 1 fieldMapCopy['operationalLayers'][layerMod]['layerDefinition']['definitionExpression'] = lyrFilter
TypeError: list indices must be integers or slices, not list
I am late in replying, but the error is indicating the data you have is a list not a dictionary. Check out if what you are getting is what you are expecting.
I also notice that the index 'layerMod' of the 'operationalLayers' variable seems to be erroneous.
I just can't find any reliable documentation about this. I have had a ticket open with tech support that's older than a month now.