I was recently working on a project that needed something like 100 unique symbols. Each symbol was a circle or square with a four letter code on it. This is something that lent itself perfectly to being done programatically. I really didn't want to have to generate those symbols one by one, so I started searching of ways to do this programatically, but didn't find much information on how I might get this done using Python.
The first glimmer of hope was when I found how to apply symbols from style gallery (i.e. Favorites or project Styles .stylx). I had accepted the fact that I'd just programatically create a bunch of png's, add them to my Favorites, and then write some code to apply the symbols in my Pro project. Then I stumbled upon an Esri blog post that mentioned that .stylx files are just SQLite databases. This got me thinking that I'd be able to further program the generation of these symbols.
I used DB Browser for SQLite to take a look at the structure of the .stylx db. Most of what you need is stored in the ITEMS table. There's a content field where the json representation of the symbol is stored. For some reason, the json string has a character at the end that makes DB Browser think it's a blob instead of text. If you delete the 00 at the end, it will then display as text and you can get an idea of what the json looks like for a CIMPointSymbol for example.
Things to know about the .stylx file:
I broke my code up into two python scripts. Here's the pseudocode and some real code for each script:
Generate symbols - programmatically generate symbols and add to your Favorites .stylx
execute sql code to insert row into db
new_row = (new_id,3,'',code,'rgb;black',json.dumps(new_sym),code)
commit changes to db and close db
cursor.execute('INSERT INTO ITEMS(ID, CLASS, CATEGORY, NAME, TAGS, CONTENT, KEY) VALUES(?,?,?,?,?,?,?)', new_row)
At this point, I now have a bunch of new symbols in my .stylx file. While testing I worked on a copy of my Favorites.stylx, but as long as Pro is closed, I don't think there's any issues with working on the real file in its default location ("C:\Users\userxxxx\AppData\Roaming\ESRI\ArcGISPro\Favorites.stylx"). Just make sure you have a backup copy of it just in case you ruin it.
Apply symbols - as long as the name of your new symbols matches the symbol item values in your Pro project, it's relatively easy to apply the symbology programmatically
m = p.listMaps('Map') lyr = m.listLayers("layer name") sym = lyr.symbology
for grp in sym.renderer.groups: for item in grp.items: item.symbol.applySymbolFromGallery(item.values)
I hope this helps someone that found themselves in the same position that I was. If anyone needs any more details on how this was done, just let me know.
Here's a list of posts that I found while searching how to do this
Importing Custom Point Symbols
Assigning an icon from a .stylx file and rotating it, in arcpy
Thank you for sharing this! I have about 70 unique polygon symbols in a layer and have been trying to find an efficient way to get them into a style. I probably could have manually saved each symbol to a style in the time I spent searching for a different way, but I know I have other symbols/layers in a similar situation. I hope to try your method.
Holly, glad this was helpful for you. Let me know if you run into any roadblocks if you try this out.
I believe your solution approaches is what I need after a lot of research (Pro 2.7.1) which include apply symbols from style gallery, and examples like Restaurant or Python_CIM_Access. Your method seems to be the only current solution to my problem but I am not sure that it is the right and only possible way. So I would like more details or just advices.
But in the previous cases (links) it is often a question of superimposing symbols and not of automatically creating a symbol with several layers as my goal is to automatically create a legend (.lyrx) of 500 polygon symbols which have each 5 layers. Each polygon has a five characters tag identifier (eg "A1234"). Each character determines the symbology of a layer according its place in the idientifier : the first character fix the solid color of the first layer, the second is used for colored hatch of the second layer, the last three layers have a single and different text marker (like "T" or whatever). The hatches and markers are colored and rotated according to the color and angles read in an attribute table (colors, angles).
This table can therefore be read with pandas df (Python). But I have a few questions in the part "Generate symbols" : 1) will the template need to be created with a single 5-layer symbol (.lyrx), then renamed to .json? 2) I don't understand after "Connect to .stylx like using sqlite3" what ".stylx" is refering about (the new .json ?) ? 3) Is it really possible not to start with a military style .lyrx (MIL *)? 4) Do you think my problem might actually be solved with your method? 5) How should I proceed to program the “Generate symbols” part as automatic as possible?
Thanks for your advices.
Forgot the "links" :
apply symbols from style gallery, and examples like Restaurant or Python_CIM_Access_Samples
I am desperately looking for a way to convert Symbology Encoding to ArcGIS Pro .Stylx do you have any idea for me?
great way to create styles from images in minutes. Thanks a lot for the saved time!