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?
Answer
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)
arcpy.RefreshActiveView()
In my testing this subjectively feels about the same as the standard interactive selection tools with the default selection tolerance of 3 pixels.
No comments:
Post a Comment