Python Blog

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Other Boards in This Place


Latest Activity

(204 Posts)
DanPatterson
MVP Esteemed Contributor

This is a follow up to the Common points blog, but with floating point issues addressed because sometimes exact comparisons aren't great due to calculation artifacts or user input issues.

Read more...

more
1 0 311
DanPatterson
MVP Esteemed Contributor

A followup to 'Common segments', since it the points that count in the first place.  I will compare 'normal' to 'numpy' checks so you can add to your arsenal.

Read more...

more
1 1 356
DanPatterson
MVP Esteemed Contributor

Polygons have them.  Polylines sometimes.  It isn't just about matching coordinates.  It is about sharing commonalities.

Read more...

more
1 0 368
DanPatterson
MVP Esteemed Contributor

A combination of ideas.

Read more...

more
2 0 155
DanPatterson
MVP Esteemed Contributor

A point on line missive using numpy and a basic math reminder.

Read more...

more
8 0 434
Clubdebambos
MVP Regular Contributor

The spatial clause for a definition query arrived at ArcGIS Pro 3.5, and while an excellent addition to the definition query capabilities, it still comes up a little short by only enabling 'intersection' as the spatial relationship. In this blog post we will explore how you can generate your own ArcPy geometry object (polygon in this example) to overcome this limitation and apply a spatial clause to your definition query that suits your requirements. 

Read more...

more
3 0 305
Samy_BoumaNgock
Emerging Contributor

Hi everyone,

I’m sharing a working Python script that applies a UniqueValueRenderer symbology to a point feature class in ArcGIS Pro using arcpy. This implementation uses Picture Marker Symbols to represent each unique value in a field—specifically, country flags. The shared code is part of a broader implementation.

SamyBouma_Ngock_0-1748357457635.gif

Why This Matters

Many of us have faced challenges when working with CIM-based symbology in ArcGIS Pro. The documentation around the Cartographic Information Model (CIM) can be sparse or unclear, and issues often arise regardless of the programming language used.

This post aims to provide a working example that others can adapt and build upon.

 

Use Case

  • Feature class type: Point (e.g., country centroids)
  • Field used for symbology: Country_Flag
    • Must use the internal field name, not the alias
    • Field name is case-sensitive
  • Unique values: 238 (each representing a country)
  • Goal: Assign a Picture Marker Symbol (flag image) to each point based on the Country_Flag field

 

Implementation Steps

  • Set a default UniqueValueRenderer using a basic shape marker, keyed on the Country_Flag field.
  • Iterate through each unique value and assign a Picture Marker Symbol using images stored in a local folder.
    • Each image filename matches a value in the Country_Flag field exactly (e.g., France.png, Brazil.png).

 

Key Challenges

  • CIM complexity: The structure of CIM symbol layers is not always intuitive.
  • Field name sensitivity: Using the alias or incorrect casing can silently fail.
  • Lack of consistent examples: Many developers report inconsistent behavior or undocumented quirks when applying symbology programmatically.

 

Why I’m Posting

I’ve seen many threads where people are stuck on similar issues, so I wanted to contribute a working reference. If you're trying to automate symbology in ArcGIS Pro using arcpy, this might save you some time.

In the code below, read "data:image" in its HTML version data+colon symbol+image

Cheers,

    def set_defaultuniquevaluesrenderer(featurelayer=None, fieldname=None):
        """Set a default unique values renderer for the specified field in the feature layer."""
        if featurelayer is None:
            arcpy.AddError("Layer not found. Symbology not updated.")
        
        sym = featurelayer.symbology
        sym.updateRenderer('UniqueValueRenderer')
        sym.renderer.fields = [fieldname]
        featurelayer.symbology = sym
        arcpy.AddMessage(f"Symbology updated to UniqueValueRenderer on field: {fieldname}")

    def set_updatesymbology(featurelayer=None, fieldname=None, imagefolder=None):
        """Update only the point symbols as picture markers with corresponding images."""
        if featurelayer is None:
            arcpy.AddError("Layer not found. Symbology not updated.")

        # Get the CIM (Cartographic Information Model) definition of the layer
        cim = featurelayer.getDefinition('V3')
        renderer = cim.renderer

        # Iterate through each class in the renderer's first group
        for classDef in renderer.groups[0].classes:
            # Get the value for the symbol (usually the flag image filename)
            try:
                value = classDef.values[0].fieldValues[0]
            except (AttributeError, IndexError, TypeError):
                arcpy.AddWarning(f"Skipping class with no valid value for symbol: {classDef.name}")
                continue
            
            # Build the full path to the image file
            imagePath = os.path.join(imagefolder, value)
            if arcpy.Exists(imagePath):
                # Read and encode the image as base64
                with open(imagePath, "rb") as imgFile:
                    encoded = base64.b64encode(imgFile.read()).decode("utf-8")
                # Define a CIMPictureMarker using the encoded image
                pictureMarker = {
                    "type": "CIMPictureMarker",
                    "enable": True,
                    "size": 10,
                    "url": f"data:image/png;base64,{encoded}",
                }
                # Create a CIMPointSymbol with the picture marker
                pointSymbol = {
                    "type": "CIMPointSymbol",
                    "symbolLayers": [pictureMarker]
                }
                # Create a CIMSymbolReference for the class symbol
                symbolRef = {
                    "type": "CIMSymbolReference",
                    "symbol": pointSymbol
                }
                # Assign the new symbol to the class definition
                classDef.symbol = symbolRef

        # Apply the updated CIM definition back to the feature layer
        featurelayer.setDefinition(cim)
        arcpy.AddMessage("Point symbols updated with corresponding flag images.")

 

more
1 0 596
DanPatterson
MVP Esteemed Contributor

Text data is a bother because of its variable length.  NumPy provides a path forward.

Read more...

more
4 0 334
DanPatterson
MVP Esteemed Contributor

worth reading, particularly with the new additions to specifying tool outputs in 3.5

Read more...

more
2 1 347
DanPatterson
MVP Esteemed Contributor

It is springtime, so don't neglect your boundaries.  They may have redundant points, segments that overlap and a variety of other mishaps.

Read more...

more
2 0 370
239 Subscribers
Labels