#ShieldToolAddin.py #By Kerry Alley 2013-03-12 #Vermont Agency of Transportation # #Python Add-In for ArcMap 10.1, 10.2 # #SELECT_ROAD (button) #When activated, will select features within 20 map-meters of the mouse click on the map. #The features are selected only from the top-most layer with the GDB_HMS.HMSADMIN.rdsmall_arc # data source, regardless of layer name. # #CREATE_SHIELD (button) #Requires that a single rdsmall_arc feature already be selected #User makes a single click on the map to indicate the location of the highway shield, and # makes a double-click where the leader line extending from the highway shield will end. #Both a point feature and a line feature are created, with relevant attributes transferred # from the selected rdsmall_arc feature. #There is an un-commentable option in this script that sets the length of the leader line to # a fixed length, for uniformity. # #NOTE: This addin works "normally" if there is not an active editing session in ArcMap, but if # there is an active editing session, the addin "crashes" at the call to stopEditing(). The # features will still be created, but the screen will not refresh if there is a pre-existing # editing session active. import arcpy, time, os, math import pythonaddins class SelectRoadClass(object): """Implementation for ShieldToolAddinA_addin.tool (Tool)""" def __init__(self): self.enabled = True self.shape = "NONE" def onMouseDownMap(self, x, y, button, shift): #start_time = time.time() #only used to compare run-times of different versions of the script arcpy.env.overwriteOutput = True rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc" mxd = arcpy.mapping.MapDocument('current') flag_rdsmall = 0 #flag_rdsmall is used to flag the first occurence of a layer having the desired dataSource in TOC for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("dataSource"): if str(lyr.dataSource).endswith(rdsmall_dataSource) and not flag_rdsmall: rdsmall_lyr = lyr flag_rdsmall = 1 point = arcpy.Point() point.X = x point.Y = y pointGeometry = arcpy.PointGeometry(point) arcpy.SelectLayerByLocation_management(rdsmall_lyr, "WITHIN_A_DISTANCE", pointGeometry, "20 Meters", "NEW_SELECTION") #print time.time() - start_time, "seconds" class CreateShieldClass(object): """Implementation for ShieldToolAddinB_addin.tool (Tool)""" def __init__(self): self.enabled = True self.cursor = 3 self.shape = "LINE" def onLine(self, line_geometry): #start_time = time.time() #only used to compare rough run-times of different versions of the script arcpy.env.overwriteOutput = True #Hard-wiring the exact feature classes that will be edited with shield tool. shield_points_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_points" shield_arcs_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_arcs" rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc" mxd = arcpy.mapping.MapDocument('current') #for new shields to appear in current mxd, this script must refer to layers in the current mxd lyrs = arcpy.mapping.ListLayers(mxd) flag_points = 0 flag_arcs = 0 flag_rdsmall = 0 for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("dataSource"): if str(lyr.dataSource).endswith(shield_points_dataSource) and flag_points == 0: shield_points_lyr = lyr flag_points = 1 if str(lyr.dataSource).endswith(shield_arcs_dataSource) and flag_arcs == 0: shield_arcs_lyr = lyr flag_arcs = 1 if str(lyr.dataSource).endswith(rdsmall_dataSource) and flag_rdsmall == 0: rdsmall_lyr = lyr flag_rdsmall = 1 if not (shield_points_lyr and shield_arcs_lyr and rdsmall_lyr): print "Must have 3 layers in this mxd: shield points, shield arcs, and rdsmall" #only allow shield creation if a single road arc is selected num_road_arcs = int(arcpy.GetCount_management(rdsmall_lyr).getOutput(0)) print "%s rdsmall arc(s) selected" %num_road_arcs if num_road_arcs == 1: workspace = rdsmall_lyr.workspacePath #(refers to .sde file in DatabaseConnections) arcpy.env.workspace = workspace edit = arcpy.da.Editor(workspace) edit.startEditing(True, True) #with undo, multiuser mode #identify maximum SHI_GRP_ID value currently used in shields feature class max_id = sorted(arcpy.da.SearchCursor(shield_points_lyr.dataSource, "SHI_GRP_ID"), reverse = 1)[0][0] #print max_id + 1 #collect selected road arc attributes rdsmall_values = sorted(arcpy.da.SearchCursor(rdsmall_lyr, ["UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS"])) #uncomment the last line of this block of code to turn off the truncation of the leader line #determine line coordinates, slope, and truncated line geometry based on first and last point. a_pt = line_geometry.firstPoint b_pt = line_geometry.lastPoint slope = (b_pt.Y - a_pt.Y)/(b_pt.X - a_pt.X) theta = math.atan(slope) #fixed_length = 150. fixed_length = 185. if b_pt.X - a_pt.X < 0: x = fixed_length * math.cos(theta) * -1 y = fixed_length * math.sin(theta) * -1 else: x = fixed_length * math.cos(theta) y = fixed_length * math.sin(theta) point = arcpy.Point() point.X = a_pt.X + x point.Y = a_pt.Y + y array = arcpy.Array() array.add(line_geometry.firstPoint) array.add(point) fixed_line = arcpy.Polyline(array) #To remove the constraint of fixed shield arc lengths, uncomment the following line: fixed_line = line_geometry #this line reverts the fixed_line to the original input geometry #create shield point feature and populate attributes new_points_Cur = arcpy.da.InsertCursor(shield_points_lyr, ["SHAPE@XY", "UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS", "SHI_GRP_ID", "INSET", "ISVISIBLE", "SUBINSET"]) test = (fixed_line.firstPoint,) + tuple(rdsmall_values) + (max_id + 1,) test_tuple = ((test[0].X, test[0].Y), test[1][0], test[1][1], str(test[1][2]), str(test[1][3]), test[1][4], test[2], "N", 1, "N") #test_tuple = ((test[0].X, test[0].Y), rdsmall_values[0], str(rdsmall_values[2]), str(rdsmall_values[3]), rdsmall_values[4], max_id + 1, "N", 1, "N") edit.startOperation() new_points_Cur.insertRow(test_tuple) edit.stopOperation() del new_points_Cur #create shield arc feature and populate SHI_GRP_ID, CTCODE, UA, INSET, ISVISIBLE, and SUBINSET fields new_arc_Cur = arcpy.da.InsertCursor(shield_arcs_lyr.dataSource, ["SHAPE@", "SHI_GRP_ID", "CTCODE", "UA", "INSET", "ISVISIBLE", "SUBINSET"]) edit.startOperation() new_arc_Cur.insertRow([fixed_line, max_id + 1, str(rdsmall_values[0][2]), rdsmall_values[0][0], "N", 1, "N"]) edit.stopOperation() del new_arc_Cur edit.stopEditing(True) #save changes (doesn't work if an editing session is open in ArcMap, but ) arcpy.SelectLayerByAttribute_management(rdsmall_lyr, "CLEAR_SELECTION") arcpy.RefreshActiveView() else: print "Shield Not Created" print "Must select a single arc from rdsmall" #print time.time() - start_time, "seconds"
I have a Python Addin that selects a feature by mouse click location and updates the attributes
Los miembros registrados pueden publicar, seguir actualizaciones y más. ¿Nuevo aquí? Regístrate gratis.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.