1

I have an ETL updating a layer attribute on a registered Enterprise geodatabase. The layer has been published on ArcGIS Portal which sends the layer with updated values to ArcGIS Online. This data is on a webmap that has Natural Breaks symbology applied to it. The web map participates on a web site. The layer is updated twice a day.

When the data values exceed the maximum value from the previous update the symbology can't render those now out of range values requiring someone to open the webmap and reapply the symbology each time the ETL runs.

Currently I'm using selenium to mimick a user logging on and doing the update manually but it is hacky and often errors out. Also requires an active user profile session on console machine.

I looked into Python API for ArcGIS and came across this: https://community.esri.com/groups/arcgis-python-api/blog/2019/04/09/updating-layer-symbology-with-the-arcgis-api-for-python

but it looks like that only works if you already have the values for your breaks defined in an existing JSON file you use to update the current JSON file your web map is referencing.

Last, I tried to use arcpy to update symbology in an ArcPr project and export the layer file and get the new JSON values from that, but applying the code below did not update anything:

import arcpy

p = arcpy.mp.ArcGISProject(r'C:\my_project.aprx')
m = p.listMaps()[0]

for lyr in m.listLayers():
  if lyr.isFeatureLayer:
    sym = lyr.symbology
    if hasattr(sym, 'renderer'):
        sym.updateRenderer('GraduatedColorsRenderer')
        sym.renderer.classificationField = 'CaseRates'
        sym.renderer.classificationMethod = 'NaturalBreaks'
        sym.renderer.breakCount = 5
        
        lyr.symbology = sym

Seems like this should be way more simple than this, especially as this does not work.

5
  • Hi geoJshaun - There are multiple programmatic ways to update the symbology of a web map, using python, REST, javascript etc depending on your preference. Using Selenium seems an awkward way to do it. How are you currently updating the ArcGIS Online data? Commented Aug 18, 2020 at 0:13
  • Hi Bjorn. I'm currently using Selenium to do it, mimicking the actions of a logged on user. It is awkward and I'd prefer to use the ArcGIS API for JS, I think. Something that references the web map and uses legend API reference but with added logic to calculate min max values of data range in web map's feature layer.
    – geoJshaun
    Commented Aug 19, 2020 at 16:30
  • If you want to automate it, the easiest way to update the webmap is probably using ArcGIS API for Python OR node.js making direct REST requests. Either could easily be scheduled to run after your data update. (I'm guessing your twice daily update is already automated...) Commented Aug 19, 2020 at 20:46
  • @BjornSvensson looking at the Python API seems you have to have break values predefined in a JSON file you can swap out. I won't know the values ahead of time to do this. Here's what I'm looking at:community.esri.com/groups/arcgis-python-api/blog/2019/04/09/…
    – geoJshaun
    Commented Aug 20, 2020 at 1:18
  • @BjornSvensson updated post
    – geoJshaun
    Commented Aug 20, 2020 at 1:26

1 Answer 1

1

Option 1.

If you're just worried about the maximum value, you could just change the upper limit to some very high number that's likely to include future high values.

You can do this using Map Viewer UI or if you prefer, the raw webmap json in which case it's the classMaxValue on the last item in layerDefinition.drawingInfo.renderer.classBreakInfos.

Option 2.

To figure out what the exact natural breaks should be, use "Generate Renderer".

This is available both in the ArcGIS API for Python (see https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html?highlight=generate#arcgis.features.FeatureLayer.generate_renderer) or using the REST API.

For example, you can get those values with a REST request to the Featurelayer using it's "Generate Renderer" option. That's what the Map Viewer is doing. Example REST request:

    {
    "type":"classBreaksDef",
    "classificationField":"total_turb",
    "classificationMethod":"esriClassifyNaturalBreaks",
    "breakCount":4
    }

Ref: https://developers.arcgis.com/rest/services-reference/generate-renderer.htm

1
  • Sorry for the delayed response but this has taken quite a bit of effort to research. The process I developed uses the Python API to swap out the JSON. I have figured out a way to compute the the breaks using jenkspy. Now I have to find a way to locate the max values and labels in the list that is part of the JSON object classBreakInfos with the values generated by jenkspy. Thank you for the solution but I can't quite follow the workflow.
    – geoJshaun
    Commented Aug 27, 2020 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.