Here is what I would like to do. I have a polygon feature class called Subdivisions and a point feature class called Inspection. If I label all the Subdivisions my map becomes too congested. I only want to label Subdivisions that spatially contains an Inspection point. If a Subdivision does not contain an Inspection point it does not get labeled. Is there a simple way to do this?

The data is not setup to do joins or relates using primary keys. I know I can run a spatial join to accomplish this task but it involves extra steps an creating an extra feature class. I have to maintain this map regularly so the few steps the better.

Is it possible to do this in ArcMap using python in label expressions or definition queries? Let me know if you have a good solution.

4 Answers 4


This is what I would do.

  1. First I would use the selection tool to select all of the polygons that contain a point
  2. Selection→select by location→selct from "subdivion" Source layer "inspection"→ contain the source layer feature
  3. I would then right click on the subdivisions class and create a layer from selected features
  4. you now have a layer of subdivisions that contain an inspection. you can set the outline and fill to none and label this layer.
  • Good idea! I forgot about that. Depending on what I learn here that might be my go to move. I would like to have something that can update automatically, like a python label expression (if that's possible). I'm that lazy!
    – user19300
    Feb 19, 2015 at 15:05

You could also add a text field to your subdivision layer, HasInspection. Calculate the values in that field to Y or N based on whether it has an inspection point. Then set up a label class that only labels subdivisions where HasInspection = Y.

Once you do this, you'll only have to run the field calculation periodically (or do the update in the new subdivision creation workflow) to update the values in HasInspection. The labels will take care of themselves. As a side benefit, the subdivisions will now have an additional attribute that may be useful for other purposes.


Here is some python for you. as you can tell i am lazy too.

#Assumes all data is within the same database
#will look for FC called SUB and compare it to FC Inspection
#Will create new FC called Sub_with_Insp
#should overwrite Sub_with_Insp every time
import arcpy
arcpy.env.workspace = r"C:\Users\whatever\test.gdb"
arcpy.env.overwriteOutput = True

arcpy.MakeFeatureLayer_management('Sub', 'Sub_lyr') 
arcpy.SelectLayerByLocation_management('Sub_lyr', 'COMPLETELY_CONTAINS', 'Inspection')
arcpy.CopyFeatures_management('Sub_lyr', 'Sub_with_Insp') 

I am going to give you a slight python alternative to the other answer. I am not going to write out the whole thing, but if you are familiar with arcpy, you should be able to fill in the gaps.

First things first. Select those Subdivision features that contain and inspection point.

arcpy.SelectLayerByLocation_management("SUBDIVISION", "CONTAINS", "INSPECTION POINT", 0, "NEW_SELECTION")

Now you can go through the selected features and grab the FID information.

First describe the layer to get the selected info.

select = arcpy.Describe("SUBDIVISION")

Now you want to go through the selected features to grab an identifier.

for feature in select.FIDset.split("; "):
  #here is where you can use your identifier to build an expression
  #I usually have a global variable (ex: expression) where I append values to it
  #something like.. myExpression += "FID = '" + feature + "' or "
  #without using a sentinel/counter, I end up having to remove the last " or "
  #to each his own though.. just giving you ideas
  #here I am just printing it though
  print feature

Now, you need to get the layer you're working with. I am assuming you've got it loaded up in the data frame/Table of Contents.

I select my layer, but I first need to create a map document to use for my function.

mxd = arcpy.mapping.MapDocument("CURRENT")
layer = arcpy.mapping.ListLayers(mxd, "SUBDIVISION*")[0]
#ListLayers returns a list, I am using "SUBDIVISION*" as a wildcard to limit to only the one I want
#results may vary on this though.. it is up to you to make it right

From here, you can edit your labeling expressions. I did that like this.

layer.labelClasses[0].SQLQuery = myExpression
layer.labelClasses[0].expression = #field you want to label with (optional)

I am taking the expression I made and using it as a SQL Query against the layer. This sets the selected features that you want to label. Then I am taking the expression part of the labelClass to write out the field I want to label with. This is optional though, the SQL Query is the part that matters, the rest can be done manually. If you look at the properties of the expression and SQLQuery, you can see the code modified those with the layer. Make sure you Method is set to Define classes of fatures and label each differently to see how the default class was edited. I am not 100% sure this works if you have it set as Label all the features the same way.. I know you can't see the SQLQuery part, and I did not fully test this to double check. (Layer Properties -> Labels -> Expression/SQLQuery).

You can modify this to be a cut and paste script you drop in the interactive window (like I did) or make it a tool, if you desire.

  • I also read that a SearchCursor returns selected features only if there is a selection. That would give you some better options for using field names and such. Something else to look into...
    – Branco
    Feb 19, 2015 at 15:42
  • I'm not sure the OP is looking for a scripting solution, though. Maybe he or she will clarify.
    – recurvata
    Feb 19, 2015 at 16:05
  • There isn't much more simple than a script or a tool to do this though. Once it is set up, it can be a button press or copy/paste thing.
    – Branco
    Feb 19, 2015 at 16:21

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.