In this answer to another Python add-in question I suggested supplying a search_distance to the SelectLayerByLocation function in order to allow points and lines to be selected by an intersecting point, interactively clicked by the user using the onMouseDownMap method of a Python add-in Tool class.

In ArcObjects you would normally use ArcMap's selection tolerance in pixels and expand your point's envelope by that amount in map coordinates, but I can't find any equivalent way of doing this in arcpy.

  • Is there a way to access ArcMap's selection tolerance setting without using ArcObjects? And if so, how can you convert this amount to map coordinates so that you can buffer the point or select within a search distance?

Or alternatively and more generally stated:

  • Is there a scale-dependent way to to expand/buffer a point so that interactive selection of features with Python add-in Tools is a similar user experience to the usual interactive selection tools in ArcMap?

Well here is a partial solution -- I don't see any way to access ArcMap's selection tolerance with arcpy, but if you want to pass in your own or just stick with the default of 3 pixels, this function will give you the map distance in inches by which to buffer or use as a search_distance with Select Layer by Location.

def getSearchDistanceInches(scale, selection_tolerance=3):
    """Returns the map distance in inches that corresponds to the input selection
    tolerance in pixels (default 3) at the specified map scale."""
    return scale * selection_tolerance / 96.0 # DPI used by ArcMap when reporting scale

Example usage (in the context of a Python add-in Tool):

def onMouseDownMap(self, x, y, button, shift):
    mxd = arcpy.mapping.MapDocument("CURRENT")
    pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
    searchdistance = getSearchDistanceInches(mxd.activeDataFrame.scale, 3) # 3 pixels is the default ArcMap selection tolerance
    for lyr in arcpy.mapping.ListLayers(mxd, "", mxd.activeDataFrame):
        if lyr.isFeatureLayer:
            arcpy.SelectLayerByLocation_management(lyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance)

In my testing this subjectively feels about the same as the standard interactive selection tools with the default selection tolerance of 3 pixels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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