Select to view content in your preferred language

Enhance the ArcGIS Pro Definition Query Spatial Clause with ArcPy with a Multi-layer Geometry Filter

88
0
Tuesday
Labels (1)
Clubdebambos
MVP Regular Contributor
2 0 88

Original blog post available here.

Introduction

ArcGIS Pro 3.5 saw the addition of the Spatial Clause functionality for a Definition Query. While limited, it is a very useful addition where we can filter a layers features where they intersect another layer entirely or based on a selection. We are limited to intersects and we ae also limited to one spatial clause per definition query.

In this blog post we are going to use ArcPy to overcome this limitation. We will show that we can create a definition query where we filter points based on intersection with a polygon layer, but we also want to filter out points that intersect features in a second polygon layer. In our example, we want to create a definition query, using the spatial clause, where points intersect the green highlighted area below, but do not intersect the red areas.

Clubdebambos_1-1752587336908.png

 

The Setup

Clubdebambos_2-1752587385430.png

 

We access the open APRX we are working in, access the relevant Map, and we access each layer where pt_lyr is the layer we want to apply a definition query to using the spatial clause functionality, where the points intersect the right-most polygon in ply2_lyr, but do not intersect the polygons on ply1_lyr.

aprx = arcpy.mp.ArcGISProject("CURRENT")
m = aprx.listMaps("Blog")[0]
m.name
'Blog'
pt_lyr, ply1_lyr, ply2_lyr = m.listLayers()
pt_lyr.name, ply1_lyr.name, ply2_lyr.name
('points_fc', 'polygon_1', 'polygon_2')

 

Get the required geometries

We will grab the Polygon geometry for our main area from ply2_lyr. We want points that intersect this area. We also get all polygons from ply1_lyr which we do not want points that intersect these. 

## get the polygon where we want points that intersect
ply2_geom = [row[0] for row in arcpy.da.SearchCursor(ply2_lyr, "SHAPE@", "OBJECTID=1")][0]

## get the polygons for where we do not want points to intersect
ply1_geoms = [row[0] for row in arcpy.da.SearchCursor(ply1_lyr,"SHAPE@")]
 

There can be only one!

We union all polygons from ply1_lyr together to give us one geometry object (Polygon).

We then erase these areas from the geometry from ply2_lyr. This will give us the geometry to use in our spatial clause in the definition query. The spatial clause uses a geometry object to perform the intersect. At the time of writing this, you could use a layer in its entirety, a selection, or a custom extent via the GUI.

## union the two geometries for non-intersection
## you could iterate over more geometries, the goal here is a single multi-geom object
ply1_geom = ply1_geoms[0].union(ply1_geoms[1])

## erase the non-intersecting polygons from the intersecting
sc_geom = ply2_geom.difference(ply1_geom)

 

Define and apply the definition query

We define the definition query dictionary and apply the definition query to our pt_lyr. The workflow below will remove any current definition query and make this one the solo one available for the point layer.

## define the definition query
dq = {"name" : "Spatial Clause Testing", "sql" : "", "isActive" : True, "spatialClause" : [{"geometry":sc_geom}]}

## apply the definition query
## NOTE: this will remove any definition queries and replace with a single definition query
pt_lyr.updateDefinitionQueries([dq])

 

Clubdebambos_3-1752587564835.png

 

 

Contributors
About the Author
GIS Consultant with extensive experience utilising skills for GIS project management, quality map production, data management, geospatial analysis, standardisation, and workflow automation across a range of industries such as agriculture, oil & gas, telecommunications and engineering. Going beyond map production there is a passion for the technologies behind GIS, the databases, the programming languages, the analysis and statistical output, and continued professional development associated with GIS. You will mainly find me contributing in the Python and ArcGIS API for Python Communities.
Labels